aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.it_it/strings.po6
-rw-r--r--addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.et_ee/strings.po12
-rw-r--r--addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.it_it/strings.po10
-rw-r--r--addons/game.controller.keyboard/addon.xml2
-rw-r--r--addons/game.controller.keyboard/resources/language/resource.language.es_es/strings.po6
-rw-r--r--addons/game.controller.keyboard/resources/language/resource.language.it_it/strings.po8
-rw-r--r--addons/game.controller.keyboard/resources/language/resource.language.ru_ru/strings.po18
-rw-r--r--addons/resource.language.en_gb/resources/strings.po7
-rw-r--r--addons/skin.estuary/language/resource.language.sk_sk/strings.po10
-rw-r--r--addons/skin.estuary/xml/DialogPVRInfo.xml2
-rw-r--r--addons/skin.estuary/xml/Includes_PVR.xml4
-rw-r--r--addons/skin.estuary/xml/Variables.xml9
-rw-r--r--cmake/modules/FindBrotli.cmake68
-rw-r--r--cmake/modules/FindCurl.cmake248
-rw-r--r--cmake/modules/FindD3DX11Effects.cmake16
-rw-r--r--cmake/modules/FindEffects11.cmake121
-rw-r--r--cmake/modules/FindFlatBuffers.cmake65
-rw-r--r--cmake/modules/FindNGHttp2.cmake52
-rw-r--r--cmake/modules/FindSSE.cmake72
-rw-r--r--cmake/modules/FindTagLib.cmake2
-rw-r--r--cmake/modules/buildtools/FindEffectsCompiler.cmake32
-rw-r--r--cmake/platform/windows/windows.cmake3
-rw-r--r--cmake/platform/windowsstore/windowsstore.cmake3
-rw-r--r--cmake/scripts/android/ArchSetup.cmake3
-rw-r--r--cmake/scripts/android/Install.cmake1
-rw-r--r--cmake/scripts/common/Macros.cmake1
-rw-r--r--cmake/treedata/common/tests.txt1
-rw-r--r--cmake/treedata/windows/externals.txt1
-rw-r--r--cmake/treedata/windowsstore/externals.txt1
-rw-r--r--lib/win32/Effects11/Binary/EffectBinaryFormat.h676
-rw-r--r--lib/win32/Effects11/Binary/EffectStateBase11.h51
-rw-r--r--lib/win32/Effects11/Binary/EffectStates11.h237
-rw-r--r--lib/win32/Effects11/Binary/SOParser.h315
-rw-r--r--lib/win32/Effects11/CMakeLists.txt42
-rw-r--r--lib/win32/Effects11/Effect.h1276
-rw-r--r--lib/win32/Effects11/EffectAPI.cpp320
-rw-r--r--lib/win32/Effects11/EffectLoad.cpp4030
-rw-r--r--lib/win32/Effects11/EffectLoad.h159
-rw-r--r--lib/win32/Effects11/EffectNonRuntime.cpp2988
-rw-r--r--lib/win32/Effects11/EffectReflection.cpp2183
-rw-r--r--lib/win32/Effects11/EffectRuntime.cpp718
-rw-r--r--lib/win32/Effects11/EffectVariable.inl4964
-rw-r--r--lib/win32/Effects11/HISTORY.md131
-rw-r--r--lib/win32/Effects11/IUnknownImp.h53
-rw-r--r--lib/win32/Effects11/LICENSE21
-rw-r--r--lib/win32/Effects11/README.md66
-rw-r--r--lib/win32/Effects11/SECURITY.md41
-rw-r--r--lib/win32/Effects11/d3dxGlobal.cpp403
-rw-r--r--lib/win32/Effects11/inc/d3dx11effect.h1212
-rw-r--r--lib/win32/Effects11/inc/d3dxGlobal.h1290
-rw-r--r--lib/win32/Effects11/pchfx.h55
-rw-r--r--project/BuildDependencies/scripts/0_package.target-win10-arm.list3
-rw-r--r--project/BuildDependencies/scripts/0_package.target-win10-win32.list3
-rw-r--r--project/BuildDependencies/scripts/0_package.target-win10-x64.list3
-rw-r--r--project/BuildDependencies/scripts/0_package.target-win32.list3
-rw-r--r--project/BuildDependencies/scripts/0_package.target-x64.list3
-rw-r--r--system/shaders/GL/1.2/gl_shader_vert.glsl2
-rw-r--r--system/shaders/GL/1.2/gl_shader_vert_clip.glsl43
-rw-r--r--system/shaders/GL/1.2/gl_shader_vert_default.glsl1
-rw-r--r--system/shaders/GL/1.2/gl_shader_vert_simple.glsl28
-rw-r--r--system/shaders/GL/1.2/gl_yuv2rgb_vertex.glsl1
-rw-r--r--system/shaders/GL/1.5/gl_shader_vert.glsl2
-rw-r--r--system/shaders/GL/1.5/gl_shader_vert_clip.glsl43
-rw-r--r--system/shaders/GL/1.5/gl_shader_vert_default.glsl1
-rw-r--r--system/shaders/GL/1.5/gl_shader_vert_simple.glsl28
-rw-r--r--system/shaders/GL/1.5/gl_yuv2rgb_vertex.glsl1
-rw-r--r--system/shaders/GLES/2.0/gles_shader.vert2
-rw-r--r--system/shaders/GLES/2.0/gles_shader_clip.vert43
-rw-r--r--system/shaders/GLES/2.0/gles_shader_simple.vert30
-rw-r--r--system/shaders/GLES/2.0/gles_yuv2rgb.vert1
-rw-r--r--tools/Linux/kodi.sh.in7
-rw-r--r--tools/android/packaging/Makefile.in13
-rw-r--r--tools/android/packaging/media/mipmap-hdpi/ic_launcher.png (renamed from tools/android/packaging/media/drawable-hdpi/ic_launcher.png)bin5488 -> 5488 bytes
-rw-r--r--tools/android/packaging/media/mipmap-ldpi/ic_launcher.png (renamed from tools/android/packaging/media/drawable-ldpi/ic_launcher.png)bin2336 -> 2336 bytes
-rw-r--r--tools/android/packaging/media/mipmap-mdpi/ic_launcher.png (renamed from tools/android/packaging/media/drawable-mdpi/ic_launcher.png)bin3540 -> 3540 bytes
-rw-r--r--tools/android/packaging/media/mipmap-xhdpi/banner.png (renamed from tools/android/packaging/media/drawable-xhdpi/banner.png)bin12143 -> 12143 bytes
-rw-r--r--tools/android/packaging/media/mipmap-xhdpi/ic_launcher.png (renamed from tools/android/packaging/media/drawable-xhdpi/ic_launcher.png)bin7296 -> 7296 bytes
-rw-r--r--tools/android/packaging/media/mipmap-xxhdpi/ic_launcher.png (renamed from tools/android/packaging/media/drawable-xxhdpi/ic_launcher.png)bin12194 -> 12194 bytes
-rw-r--r--tools/android/packaging/media/mipmap-xxxhdpi/ic_launcher.png (renamed from tools/android/packaging/media/drawable-xxxhdpi/ic_launcher.png)bin13483 -> 13483 bytes
-rw-r--r--tools/android/packaging/xbmc/AndroidManifest.xml.in6
-rw-r--r--tools/android/packaging/xbmc/res/layout/activity_splash.xml11
-rw-r--r--tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in63
-rw-r--r--tools/android/packaging/xbmc/src/XBMCTextureCache.java.in32
-rw-r--r--tools/depends/configure.ac6
-rw-r--r--tools/depends/native/cargo-c/CARGO-C-VERSION7
-rw-r--r--tools/depends/native/cargo-c/Makefile3
-rw-r--r--tools/depends/native/openssl/OPENSSL-VERSION4
-rw-r--r--tools/depends/native/rustup/Makefile2
-rw-r--r--tools/depends/native/rustup/RUSTUP-VERSION4
-rw-r--r--tools/depends/target/Makefile4
-rw-r--r--tools/depends/target/brotli/01-all-disable-exe.patch28
-rw-r--r--tools/depends/target/brotli/BROTLI-VERSION5
-rw-r--r--tools/depends/target/brotli/Makefile33
-rw-r--r--tools/depends/target/cec/Makefile2
-rw-r--r--tools/depends/target/curl/01-win-nghttp2-add-name.patch11
-rw-r--r--tools/depends/target/curl/CURL-VERSION5
-rw-r--r--tools/depends/target/curl/Makefile70
-rw-r--r--tools/depends/target/effects11/01-win-debugpostfix.patch11
-rw-r--r--tools/depends/target/effects11/EFFECTS11-VERSION5
-rw-r--r--tools/depends/target/gmp/Makefile2
-rw-r--r--tools/depends/target/gnutls/Makefile5
-rw-r--r--tools/depends/target/gnutls/android-fpending.patch13
-rw-r--r--tools/depends/target/libgcrypt/Makefile7
-rw-r--r--tools/depends/target/openssl/001-android-getauxvalrevert.patch6
-rw-r--r--tools/depends/target/openssl/16-kodi.conf16
-rw-r--r--tools/depends/target/openssl/Makefile35
-rw-r--r--tools/depends/target/openssl/OPENSSL-VERSION4
-rw-r--r--tools/depends/target/pythonmodule-pil/PYTHONMODULE-PIL-VERSION4
-rw-r--r--tools/depends/target/tinyxml2/Makefile2
-rw-r--r--xbmc/AutoSwitch.cpp1
-rw-r--r--xbmc/Autorun.cpp9
-rw-r--r--xbmc/BackgroundInfoLoader.cpp1
-rw-r--r--xbmc/CMakeLists.txt2
-rw-r--r--xbmc/ContextMenus.cpp7
-rw-r--r--xbmc/CueDocument.cpp1
-rw-r--r--xbmc/FileItem.cpp1511
-rw-r--r--xbmc/FileItem.h218
-rw-r--r--xbmc/FileItemList.cpp1176
-rw-r--r--xbmc/FileItemList.h206
-rw-r--r--xbmc/GUIInfoManager.cpp32
-rw-r--r--xbmc/NfoFile.cpp1
-rw-r--r--xbmc/PartyModeManager.cpp1
-rw-r--r--xbmc/PlayListPlayer.cpp26
-rw-r--r--xbmc/PlayListPlayer.h7
-rw-r--r--xbmc/SeekHandler.cpp6
-rw-r--r--xbmc/URL.cpp12
-rw-r--r--xbmc/Util.cpp16
-rw-r--r--xbmc/addons/AddonManager.cpp1
-rw-r--r--xbmc/addons/AddonManager.h3
-rw-r--r--xbmc/addons/AddonRepos.cpp97
-rw-r--r--xbmc/addons/AddonRepos.h10
-rw-r--r--xbmc/addons/FilesystemInstaller.cpp1
-rw-r--r--xbmc/addons/Scraper.cpp11
-rw-r--r--xbmc/addons/Scraper.h2
-rw-r--r--xbmc/addons/Skin.cpp1
-rw-r--r--xbmc/addons/VFSEntry.h1
-rw-r--r--xbmc/addons/addoninfo/AddonInfo.cpp1
-rw-r--r--xbmc/addons/gui/GUIDialogAddonInfo.cpp1
-rw-r--r--xbmc/addons/gui/GUIDialogAddonSettings.cpp1
-rw-r--r--xbmc/addons/gui/GUIViewStateAddonBrowser.cpp1
-rw-r--r--xbmc/addons/gui/GUIWindowAddonBrowser.cpp1
-rw-r--r--xbmc/addons/interfaces/Filesystem.cpp1
-rw-r--r--xbmc/addons/interfaces/gui/Window.cpp1
-rw-r--r--xbmc/addons/settings/AddonSettings.cpp1
-rw-r--r--xbmc/application/AppParamParser.cpp1
-rw-r--r--xbmc/application/AppParams.cpp4
-rw-r--r--xbmc/application/AppParams.h2
-rw-r--r--xbmc/application/Application.cpp53
-rw-r--r--xbmc/application/Application.h9
-rw-r--r--xbmc/application/ApplicationPlayer.cpp4
-rw-r--r--xbmc/application/ApplicationPlayerCallback.cpp17
-rw-r--r--xbmc/application/ApplicationPowerHandling.cpp6
-rw-r--r--xbmc/application/ApplicationSkinHandling.cpp1
-rw-r--r--xbmc/application/ApplicationStackHelper.cpp1
-rw-r--r--xbmc/cdrip/CDDARipJob.cpp6
-rw-r--r--xbmc/cdrip/CDDARipper.cpp1
-rw-r--r--xbmc/cores/AudioEngine/CMakeLists.txt6
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp2
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp16
-rw-r--r--xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp2
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp16
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkDARWINTVOS.mm12
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp4
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp54
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h2
-rw-r--r--xbmc/cores/AudioEngine/Sinks/AESinkStarfish.cpp55
-rw-r--r--xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.cpp195
-rw-r--r--xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.h21
-rw-r--r--xbmc/cores/AudioEngine/Utils/AEPackIEC61937.cpp6
-rw-r--r--xbmc/cores/AudioEngine/Utils/AEPackIEC61937.h4
-rw-r--r--xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp15
-rw-r--r--xbmc/cores/AudioEngine/Utils/AEStreamInfo.h2
-rw-r--r--xbmc/cores/AudioEngine/Utils/PackerMAT.cpp440
-rw-r--r--xbmc/cores/AudioEngine/Utils/PackerMAT.h119
-rw-r--r--xbmc/cores/DllLoader/exports/emu_msvcrt.cpp1
-rw-r--r--xbmc/cores/RetroPlayer/messages/CMakeLists.txt6
-rw-r--r--xbmc/cores/RetroPlayer/rendering/RenderContext.cpp15
-rw-r--r--xbmc/cores/RetroPlayer/rendering/RenderContext.h1
-rw-r--r--xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.cpp2
-rw-r--r--xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp4
-rw-r--r--xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp2
-rw-r--r--xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp4
-rw-r--r--xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp1
-rw-r--r--xbmc/cores/VideoPlayer/DVDFileInfo.cpp11
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp8
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp8
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp6
-rw-r--r--xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp1
-rw-r--r--xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp1
-rw-r--r--xbmc/cores/VideoPlayer/VideoPlayer.cpp5
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.h2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp5
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodec.cpp4
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp57
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h1
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp85
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h4
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.cpp2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.h2
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp11
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp10
-rw-r--r--xbmc/cores/paplayer/AudioDecoder.cpp5
-rw-r--r--xbmc/cores/paplayer/PAPlayer.cpp8
-rw-r--r--xbmc/cores/playercorefactory/PlayerCoreFactory.cpp8
-rw-r--r--xbmc/cores/playercorefactory/PlayerSelectionRule.cpp31
-rw-r--r--xbmc/cores/playercorefactory/PlayerSelectionRule.h1
-rw-r--r--xbmc/dialogs/GUIDialogColorPicker.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogContextMenu.cpp5
-rw-r--r--xbmc/dialogs/GUIDialogContextMenu.h1
-rw-r--r--xbmc/dialogs/GUIDialogFileBrowser.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogMediaFilter.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogMediaSource.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogSelect.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogSimpleMenu.cpp23
-rw-r--r--xbmc/dialogs/GUIDialogSimpleMenu.h2
-rw-r--r--xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp1
-rw-r--r--xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp1
-rw-r--r--xbmc/events/windows/GUIViewStateEventLog.cpp1
-rw-r--r--xbmc/events/windows/GUIWindowEventLog.cpp1
-rw-r--r--xbmc/favourites/ContextMenus.cpp7
-rw-r--r--xbmc/favourites/FavouritesService.cpp8
-rw-r--r--xbmc/favourites/FavouritesService.h1
-rw-r--r--xbmc/favourites/GUIViewStateFavourites.cpp2
-rw-r--r--xbmc/favourites/GUIWindowFavourites.cpp4
-rw-r--r--xbmc/filesystem/AddonsDirectory.cpp39
-rw-r--r--xbmc/filesystem/AudioBookFileDirectory.cpp1
-rw-r--r--xbmc/filesystem/BlurayCallback.cpp1
-rw-r--r--xbmc/filesystem/BlurayDirectory.cpp1
-rw-r--r--xbmc/filesystem/CDDADirectory.cpp1
-rw-r--r--xbmc/filesystem/DAVDirectory.cpp1
-rw-r--r--xbmc/filesystem/Directorization.h1
-rw-r--r--xbmc/filesystem/Directory.cpp7
-rw-r--r--xbmc/filesystem/DirectoryCache.cpp1
-rw-r--r--xbmc/filesystem/EventsDirectory.cpp1
-rw-r--r--xbmc/filesystem/FTPDirectory.cpp1
-rw-r--r--xbmc/filesystem/File.cpp3
-rw-r--r--xbmc/filesystem/FileDirectoryFactory.cpp7
-rw-r--r--xbmc/filesystem/HTTPDirectory.cpp1
-rw-r--r--xbmc/filesystem/IFileTypes.h3
-rw-r--r--xbmc/filesystem/ISO9660Directory.cpp1
-rw-r--r--xbmc/filesystem/LibraryDirectory.cpp1
-rw-r--r--xbmc/filesystem/MultiPathDirectory.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp1
-rw-r--r--xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp1
-rw-r--r--xbmc/filesystem/MusicFileDirectory.cpp1
-rw-r--r--xbmc/filesystem/MusicSearchDirectory.cpp1
-rw-r--r--xbmc/filesystem/NFSDirectory.cpp1
-rw-r--r--xbmc/filesystem/PlaylistDirectory.cpp1
-rw-r--r--xbmc/filesystem/PlaylistFileDirectory.cpp1
-rw-r--r--xbmc/filesystem/PluginDirectory.cpp1
-rw-r--r--xbmc/filesystem/RSSDirectory.cpp1
-rw-r--r--xbmc/filesystem/ResourceDirectory.cpp1
-rw-r--r--xbmc/filesystem/SmartPlaylistDirectory.cpp1
-rw-r--r--xbmc/filesystem/SourcesDirectory.cpp15
-rw-r--r--xbmc/filesystem/SpecialProtocolDirectory.cpp1
-rw-r--r--xbmc/filesystem/StackDirectory.cpp1
-rw-r--r--xbmc/filesystem/UDFDirectory.cpp1
-rw-r--r--xbmc/filesystem/UPnPDirectory.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp1
-rw-r--r--xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp1
-rw-r--r--xbmc/filesystem/VirtualDirectory.cpp1
-rw-r--r--xbmc/filesystem/ZeroconfDirectory.cpp1
-rw-r--r--xbmc/filesystem/test/TestDirectory.cpp1
-rw-r--r--xbmc/filesystem/test/TestHTTPDirectory.cpp1
-rw-r--r--xbmc/filesystem/test/TestZipFile.cpp1
-rw-r--r--xbmc/games/addons/GameClientProperties.cpp1
-rw-r--r--xbmc/games/agents/windows/GUIAgentControllerList.cpp1
-rw-r--r--xbmc/games/controllers/dialogs/ControllerInstaller.cpp1
-rw-r--r--xbmc/games/controllers/dialogs/ControllerSelect.cpp1
-rw-r--r--xbmc/games/dialogs/GUIDialogSelectGameClient.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameSaves.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameStretchMode.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameVideoFilter.h1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp1
-rw-r--r--xbmc/games/dialogs/osd/DialogInGameSaves.h1
-rw-r--r--xbmc/games/ports/guicontrols/GUIActivePortList.cpp1
-rw-r--r--xbmc/games/ports/windows/GUIPortList.cpp1
-rw-r--r--xbmc/games/windows/GUIViewStateWindowGames.cpp1
-rw-r--r--xbmc/games/windows/GUIWindowGames.cpp1
-rw-r--r--xbmc/guilib/CMakeLists.txt12
-rw-r--r--xbmc/guilib/GUIBaseContainer.cpp58
-rw-r--r--xbmc/guilib/GUIBaseContainer.h9
-rw-r--r--xbmc/guilib/GUIBorderedImage.cpp12
-rw-r--r--xbmc/guilib/GUIButtonControl.cpp18
-rw-r--r--xbmc/guilib/GUIControl.cpp27
-rw-r--r--xbmc/guilib/GUIControl.h6
-rw-r--r--xbmc/guilib/GUIControlGroup.cpp41
-rw-r--r--xbmc/guilib/GUIControlGroup.h1
-rw-r--r--xbmc/guilib/GUIEditControl.cpp3
-rw-r--r--xbmc/guilib/GUIFadeLabelControl.cpp10
-rw-r--r--xbmc/guilib/GUIFadeLabelControl.h4
-rw-r--r--xbmc/guilib/GUIFont.cpp16
-rw-r--r--xbmc/guilib/GUIFontManager.cpp1
-rw-r--r--xbmc/guilib/GUIFontTTF.cpp109
-rw-r--r--xbmc/guilib/GUIFontTTF.h12
-rw-r--r--xbmc/guilib/GUIFontTTFGL.cpp123
-rw-r--r--xbmc/guilib/GUIFontTTFGL.h4
-rw-r--r--xbmc/guilib/GUIFontTTFGLES.cpp107
-rw-r--r--xbmc/guilib/GUIFontTTFGLES.h1
-rw-r--r--xbmc/guilib/GUILabelControl.cpp3
-rw-r--r--xbmc/guilib/GUILabelControl.dox4
-rw-r--r--xbmc/guilib/GUIListItemLayout.cpp5
-rw-r--r--xbmc/guilib/GUIListItemLayout.h1
-rw-r--r--xbmc/guilib/GUIListLabel.cpp3
-rw-r--r--xbmc/guilib/GUIMultiImage.cpp1
-rw-r--r--xbmc/guilib/GUIPanelContainer.cpp29
-rw-r--r--xbmc/guilib/GUISettingsSliderControl.cpp3
-rw-r--r--xbmc/guilib/GUISpinControl.cpp3
-rw-r--r--xbmc/guilib/GUITextBox.cpp10
-rw-r--r--xbmc/guilib/GUITextBox.h1
-rw-r--r--xbmc/guilib/GUITextLayout.cpp135
-rw-r--r--xbmc/guilib/GUITexture.cpp55
-rw-r--r--xbmc/guilib/GUITexture.h15
-rw-r--r--xbmc/guilib/GUITextureD3D.cpp4
-rw-r--r--xbmc/guilib/GUITextureD3D.h4
-rw-r--r--xbmc/guilib/GUITextureGL.cpp20
-rw-r--r--xbmc/guilib/GUITextureGL.h4
-rw-r--r--xbmc/guilib/GUITextureGLES.cpp20
-rw-r--r--xbmc/guilib/GUITextureGLES.h4
-rw-r--r--xbmc/guilib/GUIVideoControl.cpp14
-rw-r--r--xbmc/guilib/GUIWindow.cpp4
-rw-r--r--xbmc/guilib/GUIWindowManager.cpp56
-rw-r--r--xbmc/guilib/GUIWindowManager.h6
-rw-r--r--xbmc/guilib/Texture.cpp194
-rw-r--r--xbmc/guilib/Texture.h75
-rw-r--r--xbmc/guilib/TextureBase.cpp413
-rw-r--r--xbmc/guilib/TextureBase.h117
-rw-r--r--xbmc/guilib/TextureFormats.h155
-rw-r--r--xbmc/guilib/guiinfo/GUIInfoLabels.h6
-rw-r--r--xbmc/guilib/guiinfo/LibraryGUIInfo.cpp1
-rw-r--r--xbmc/guilib/guiinfo/MusicGUIInfo.cpp14
-rw-r--r--xbmc/guilib/guiinfo/PicturesGUIInfo.cpp4
-rw-r--r--xbmc/guilib/guiinfo/SystemGUIInfo.cpp21
-rw-r--r--xbmc/guilib/guiinfo/VideoGUIInfo.cpp15
-rw-r--r--xbmc/guilib/listproviders/DirectoryProvider.cpp9
-rw-r--r--xbmc/imagefiles/SpecialImageLoaderFactory.cpp1
-rw-r--r--xbmc/input/keyboard/KeyboardLayoutManager.cpp1
-rw-r--r--xbmc/input/keymaps/ButtonTranslator.cpp1
-rw-r--r--xbmc/interfaces/AnnouncementManager.cpp4
-rw-r--r--xbmc/interfaces/builtins/PlayerBuiltins.cpp21
-rw-r--r--xbmc/interfaces/json-rpc/AddonsOperations.cpp10
-rw-r--r--xbmc/interfaces/json-rpc/AddonsOperations.h3
-rw-r--r--xbmc/interfaces/json-rpc/AudioLibrary.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/FileItemHandler.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/FileOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/PVROperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/PlayerOperations.cpp5
-rw-r--r--xbmc/interfaces/json-rpc/PlaylistOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/ProfilesOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/TextureOperations.cpp1
-rw-r--r--xbmc/interfaces/json-rpc/VideoLibrary.cpp1
-rw-r--r--xbmc/interfaces/legacy/Control.cpp1
-rw-r--r--xbmc/interfaces/legacy/Dialog.cpp1
-rw-r--r--xbmc/interfaces/legacy/ModuleXbmcplugin.cpp1
-rw-r--r--xbmc/interfaces/legacy/ModuleXbmcvfs.cpp1
-rw-r--r--xbmc/interfaces/legacy/PlayList.cpp1
-rw-r--r--xbmc/interfaces/legacy/Player.cpp1
-rw-r--r--xbmc/interfaces/legacy/WindowXML.cpp1
-rw-r--r--xbmc/music/CMakeLists.txt2
-rw-r--r--xbmc/music/ContextMenus.cpp8
-rw-r--r--xbmc/music/GUIViewStateMusic.cpp6
-rw-r--r--xbmc/music/MusicDatabase.cpp1
-rw-r--r--xbmc/music/MusicFileItemClassify.cpp81
-rw-r--r--xbmc/music/MusicFileItemClassify.h36
-rw-r--r--xbmc/music/MusicInfoLoader.cpp30
-rw-r--r--xbmc/music/MusicUtils.cpp18
-rw-r--r--xbmc/music/dialogs/GUIDialogMusicInfo.cpp5
-rw-r--r--xbmc/music/dialogs/GUIDialogSongInfo.cpp9
-rw-r--r--xbmc/music/dialogs/GUIDialogSongInfo.h1
-rw-r--r--xbmc/music/infoscanner/MusicInfoScanner.cpp9
-rw-r--r--xbmc/music/tags/MusicInfoTagLoaderFactory.cpp7
-rw-r--r--xbmc/music/test/CMakeLists.txt3
-rw-r--r--xbmc/music/test/TestMusicFileItemClassify.cpp190
-rw-r--r--xbmc/music/windows/GUIWindowMusicBase.cpp45
-rw-r--r--xbmc/music/windows/GUIWindowMusicNav.cpp27
-rw-r--r--xbmc/music/windows/GUIWindowMusicPlaylist.cpp6
-rw-r--r--xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp1
-rw-r--r--xbmc/music/windows/MusicFileItemListModifier.cpp7
-rw-r--r--xbmc/network/AirPlayServer.cpp1
-rw-r--r--xbmc/network/CMakeLists.txt2
-rw-r--r--xbmc/network/NetworkFileItemClassify.cpp41
-rw-r--r--xbmc/network/NetworkFileItemClassify.h24
-rw-r--r--xbmc/network/test/CMakeLists.txt3
-rw-r--r--xbmc/network/test/TestNetworkFileItemClassify.cpp289
-rw-r--r--xbmc/network/upnp/UPnPInternal.cpp19
-rw-r--r--xbmc/network/upnp/UPnPPlayer.cpp15
-rw-r--r--xbmc/network/upnp/UPnPRenderer.cpp6
-rw-r--r--xbmc/network/upnp/UPnPServer.cpp21
-rw-r--r--xbmc/peripherals/addons/PeripheralAddon.cpp1
-rw-r--r--xbmc/peripherals/bus/PeripheralBus.cpp1
-rw-r--r--xbmc/peripherals/dialogs/GUIDialogPeripherals.h1
-rw-r--r--xbmc/pictures/GUIDialogPictureInfo.cpp1
-rw-r--r--xbmc/pictures/GUIViewStatePictures.cpp1
-rw-r--r--xbmc/pictures/GUIWindowPictures.cpp7
-rw-r--r--xbmc/pictures/GUIWindowSlideShow.cpp39
-rw-r--r--xbmc/pictures/PictureFolderImageFileLoader.cpp1
-rw-r--r--xbmc/pictures/PictureInfoLoader.cpp11
-rw-r--r--xbmc/pictures/PictureThumbLoader.cpp8
-rw-r--r--xbmc/pictures/SlideShowPicture.cpp3
-rw-r--r--xbmc/pictures/SlideShowPictureGL.cpp2
-rw-r--r--xbmc/pictures/SlideShowPictureGLES.cpp2
-rw-r--r--xbmc/platform/android/activity/CMakeLists.txt2
-rw-r--r--xbmc/platform/android/activity/JNIXBMCTextureCache.cpp42
-rw-r--r--xbmc/platform/android/activity/JNIXBMCTextureCache.h29
-rw-r--r--xbmc/platform/android/activity/XBMCApp.cpp77
-rw-r--r--xbmc/platform/android/activity/XBMCApp.h3
-rw-r--r--xbmc/platform/android/activity/android_main.cpp2
-rw-r--r--xbmc/platform/android/filesystem/APKDirectory.cpp1
-rw-r--r--xbmc/platform/android/filesystem/AndroidAppDirectory.cpp1
-rw-r--r--xbmc/platform/darwin/tvos/TVOSTopShelf.mm1
-rw-r--r--xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp1
-rw-r--r--xbmc/platform/freebsd/PlatformFreebsd.cpp6
-rw-r--r--xbmc/platform/linux/OptionalsReg.cpp6
-rw-r--r--xbmc/platform/linux/OptionalsReg.h2
-rw-r--r--xbmc/platform/linux/PlatformLinux.cpp8
-rw-r--r--xbmc/platform/posix/filesystem/PosixDirectory.cpp1
-rw-r--r--xbmc/platform/posix/filesystem/SMBDirectory.cpp1
-rw-r--r--xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp1
-rw-r--r--xbmc/platform/posix/filesystem/SMBWSDiscoveryListener.cpp1
-rw-r--r--xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp1
-rw-r--r--xbmc/platform/win32/filesystem/Win32Directory.cpp1
-rw-r--r--xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp1
-rw-r--r--xbmc/platform/win32/network/NetworkWin32.cpp21
-rw-r--r--xbmc/playlists/PlayList.cpp8
-rw-r--r--xbmc/playlists/PlayListFactory.cpp9
-rw-r--r--xbmc/playlists/PlayListM3U.cpp8
-rw-r--r--xbmc/playlists/PlayListPLS.cpp8
-rw-r--r--xbmc/playlists/SmartPlaylistFileItemListModifier.cpp1
-rw-r--r--xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp1
-rw-r--r--xbmc/profiles/windows/GUIWindowSettingsProfile.cpp1
-rw-r--r--xbmc/programs/GUIViewStatePrograms.cpp1
-rw-r--r--xbmc/programs/GUIWindowPrograms.cpp1
-rw-r--r--xbmc/pvr/PVRChannelGroupImageFileLoader.cpp1
-rw-r--r--xbmc/pvr/PVRThumbLoader.cpp1
-rw-r--r--xbmc/pvr/addons/PVRClient.cpp11
-rw-r--r--xbmc/pvr/addons/PVRClient.h6
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp1
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp1
-rw-r--r--xbmc/pvr/filesystem/PVRGUIDirectory.cpp1
-rw-r--r--xbmc/pvr/guilib/GUIEPGGridContainer.cpp121
-rw-r--r--xbmc/pvr/guilib/GUIEPGGridContainer.h25
-rw-r--r--xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp10
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIActionsUtils.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp1
-rw-r--r--xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h3
-rw-r--r--xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp24
-rw-r--r--xbmc/pvr/windows/GUIViewStatePVR.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRBase.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRChannels.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRGuide.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRRecordings.cpp7
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRSearch.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRTimers.cpp1
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp1
-rw-r--r--xbmc/rendering/RenderSystem.cpp2
-rw-r--r--xbmc/rendering/RenderSystem.h10
-rw-r--r--xbmc/rendering/gl/GLShader.cpp7
-rw-r--r--xbmc/rendering/gl/GLShader.h10
-rw-r--r--xbmc/rendering/gl/RenderSystemGL.cpp111
-rw-r--r--xbmc/rendering/gl/RenderSystemGL.h11
-rw-r--r--xbmc/rendering/gles/GLESShader.cpp4
-rw-r--r--xbmc/rendering/gles/GLESShader.h8
-rw-r--r--xbmc/rendering/gles/RenderSystemGLES.cpp97
-rw-r--r--xbmc/rendering/gles/RenderSystemGLES.h9
-rw-r--r--xbmc/settings/AdvancedSettings.cpp2
-rw-r--r--xbmc/settings/AdvancedSettings.h2
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.cpp2
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.h8
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsBase.h4
-rw-r--r--xbmc/settings/windows/GUIControlSettings.cpp1
-rw-r--r--xbmc/test/TestBasicEnvironment.cpp1
-rw-r--r--xbmc/utils/ExecString.cpp8
-rw-r--r--xbmc/utils/FileOperationJob.h1
-rw-r--r--xbmc/utils/FontUtils.cpp1
-rw-r--r--xbmc/utils/Geometry.h7
-rw-r--r--xbmc/utils/GroupUtils.cpp6
-rw-r--r--xbmc/utils/PlayerUtils.cpp4
-rw-r--r--xbmc/utils/RecentlyAddedJob.cpp1
-rw-r--r--xbmc/utils/SaveFileStateJob.cpp41
-rw-r--r--xbmc/utils/TransformMatrix.h12
-rw-r--r--xbmc/utils/URIUtils.cpp10
-rw-r--r--xbmc/utils/test/TestVariant.cpp2
-rw-r--r--xbmc/video/CMakeLists.txt2
-rw-r--r--xbmc/video/ContextMenus.cpp48
-rw-r--r--xbmc/video/Episode.h2
-rw-r--r--xbmc/video/GUIViewStateVideo.cpp7
-rw-r--r--xbmc/video/VideoChapterImageFileLoader.cpp14
-rw-r--r--xbmc/video/VideoChapterImageFileLoader.h4
-rw-r--r--xbmc/video/VideoDatabase.cpp182
-rw-r--r--xbmc/video/VideoDatabase.h43
-rw-r--r--xbmc/video/VideoEmbeddedImageFileLoader.cpp14
-rw-r--r--xbmc/video/VideoEmbeddedImageFileLoader.h4
-rw-r--r--xbmc/video/VideoFileItemClassify.cpp152
-rw-r--r--xbmc/video/VideoFileItemClassify.h50
-rw-r--r--xbmc/video/VideoGeneratedImageFileLoader.cpp12
-rw-r--r--xbmc/video/VideoGeneratedImageFileLoader.h4
-rw-r--r--xbmc/video/VideoInfoDownloader.cpp6
-rw-r--r--xbmc/video/VideoInfoDownloader.h6
-rw-r--r--xbmc/video/VideoInfoScanner.cpp22
-rw-r--r--xbmc/video/VideoInfoScanner.h5
-rw-r--r--xbmc/video/VideoItemArtworkHandler.cpp10
-rw-r--r--xbmc/video/VideoItemArtworkHandler.h4
-rw-r--r--xbmc/video/VideoThumbLoader.cpp20
-rw-r--r--xbmc/video/VideoUtils.cpp20
-rw-r--r--xbmc/video/VideoUtils.h4
-rw-r--r--xbmc/video/dialogs/GUIDialogCMSSettings.cpp1
-rw-r--r--xbmc/video/dialogs/GUIDialogSubtitles.cpp1
-rw-r--r--xbmc/video/dialogs/GUIDialogTeletext.cpp5
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp6
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoInfo.cpp8
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoManager.cpp23
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoManager.h1
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp9
-rw-r--r--xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp9
-rw-r--r--xbmc/video/guilib/VideoAction.h7
-rw-r--r--xbmc/video/guilib/VideoGUIUtils.cpp33
-rw-r--r--xbmc/video/guilib/VideoGUIUtils.h4
-rw-r--r--xbmc/video/guilib/VideoPlayActionProcessor.cpp7
-rw-r--r--xbmc/video/guilib/VideoPlayActionProcessor.h7
-rw-r--r--xbmc/video/guilib/VideoSelectActionProcessor.cpp8
-rw-r--r--xbmc/video/guilib/VideoSelectActionProcessor.h7
-rw-r--r--xbmc/video/guilib/VideoVersionHelper.cpp19
-rw-r--r--xbmc/video/guilib/VideoVersionHelper.h15
-rw-r--r--xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp1
-rw-r--r--xbmc/video/jobs/VideoLibraryRefreshingJob.cpp15
-rw-r--r--xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp5
-rw-r--r--xbmc/video/jobs/VideoLibraryScanningJob.h2
-rw-r--r--xbmc/video/tags/IVideoInfoTagLoader.h2
-rw-r--r--xbmc/video/tags/VideoInfoTagLoaderFactory.cpp5
-rw-r--r--xbmc/video/tags/VideoInfoTagLoaderFactory.h4
-rw-r--r--xbmc/video/tags/VideoTagExtractionHelper.cpp5
-rw-r--r--xbmc/video/tags/VideoTagExtractionHelper.h7
-rw-r--r--xbmc/video/tags/VideoTagLoaderFFmpeg.h2
-rw-r--r--xbmc/video/tags/VideoTagLoaderNFO.cpp1
-rw-r--r--xbmc/video/tags/VideoTagLoaderNFO.h2
-rw-r--r--xbmc/video/tags/VideoTagLoaderPlugin.cpp1
-rw-r--r--xbmc/video/tags/VideoTagLoaderPlugin.h2
-rw-r--r--xbmc/video/test/CMakeLists.txt1
-rw-r--r--xbmc/video/test/TestStacks.cpp1
-rw-r--r--xbmc/video/test/TestVideoFileItemClassify.cpp223
-rw-r--r--xbmc/video/test/TestVideoInfoScanner.cpp12
-rw-r--r--xbmc/video/test/TestVideoUtils.cpp5
-rw-r--r--xbmc/video/windows/GUIWindowFullScreen.cpp23
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.cpp110
-rw-r--r--xbmc/video/windows/GUIWindowVideoBase.h8
-rw-r--r--xbmc/video/windows/GUIWindowVideoNav.cpp23
-rw-r--r--xbmc/video/windows/GUIWindowVideoPlaylist.cpp8
-rw-r--r--xbmc/video/windows/VideoFileItemListModifier.cpp7
-rw-r--r--xbmc/view/GUIViewControl.cpp1
-rw-r--r--xbmc/view/GUIViewState.cpp3
-rw-r--r--xbmc/windowing/GraphicContext.cpp39
-rw-r--r--xbmc/windowing/GraphicContext.h46
-rw-r--r--xbmc/windowing/X11/GLContextEGL.cpp2
-rw-r--r--xbmc/windowing/android/AndroidUtils.cpp218
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLView.h11
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLView.mm21
-rw-r--r--xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm18
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.h1
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.mm12
-rw-r--r--xbmc/windowing/wayland/CMakeLists.txt2
-rw-r--r--xbmc/windowing/wayland/Seat.cpp9
-rw-r--r--xbmc/windowing/wayland/Seat.h10
-rw-r--r--xbmc/windowing/wayland/SeatWebOS.cpp29
-rw-r--r--xbmc/windowing/wayland/SeatWebOS.h33
-rw-r--r--xbmc/windowing/wayland/ShellSurfaceWebOSShell.cpp6
-rw-r--r--xbmc/windowing/wayland/WinSystemWayland.cpp29
-rw-r--r--xbmc/windowing/wayland/WinSystemWayland.h4
-rw-r--r--xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp19
-rw-r--r--xbmc/windowing/wayland/WinSystemWaylandWebOS.h3
-rw-r--r--xbmc/windowing/wayland/XkbcommonKeymap.cpp1
-rw-r--r--xbmc/windowing/win10/WinSystemWin10.cpp9
-rw-r--r--xbmc/windowing/win10/WinSystemWin10.h4
-rw-r--r--xbmc/windowing/win10/WinSystemWin10DX.cpp17
-rw-r--r--xbmc/windows/GUIMediaWindow.cpp54
-rw-r--r--xbmc/windows/GUIWindowDebugInfo.cpp6
-rw-r--r--xbmc/windows/GUIWindowFileManager.cpp6
-rw-r--r--xbmc/windows/GUIWindowLoginScreen.cpp1
604 files changed, 8377 insertions, 25073 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1f0253ee10..1b4348f7a7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -89,6 +89,7 @@ option(ENABLE_INTERNAL_FFMPEG "Enable internal ffmpeg?" OFF)
# These are built for all platforms not using system libs or disabled by user
dependent_option(ENABLE_INTERNAL_CEC "Enable internal libcec?")
+dependent_option(ENABLE_INTERNAL_CURL "Enable internal libcurl?")
dependent_option(ENABLE_INTERNAL_FLATBUFFERS "Enable internal flatbuffers?")
dependent_option(ENABLE_INTERNAL_FMT "Enable internal fmt?")
dependent_option(ENABLE_INTERNAL_NFS "Enable internal libnfs?")
@@ -185,6 +186,7 @@ endforeach()
set(required_buildtools FlatC
JsonSchemaBuilder
TexturePacker
+ ${PLATFORM_REQUIRED_TOOLS}
)
# Optional build tools
diff --git a/addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.it_it/strings.po b/addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.it_it/strings.po
index 2695c99b70..9f98ca875c 100644
--- a/addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.it_it/strings.po
+++ b/addons/audioencoder.kodi.builtin.aac/resources/language/resource.language.it_it/strings.po
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: KODI Main\n"
"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2022-12-12 07:26+0000\n"
+"PO-Revision-Date: 2024-04-14 16:18+0000\n"
"Last-Translator: Massimo Pissarello <mapi68@gmail.com>\n"
"Language-Team: Italian <https://kodi.weblate.cloud/projects/kodi-core/audioencoder-kodi-builtin-aac/it_it/>\n"
"Language: it_it\n"
@@ -15,7 +15,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.14.2\n"
+"X-Generator: Weblate 5.4.3\n"
msgctxt "Addon Summary"
msgid "AAC Audio Encoder"
@@ -35,7 +35,7 @@ msgstr "Bitrate"
#: resources/settings.xml
msgctxt "#30001"
msgid "Select which bitrate to use for the AAC audio encoder for audio compression."
-msgstr "Seleziona quale bitrate utilizzare per il codificatore Audio AAC per la compressione Audio."
+msgstr "Seleziona quale bitrate utilizzare per il codificatore Audio AAC per la compressione audio."
#. Value format for with bitrate edited field
#: resources/settings.xml
diff --git a/addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.et_ee/strings.po b/addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.et_ee/strings.po
index e1c5b0f3a8..778c45aa62 100644
--- a/addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.et_ee/strings.po
+++ b/addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.et_ee/strings.po
@@ -7,23 +7,23 @@ msgstr ""
"Project-Id-Version: KODI Main\n"
"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2022-02-26 16:13+0000\n"
-"Last-Translator: Christian Gade <gade@kodi.tv>\n"
+"PO-Revision-Date: 2024-03-22 07:13+0000\n"
+"Last-Translator: rimasx <riks_12@hot.ee>\n"
"Language-Team: Estonian <https://kodi.weblate.cloud/projects/kodi-core/audioencoder-kodi-builtin-wma/et_ee/>\n"
"Language: et_ee\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.11\n"
+"X-Generator: Weblate 5.4\n"
msgctxt "Addon Summary"
msgid "WMA Audio Encoder"
-msgstr ""
+msgstr "WMA helidekooder"
msgctxt "Addon Description"
msgid "Windows Media Audio, Microsoft’s lossy audio format."
-msgstr ""
+msgstr "Windows Media Audio, Microsofti kadudega helivorming."
#. Bitrate to use on for compression
#: resources/settings.xml
@@ -35,7 +35,7 @@ msgstr "Bitikiirus"
#: resources/settings.xml
msgctxt "#30001"
msgid "Select which bitrate to use for the WMA audio encoder for audio compression."
-msgstr ""
+msgstr "Vali, millist bitikiirust kasutada heli tihendamiseks WMA helikodeerija jaoks."
#. Value format for with bitrate edited field
#: resources/settings.xml
diff --git a/addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.it_it/strings.po b/addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.it_it/strings.po
index 68762bc46f..29a812bd6c 100644
--- a/addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.it_it/strings.po
+++ b/addons/audioencoder.kodi.builtin.wma/resources/language/resource.language.it_it/strings.po
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: KODI Main\n"
"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2022-12-12 07:26+0000\n"
+"PO-Revision-Date: 2024-04-14 16:18+0000\n"
"Last-Translator: Massimo Pissarello <mapi68@gmail.com>\n"
"Language-Team: Italian <https://kodi.weblate.cloud/projects/kodi-core/audioencoder-kodi-builtin-wma/it_it/>\n"
"Language: it_it\n"
@@ -15,15 +15,15 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.14.2\n"
+"X-Generator: Weblate 5.4.3\n"
msgctxt "Addon Summary"
msgid "WMA Audio Encoder"
-msgstr "Codificatore Audio WMA"
+msgstr "Codificatore audio WMA"
msgctxt "Addon Description"
msgid "Windows Media Audio, Microsoft’s lossy audio format."
-msgstr "Windows Media Audio, il formato Audio con perdita di dati di Microsoft."
+msgstr "Windows Media Audio, il formato audio con perdita di dati di Microsoft."
#. Bitrate to use on for compression
#: resources/settings.xml
@@ -35,7 +35,7 @@ msgstr "Bitrate"
#: resources/settings.xml
msgctxt "#30001"
msgid "Select which bitrate to use for the WMA audio encoder for audio compression."
-msgstr "Seleziona quale bitrate utilizzare per il codificatore Audio WMA per la compressione Audio."
+msgstr "Seleziona quale bitrate usare per il codificatore audio WMA per la compressione audio."
#. Value format for with bitrate edited field
#: resources/settings.xml
diff --git a/addons/game.controller.keyboard/addon.xml b/addons/game.controller.keyboard/addon.xml
index ff0533f16d..b84e675e8e 100644
--- a/addons/game.controller.keyboard/addon.xml
+++ b/addons/game.controller.keyboard/addon.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="game.controller.keyboard"
name="IBM Model M Keyboard"
- version="1.1.40"
+ version="1.1.43"
provider-name="Team Kodi">
<extension point="kodi.game.controller" library="resources/layout.xml"/>
<extension point="xbmc.addon.metadata">
diff --git a/addons/game.controller.keyboard/resources/language/resource.language.es_es/strings.po b/addons/game.controller.keyboard/resources/language/resource.language.es_es/strings.po
index e858636623..acb5810fd2 100644
--- a/addons/game.controller.keyboard/resources/language/resource.language.es_es/strings.po
+++ b/addons/game.controller.keyboard/resources/language/resource.language.es_es/strings.po
@@ -5,9 +5,9 @@
msgid ""
msgstr ""
"Project-Id-Version: KODI Addons\n"
-"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: 2014-05-30 17:00+8\n"
-"PO-Revision-Date: 2024-01-19 21:17+0000\n"
+"PO-Revision-Date: 2024-02-11 17:28+0000\n"
"Last-Translator: José Antonio Alvarado <jalvarado0.eses@gmail.com>\n"
"Language-Team: Spanish (Spain) <https://kodi.weblate.cloud/projects/kodi-add-ons-game/game-controller-keyboard/es_es/>\n"
"Language: es_es\n"
@@ -584,7 +584,7 @@ msgstr "Deshacer"
msgctxt "#30139"
msgid "Num Pad ="
-msgstr ""
+msgstr "Bloq Num ="
msgctxt "#30140"
msgid "Clear"
diff --git a/addons/game.controller.keyboard/resources/language/resource.language.it_it/strings.po b/addons/game.controller.keyboard/resources/language/resource.language.it_it/strings.po
index 2fd4f761d6..c9a302e561 100644
--- a/addons/game.controller.keyboard/resources/language/resource.language.it_it/strings.po
+++ b/addons/game.controller.keyboard/resources/language/resource.language.it_it/strings.po
@@ -5,9 +5,9 @@
msgid ""
msgstr ""
"Project-Id-Version: KODI Addons\n"
-"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: 2014-05-30 17:00+8\n"
-"PO-Revision-Date: 2024-02-03 03:13+0000\n"
+"PO-Revision-Date: 2024-03-26 17:55+0000\n"
"Last-Translator: Massimo Pissarello <mapi68@gmail.com>\n"
"Language-Team: Italian <https://kodi.weblate.cloud/projects/kodi-add-ons-game/game-controller-keyboard/it_it/>\n"
"Language: it_it\n"
@@ -15,7 +15,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.3\n"
+"X-Generator: Weblate 5.4\n"
msgctxt "Addon Summary"
msgid "IBM Model M keyboard"
@@ -584,7 +584,7 @@ msgstr "Annulla"
msgctxt "#30139"
msgid "Num Pad ="
-msgstr ""
+msgstr "Tastierino numerico ="
msgctxt "#30140"
msgid "Clear"
diff --git a/addons/game.controller.keyboard/resources/language/resource.language.ru_ru/strings.po b/addons/game.controller.keyboard/resources/language/resource.language.ru_ru/strings.po
index 0ca54021eb..6db64f0829 100644
--- a/addons/game.controller.keyboard/resources/language/resource.language.ru_ru/strings.po
+++ b/addons/game.controller.keyboard/resources/language/resource.language.ru_ru/strings.po
@@ -5,17 +5,17 @@
msgid ""
msgstr ""
"Project-Id-Version: KODI Addons\n"
-"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: 2014-05-30 17:00+8\n"
-"PO-Revision-Date: 2021-08-15 09:52+0000\n"
-"Last-Translator: Dmitry Petrov <dimakrm361@gmail.com>\n"
+"PO-Revision-Date: 2024-02-24 20:13+0000\n"
+"Last-Translator: Alexey <signfinder@gmail.com>\n"
"Language-Team: Russian <https://kodi.weblate.cloud/projects/kodi-add-ons-game/game-controller-keyboard/ru_ru/>\n"
"Language: ru_ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7.2\n"
+"X-Generator: Weblate 5.4\n"
msgctxt "Addon Summary"
msgid "IBM Model M keyboard"
@@ -460,11 +460,11 @@ msgstr "Правая Meta"
msgctxt "#30108"
msgid "Left Windows"
-msgstr ""
+msgstr "Левые окна"
msgctxt "#30109"
msgid "Right Windows"
-msgstr ""
+msgstr "Правые окна"
msgctxt "#30110"
msgid "!"
@@ -548,7 +548,7 @@ msgstr "~"
msgctxt "#30130"
msgid "Mode/Option"
-msgstr ""
+msgstr "Режим/опция"
msgctxt "#30131"
msgid "Compose"
@@ -584,7 +584,7 @@ msgstr "Undo"
msgctxt "#30139"
msgid "Num Pad ="
-msgstr ""
+msgstr "Цифровая клавиатура ="
msgctxt "#30140"
msgid "Clear"
@@ -592,7 +592,7 @@ msgstr "Clear"
msgctxt "#30141"
msgid "OEM 102nd Key"
-msgstr ""
+msgstr "OEM 102 клавиши"
#~ msgctxt "#30139"
#~ msgid "Num Pad Equals"
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
index def97f0a12..2108600360 100644
--- a/addons/resource.language.en_gb/resources/strings.po
+++ b/addons/resource.language.en_gb/resources/strings.po
@@ -7289,7 +7289,12 @@ msgctxt "#13423"
msgid "Remember for this path"
msgstr ""
-#empty string with id 13424
+#. Shown on context menu when a bluray:// or dvd:// playlist has already been saved
+#. Giving the user a chance to select a new one via the simple menu dialog
+#: xbmc/video/windows/GUIWindowVideoBase.cpp
+msgctxt "#13424"
+msgid "Choose playlist"
+msgstr ""
#: system/settings/settings.xml
msgctxt "#13425"
diff --git a/addons/skin.estuary/language/resource.language.sk_sk/strings.po b/addons/skin.estuary/language/resource.language.sk_sk/strings.po
index fdeb878d90..6ee6325111 100644
--- a/addons/skin.estuary/language/resource.language.sk_sk/strings.po
+++ b/addons/skin.estuary/language/resource.language.sk_sk/strings.po
@@ -5,17 +5,17 @@
msgid ""
msgstr ""
"Project-Id-Version: KODI Main\n"
-"Report-Msgid-Bugs-To: https://github.com/xbmc/xbmc/issues/\n"
+"Report-Msgid-Bugs-To: translations@kodi.tv\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"PO-Revision-Date: 2023-09-14 18:32+0000\n"
-"Last-Translator: Jose Riha <jose1711@gmail.com>\n"
+"PO-Revision-Date: 2024-04-02 18:25+0000\n"
+"Last-Translator: nextlooper42 <nextlooper42@protonmail.com>\n"
"Language-Team: Slovak <https://kodi.weblate.cloud/projects/kodi-add-ons-skins/skin-estuary/sk_sk/>\n"
"Language: sk_sk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);\n"
-"X-Generator: Weblate 5.0.1\n"
+"X-Generator: Weblate 5.4\n"
msgctxt "Addon Summary"
msgid "Estuary skin by phil65. (Kodi's default skin)"
@@ -488,7 +488,7 @@ msgstr "Zostáva"
msgctxt "#31135"
msgid "Binary"
-msgstr "Binary"
+msgstr "Binárna"
msgctxt "#31136"
msgid "Click here to see latest changes..."
diff --git a/addons/skin.estuary/xml/DialogPVRInfo.xml b/addons/skin.estuary/xml/DialogPVRInfo.xml
index 124915745a..44d9e56fc2 100644
--- a/addons/skin.estuary/xml/DialogPVRInfo.xml
+++ b/addons/skin.estuary/xml/DialogPVRInfo.xml
@@ -49,7 +49,7 @@
<width>1050</width>
<height>425</height>
<align>justify</align>
- <label>$INFO[ListItem.ChannelName,[B],[/B][CR]]$INFO[ListItem.Date,[COLOR grey]$LOCALIZE[552]:[/COLOR] ,[CR]]$INFO[ListItem.Duration,[COLOR grey]$LOCALIZE[180]:[/COLOR] ,[CR]]$VAR[RecordingSizeLabel]$VAR[PremieredLabel]$INFO[ListItem.Rating,[COLOR grey]$LOCALIZE[563]:[/COLOR] ,[CR]]$VAR[ExpirationDateTimeLabel]$INFO[ListItem.Genre,[COLOR grey]$LOCALIZE[515]: [/COLOR]][CR]$INFO[ListItem.ParentalRatingCode,[COLOR grey]$LOCALIZE[31017]: [/COLOR],[CR]]$INFO[ListItem.Writer,[COLOR grey]$LOCALIZE[20417]:[/COLOR] ,[CR]]$INFO[ListItem.Director,[COLOR grey]$LOCALIZE[20339]:[/COLOR] ,[CR]]$INFO[ListItem.Cast,[COLOR grey]$LOCALIZE[206]:[/COLOR] ,[CR]][CR]$INFO[ListItem.Plot]</label>
+ <label>$INFO[ListItem.ChannelName,[B],[/B][CR]]$INFO[ListItem.Date,[COLOR grey]$LOCALIZE[552]:[/COLOR] ,[CR]]$INFO[ListItem.Duration,[COLOR grey]$LOCALIZE[180]:[/COLOR] ,[CR]]$VAR[RecordingSizeLabel]$VAR[PremieredLabel]$INFO[ListItem.Rating,[COLOR grey]$LOCALIZE[563]:[/COLOR] ,[CR]]$VAR[ExpirationDateTimeLabel]$VAR[PVRInstanceName]$INFO[ListItem.Genre,[COLOR grey]$LOCALIZE[515]: [/COLOR]][CR]$INFO[ListItem.ParentalRatingCode,[COLOR grey]$LOCALIZE[31017]: [/COLOR],[CR]]$INFO[ListItem.Writer,[COLOR grey]$LOCALIZE[20417]:[/COLOR] ,[CR]]$INFO[ListItem.Director,[COLOR grey]$LOCALIZE[20339]:[/COLOR] ,[CR]]$INFO[ListItem.Cast,[COLOR grey]$LOCALIZE[206]:[/COLOR] ,[CR]][CR]$INFO[ListItem.Plot]</label>
<autoscroll time="3000" delay="4000" repeat="5000">Skin.HasSetting(AutoScroll)</autoscroll>
</control>
<control type="grouplist" id="9000">
diff --git a/addons/skin.estuary/xml/Includes_PVR.xml b/addons/skin.estuary/xml/Includes_PVR.xml
index c5da145a01..c4081f232f 100644
--- a/addons/skin.estuary/xml/Includes_PVR.xml
+++ b/addons/skin.estuary/xml/Includes_PVR.xml
@@ -440,7 +440,7 @@
<top>465</top>
<width>830</width>
<bottom>list_bottom_offset</bottom>
- <label>$VAR[FlagLabel,,[CR]]$INFO[ListItem.Genre,[COLOR grey]$LOCALIZE[515]:[/COLOR] ,[CR]]$INFO[ListItem.ParentalRatingCode,[COLOR grey]$LOCALIZE[31017]: [/COLOR],[CR]]$INFO[ListItem.TimerType,[COLOR grey]$LOCALIZE[803]:[/COLOR] ,[CR]]$VAR[RecordingSizeLabel]$VAR[ExpirationDateTimeLabel]$INFO[ListItem.Plot,[CR]]</label>
+ <label>$VAR[PVRInstanceName]$VAR[FlagLabel,,[CR]]$INFO[ListItem.Genre,[COLOR grey]$LOCALIZE[515]:[/COLOR] ,[CR]]$INFO[ListItem.ParentalRatingCode,[COLOR grey]$LOCALIZE[31017]: [/COLOR],[CR]]$INFO[ListItem.TimerType,[COLOR grey]$LOCALIZE[803]:[/COLOR] ,[CR]]$VAR[RecordingSizeLabel]$VAR[ExpirationDateTimeLabel]$INFO[ListItem.Plot,[CR]]</label>
<autoscroll delay="10000" time="3000" repeat="10000">Skin.HasSetting(AutoScroll)</autoscroll>
</control>
</control>
@@ -451,7 +451,7 @@
<top>10</top>
<width>830</width>
<height>262</height>
- <label>$LOCALIZE[19076] ($INFO[Container(5000).NumItems,[B],[/B] $LOCALIZE[31036]]) $INFO[ListItem.Property(recordingsize),- $LOCALIZE[20161]: [B],[/B]]</label>
+ <label>$LOCALIZE[19076] ($INFO[Container(5000).NumItems,[B],[/B] $LOCALIZE[31036]]) $INFO[ListItem.Property(recordingsize),- $LOCALIZE[20161]: [B],[/B]] $VAR[PVRInstanceName]</label>
<font>font37</font>
<visible>!ListItem.IsParentFolder</visible>
</control>
diff --git a/addons/skin.estuary/xml/Variables.xml b/addons/skin.estuary/xml/Variables.xml
index eaca6cd065..06d8b9b2b1 100644
--- a/addons/skin.estuary/xml/Variables.xml
+++ b/addons/skin.estuary/xml/Variables.xml
@@ -697,16 +697,16 @@
<value condition="!String.IsEmpty(Container(6).ListItem.Art(thumb))">$INFO[Container(6).ListItem.Art(thumb)]</value>
<value condition="!String.IsEmpty(Container(50).ListItem.Art(landscape))">$INFO[Container(50).ListItem.Art(landscape)]</value>
<value condition="!String.IsEmpty(Container(50).ListItem.Art(thumb))">$INFO[Container(50).ListItem.Art(thumb)]</value>
- <value>$INFO[ListItem.Art(thumb)]</value>
+ <value>$INFO[ListItem.Art(thumb)]</value>
</variable>
<variable name="VideoResolutionTypeVar">
<value condition="String.IsEqual(ListItem.VideoResolution,480)">SD</value>
<value condition="String.IsEqual(ListItem.VideoResolution,540)">SD</value>
<value condition="String.IsEqual(ListItem.VideoResolution,576)">SD</value>
<value condition="String.IsEqual(ListItem.VideoResolution,720)">HD</value>
- <value condition="String.IsEqual(ListItem.VideoResolution,1080)">HD</value>
+ <value condition="String.IsEqual(ListItem.VideoResolution,1080)">HD</value>
<value condition="String.IsEqual(ListItem.VideoResolution,4K)">UHD</value>
- <value condition="String.IsEqual(ListItem.VideoResolution,8K)">UHD</value>
+ <value condition="String.IsEqual(ListItem.VideoResolution,8K)">UHD</value>
</variable>
<variable name="VideoCodecVar">
<value condition="String.IsEqual(ListItem.VideoCodec,av1)">AV1</value>
@@ -798,4 +798,7 @@
<value condition="ListItem.IsStereoscopic">$INFO[ListItem.Duration,$LOCALIZE[180]: ][CR]$VAR[VideoCodecVar,, ]$INFO[ListItem.VideoResolution,| , ]$VAR[VideoResolutionTypeVar,, ]$VAR[VideoHDRVar,| , ]| 3D $INFO[ListItem.VideoAspect,| ,:1 ]$VAR[AudioCodecVar,| , ]$VAR[AudioChannelsVar]</value>
<value>$INFO[ListItem.Duration,$LOCALIZE[180]: ][CR]$VAR[VideoCodecVar,, ]$INFO[ListItem.VideoResolution,| , ]$VAR[VideoResolutionTypeVar,, ]$VAR[VideoHDRVar,| , ]$INFO[ListItem.VideoAspect,| ,:1 ]$VAR[AudioCodecVar,| , ]$VAR[AudioChannelsVar]</value>
</variable>
+ <variable name="PVRInstanceName">
+ <value condition="Integer.IsGreater(System.PVRCount,1)">$INFO[ListItem.BackendInstanceName,[COLOR grey]$LOCALIZE[31137]:[/COLOR] ,[CR]]</value>
+ </variable>
</includes>
diff --git a/cmake/modules/FindBrotli.cmake b/cmake/modules/FindBrotli.cmake
new file mode 100644
index 0000000000..3b8a0befc6
--- /dev/null
+++ b/cmake/modules/FindBrotli.cmake
@@ -0,0 +1,68 @@
+#.rst:
+# FindBrotli
+# ----------
+# Finds the Brotli library
+#
+# This will define the following target ALIAS:
+#
+# Brotli::Brotli - The Brotli library
+#
+# The following IMPORTED targets are made
+#
+# Brotli::BrotliCommon - The brotlicommon library
+# Brotli::BrotliDec - The brotlidec library
+#
+
+if(NOT TARGET Brotli::Brotli)
+ find_package(PkgConfig)
+ if(PKG_CONFIG_FOUND AND NOT (WIN32 OR WINDOWSSTORE))
+ pkg_check_modules(BROTLICOMMON libbrotlicommon QUIET)
+ # First item is the full path of the library file found
+ # pkg_check_modules does not populate a variable of the found library explicitly
+ list(GET BROTLICOMMON_LINK_LIBRARIES 0 BROTLICOMMON_LIBRARY)
+
+ pkg_check_modules(BROTLIDEC libbrotlidec QUIET)
+ # First item is the full path of the library file found
+ # pkg_check_modules does not populate a variable of the found library explicitly
+ list(GET BROTLIDEC_LINK_LIBRARIES 0 BROTLIDEC_LIBRARY)
+
+ set(BROTLI_INCLUDE_DIR ${BROTLICOMMON_INCLUDEDIR})
+ set(BROTLI_VERSION ${BROTLICOMMON_VERSION})
+ else()
+ find_path(BROTLI_INCLUDE_DIR NAMES brotli/decode.h
+ HINTS ${DEPENDS_PATH}/include ${BROTLICOMMON_INCLUDEDIR}
+ ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
+ find_library(BROTLICOMMON_LIBRARY NAMES brotlicommon
+ HINTS ${DEPENDS_PATH}/lib ${BROTLICOMON_LIBDIR}
+ ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
+
+ find_library(BROTLIDEC_LIBRARY NAMES brotlidec
+ HINTS ${DEPENDS_PATH}/lib ${BROTLIDEC_LIBDIR}
+ ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
+ endif()
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Brotli
+ REQUIRED_VARS BROTLICOMMON_LIBRARY BROTLIDEC_LIBRARY BROTLI_INCLUDE_DIR
+ VERSION_VAR BROTLI_VERSION)
+
+ if(BROTLI_FOUND)
+ add_library(Brotli::BrotliCommon UNKNOWN IMPORTED)
+ set_target_properties(Brotli::BrotliCommon PROPERTIES
+ IMPORTED_LOCATION "${BROTLICOMMON_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${BROTLI_INCLUDE_DIR}")
+
+ add_library(Brotli::BrotliDec UNKNOWN IMPORTED)
+ set_target_properties(Brotli::BrotliDec PROPERTIES
+ IMPORTED_LOCATION "${BROTLIDEC_LIBRARY}"
+ INTERFACE_LINK_LIBRARIES Brotli::BrotliCommon
+ INTERFACE_INCLUDE_DIRECTORIES "${BROTLI_INCLUDE_DIR}")
+
+ add_library(Brotli::Brotli ALIAS Brotli::BrotliDec)
+
+ else()
+ if(Brotli_FIND_REQUIRED)
+ message(FATAL_ERROR "Brotli libraries were not found.")
+ endif()
+ endif()
+endif()
diff --git a/cmake/modules/FindCurl.cmake b/cmake/modules/FindCurl.cmake
index fba339bc9d..3872b9c64a 100644
--- a/cmake/modules/FindCurl.cmake
+++ b/cmake/modules/FindCurl.cmake
@@ -3,62 +3,220 @@
# --------
# Finds the Curl library
#
-# This will define the following variables::
-#
-# CURL_FOUND - system has Curl
-# CURL_INCLUDE_DIRS - the Curl include directory
-# CURL_LIBRARIES - the Curl libraries
-# CURL_DEFINITIONS - the Curl definitions
-#
-# and the following imported targets::
+# This will define the following target:
#
# Curl::Curl - The Curl library
-find_package(PkgConfig)
+if(NOT TARGET Curl::Curl)
+ include(cmake/scripts/common/ModuleHelpers.cmake)
-if(PKG_CONFIG_FOUND)
- pkg_check_modules(PC_CURL libcurl QUIET)
-endif()
+ macro(buildCurl)
-find_path(CURL_INCLUDE_DIR NAMES curl/curl.h
- HINTS ${PC_CURL_INCLUDEDIR})
-find_library(CURL_LIBRARY NAMES curl libcurl libcurl_imp
- HINTS ${PC_CURL_LIBDIR})
+ find_package(NGHttp2 REQUIRED QUIET)
+ find_package(OpenSSL REQUIRED QUIET)
+ find_package(Brotli REQUIRED QUIET)
-set(CURL_VERSION ${PC_CURL_VERSION})
+ # Darwin platforms link against toolchain provided zlib regardless
+ # They will fail when searching for static. All other platforms, prefer static
+ # if possible (requires cmake 3.24+ otherwise variable is a no-op)
+ # Windows still uses dynamic lib for zlib for other purposes, dont mix
+ if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" AND NOT (WIN32 OR WINDOWS_STORE))
+ set(ZLIB_USE_STATIC_LIBS ON)
+ endif()
+ find_package(ZLIB REQUIRED)
+ unset(ZLIB_USE_STATIC_LIBS)
-set(CURL_LIB_TYPE SHARED)
-set(CURL_LDFLAGS ${PC_CURL_LDFLAGS})
+ set(CURL_VERSION ${${MODULE}_VER})
+ # Curl debug uses postfix -d for all platforms
+ set(CURL_DEBUG_POSTFIX -d)
-# check if curl is statically linked
-if(${CURL_LIBRARY} MATCHES ".+\.a$" AND PC_CURL_STATIC_LDFLAGS)
- set(CURL_LIB_TYPE STATIC)
- set(CURL_LDFLAGS ${PC_CURL_STATIC_LDFLAGS})
+ if(WIN32 OR WINDOWS_STORE)
+ set(CURL_C_FLAGS -DNGHTTP2_STATICLIB)
+ set(PLATFORM_LINK_LIBS crypt32.lib)
+ endif()
- pkg_check_modules(PC_NGHTTP2 libnghttp2 QUIET)
- find_library(NGHTTP2_LIBRARY NAMES libnghttp2 nghttp2
- HINTS ${PC_NGHTTP2_LIBDIR})
-endif()
+ set(patches "${CORE_SOURCE_DIR}/tools/depends/target/${MODULE_LC}/01-win-nghttp2-add-name.patch")
+
+ generate_patchcommand("${patches}")
+
+ set(CMAKE_ARGS -DBUILD_CURL_EXE=OFF
+ -DBUILD_SHARED_LIBS=OFF
+ -DBUILD_STATIC_LIBS=ON
+ -DBUILD_LIBCURL_DOCS=OFF
+ -DENABLE_CURL_MANUAL=OFF
+ -DCURL_DISABLE_TESTS=OFF
+ -DCURL_DISABLE_LDAP=ON
+ -DCURL_DISABLE_LDAPS=ON
+ -DCURL_DISABLE_SMB=OFF
+ -DCURL_USE_OPENSSL=ON
+ -DOPENSSL_ROOT_DIR=${DEPENDS_PATH}
+ -DCURL_BROTLI=ON
+ -DUSE_NGHTTP2=ON
+ -DUSE_LIBIDN2=OFF
+ -DCURL_USE_LIBSSH2=OFF
+ -DCURL_USE_GSSAPI=OFF
+ -DCURL_CA_FALLBACK=ON
+ ${OPTIONAL_ARGS})
+
+ BUILD_DEP_TARGET()
+
+ # Link libraries for target interface
+ set(PC_CURL_LINK_LIBRARIES Brotli::Brotli OpenSSL::Crypto OpenSSL::SSL NGHttp2::NGHttp2 ZLIB::ZLIB ${PLATFORM_LINK_LIBS})
+
+ # Add dependencies to build target
+ add_dependencies(${MODULE_LC} NGHttp2::NGHttp2)
+ add_dependencies(${MODULE_LC} OpenSSL::SSL)
+ add_dependencies(${MODULE_LC} OpenSSL::Crypto)
+ add_dependencies(${MODULE_LC} ZLIB::ZLIB)
+ add_dependencies(${MODULE_LC} Brotli::Brotli)
+ endmacro()
+
+ set(MODULE_LC curl)
+
+ SETUP_BUILD_VARS()
+
+ find_package(CURL CONFIG QUIET
+ HINTS ${DEPENDS_PATH}/lib/cmake
+ ${${CORE_PLATFORM_NAME_LC}_SEARCH_CONFIG})
+
+ # Check for existing Curl. If version >= CURL-VERSION file version, dont build
+ # A corner case, but if a linux/freebsd user WANTS to build internal curl, build anyway
+ if((CURL_VERSION VERSION_LESS ${${MODULE}_VER} AND ENABLE_INTERNAL_CURL) OR
+ ((CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd) AND ENABLE_INTERNAL_CURL))
+
+ buildCurl()
+ else()
+ # Maybe need to look explicitly for CURL::libcurl_static/shared?
+ if(NOT TARGET CURL::libcurl)
+ find_package(PkgConfig)
+
+ # We only rely on pkgconfig for non windows platforms
+ if(PKG_CONFIG_FOUND AND NOT (WIN32 OR WINDOWS_STORE))
+ pkg_check_modules(CURL libcurl QUIET)
+
+ # First item is the full path of the library file found
+ # pkg_check_modules does not populate a variable of the found library explicitly
+ list(GET CURL_LINK_LIBRARIES 0 CURL_LIBRARY_RELEASE)
+
+ # Add link libraries for static lib usage
+ if(${CURL_LIBRARY} MATCHES ".+\.a$" AND CURL_LINK_LIBRARIES)
+ # Remove duplicates
+ list(REMOVE_DUPLICATES CURL_LINK_LIBRARIES)
+
+ # Remove own library - eg libcurl.a
+ list(FILTER CURL_LINK_LIBRARIES EXCLUDE REGEX ".*curl.*\.a$")
+ set(PC_CURL_LINK_LIBRARIES ${CURL_LINK_LIBRARIES})
+ endif()
+
+ # pkgconfig sets CURL_INCLUDEDIR, map this to our "standard" variable name
+ set(CURL_INCLUDE_DIR ${CURL_INCLUDEDIR})
+ else()
+ find_path(CURL_INCLUDE_DIR NAMES curl/curl.h
+ HINTS ${DEPENDS_PATH}/include
+ ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
+ find_library(CURL_LIBRARY_RELEASE NAMES curl libcurl libcurl_imp
+ HINTS ${DEPENDS_PATH}/lib
+ ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
+ endif()
+ else()
+ # CURL::libcurl is an alias. We need to get the actual aias target, as we cant make an
+ # alias of an alias (ie our Curl::Curl cant be an alias of Curl::libcurl)
+ get_target_property(_CURL_ALIASTARGET CURL::libcurl ALIASED_TARGET)
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Curl
- REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR
- VERSION_VAR CURL_VERSION)
-
-if(CURL_FOUND)
- set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
- set(CURL_LIBRARIES ${CURL_LIBRARY} ${NGHTTP2_LIBRARY})
-
- if(NOT TARGET Curl::Curl)
- add_library(Curl::Curl ${CURL_LIB_TYPE} IMPORTED)
- set_target_properties(Curl::Curl PROPERTIES
- IMPORTED_LOCATION "${CURL_LIBRARY}"
- INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIR}")
- if(HAS_CURL_STATIC)
+ # This is for the case where a distro provides a non standard (Debug/Release) config type
+ # eg Debian's config file is CURLConfigTargets-none.cmake
+ # convert this back to either DEBUG/RELEASE or just RELEASE
+ # we only do this because we use find_package_handle_standard_args for config time output
+ # and it isnt capable of handling TARGETS, so we have to extract the info
+ get_target_property(_CURL_CONFIGURATIONS ${_CURL_ALIASTARGET} IMPORTED_CONFIGURATIONS)
+ foreach(_curl_config IN LISTS _CURL_CONFIGURATIONS)
+ # Some non standard config (eg None on Debian)
+ # Just set to RELEASE var so select_library_configurations can continue to work its magic
+ string(TOUPPER ${_curl_config} _curl_config_UPPER)
+ if((NOT ${_curl_config_UPPER} STREQUAL "RELEASE") AND
+ (NOT ${_curl_config_UPPER} STREQUAL "DEBUG"))
+ get_target_property(CURL_LIBRARY_RELEASE ${_CURL_ALIASTARGET} IMPORTED_LOCATION_${_curl_config_UPPER})
+ else()
+ get_target_property(CURL_LIBRARY_${_curl_config_UPPER} ${_CURL_ALIASTARGET} IMPORTED_LOCATION_${_curl_config_UPPER})
+ endif()
+ endforeach()
+
+ get_target_property(CURL_INCLUDE_DIR CURL::libcurl INTERFACE_INCLUDE_DIRECTORIES)
+ endif()
+ endif()
+
+ include(SelectLibraryConfigurations)
+ select_library_configurations(CURL)
+ unset(CURL_LIBRARIES)
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Curl
+ REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR
+ VERSION_VAR CURL_VERSION)
+
+ if(CURL_FOUND)
+ # cmake target and not building internal
+ if(TARGET CURL::libcurl AND NOT TARGET curl)
+ # CURL::libcurl is an alias. We need to get the actual aias target, as we cant make an
+ # alias of an alias (ie our Curl::Curl cant be an alias of Curl::libcurl)
+ if(NOT _CURL_ALIASTARGET)
+ get_target_property(_CURL_ALIASTARGET CURL::libcurl ALIASED_TARGET)
+ endif()
+
+ add_library(Curl::Curl ALIAS ${_CURL_ALIASTARGET})
+ else()
+ add_library(Curl::Curl UNKNOWN IMPORTED)
+ set_target_properties(Curl::Curl PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIR}")
+
+ if(CURL_LIBRARY_RELEASE)
+ set_target_properties(Curl::Curl PROPERTIES
+ IMPORTED_CONFIGURATIONS RELEASE
+ IMPORTED_LOCATION_RELEASE "${CURL_LIBRARY_RELEASE}")
+ endif()
+ if(CURL_LIBRARY_DEBUG)
+ set_target_properties(Curl::Curl PROPERTIES
+ IMPORTED_CONFIGURATIONS DEBUG
+ IMPORTED_LOCATION_DEBUG "${CURL_LIBRARY_DEBUG}")
+ endif()
+
+ # Add link libraries for static lib usage found from pkg-config
+ if(PC_CURL_LINK_LIBRARIES)
set_target_properties(Curl::Curl PROPERTIES
- INTERFACE_COMPILE_DEFINITIONS HAS_CURL_STATIC=1)
+ INTERFACE_LINK_LIBRARIES "${PC_CURL_LINK_LIBRARIES}")
+ endif()
+
+ if(WIN32 OR WINDOWS_STORE)
+ set_property(TARGET Curl::Curl APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "CURL_STATICLIB")
+ endif()
+
+ endif()
+
+ if(TARGET curl)
+ add_dependencies(Curl::Curl curl)
+ endif()
+
+ # Add internal build target when a Multi Config Generator is used
+ # We cant add a dependency based off a generator expression for targeted build types,
+ # https://gitlab.kitware.com/cmake/cmake/-/issues/19467
+ # therefore if the find heuristics only find the library, we add the internal build
+ # target to the project to allow user to manually trigger for any build type they need
+ # in case only a specific build type is actually available (eg Release found, Debug Required)
+ # This is mainly targeted for windows who required different runtime libs for different
+ # types, and they arent compatible
+ if(_multiconfig_generator)
+ if(NOT TARGET curl)
+ buildCurl()
+ set_target_properties(curl PROPERTIES EXCLUDE_FROM_ALL TRUE)
+ endif()
+ add_dependencies(build_internal_depends curl)
+ endif()
+
+ set_property(GLOBAL APPEND PROPERTY INTERNAL_DEPS_PROP Curl::Curl)
+
+ else()
+ if(Curl_FIND_REQUIRED)
+ message(FATAL_ERROR "Curl libraries were not found.")
endif()
endif()
endif()
-
-mark_as_advanced(CURL_INCLUDE_DIR CURL_LIBRARY CURL_LDFLAGS)
diff --git a/cmake/modules/FindD3DX11Effects.cmake b/cmake/modules/FindD3DX11Effects.cmake
deleted file mode 100644
index 0a43fd3807..0000000000
--- a/cmake/modules/FindD3DX11Effects.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# - Finds D3DX11 dependencies
-# Once done this will define
-#
-# FXC - Path to the DirectX Effects Compiler (FXC)
-
-find_program(FXC fxc
- PATHS
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;InstallationFolder]/bin/x86"
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;InstallationFolder]/bin/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;ProductVersion].0/x86"
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.1;InstallationFolder]/bin/x86"
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0;InstallationFolder]/bin/x86"
- "$ENV{WindowsSdkDir}bin/x86")
-if(NOT FXC)
- message(WARNING "Could NOT find DirectX Effects Compiler (FXC)")
-endif()
-mark_as_advanced(FXC)
diff --git a/cmake/modules/FindEffects11.cmake b/cmake/modules/FindEffects11.cmake
new file mode 100644
index 0000000000..0f4e4afaa8
--- /dev/null
+++ b/cmake/modules/FindEffects11.cmake
@@ -0,0 +1,121 @@
+# FindEffects11
+# -------
+# Finds the Effects11 library
+#
+# This will define the following target:
+#
+# windows::Effects11 - The Effects11 library
+
+if(NOT TARGET windows::Effects11)
+ include(cmake/scripts/common/ModuleHelpers.cmake)
+
+ macro(buildEffects11)
+
+ set(patches "${CMAKE_SOURCE_DIR}/tools/depends/target/${MODULE_LC}/01-win-debugpostfix.patch")
+ generate_patchcommand("${patches}")
+
+ # Effects 11 cant be built using /permissive-
+ # strip and manually set the rest of the build flags
+ string(REPLACE "/permissive-" "" EFFECTS_CXX_FLAGS ${CMAKE_CXX_FLAGS} )
+
+ set(CMAKE_ARGS
+ "-DCMAKE_CXX_FLAGS=${EFFECTS_CXX_FLAGS} $<$<CONFIG:Debug>:${CMAKE_CXX_FLAGS_DEBUG}> $<$<CONFIG:Release>:${CMAKE_CXX_FLAGS_RELEASE}>"
+ "-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS} $<$<CONFIG:Debug>:${CMAKE_EXE_LINKER_FLAGS_DEBUG}> $<$<CONFIG:Release>:${CMAKE_EXE_LINKER_FLAGS_RELEASE}>")
+
+ set(EFFECTS11_DEBUG_POSTFIX d)
+ set(WIN_DISABLE_PROJECT_FLAGS ON)
+
+ BUILD_DEP_TARGET()
+
+ set(EFFECTS11_VERSION ${${MODULE}_VER})
+
+ # Make INCLUDE_DIR match cmake config output
+ string(APPEND EFFECTS11_INCLUDE_DIR "/Effects11")
+ file(MAKE_DIRECTORY ${EFFECTS11_INCLUDE_DIR})
+ endmacro()
+
+ set(MODULE_LC effects11)
+
+ SETUP_BUILD_VARS()
+
+ find_package(effects11 CONFIG QUIET
+ HINTS ${DEPENDS_PATH}/share
+ ${${CORE_PLATFORM_NAME_LC}_SEARCH_CONFIG})
+
+ if(effects11_VERSION VERSION_LESS ${${MODULE}_VER})
+ buildEffects11()
+ else()
+ get_target_property(_EFFECTS_CONFIGURATIONS Microsoft::Effects11 IMPORTED_CONFIGURATIONS)
+ foreach(_effects_config IN LISTS _EFFECTS_CONFIGURATIONS)
+ # Some non standard config (eg None on Debian)
+ # Just set to RELEASE var so select_library_configurations can continue to work its magic
+ string(TOUPPER ${_effects_config} _effects_config_UPPER)
+ if((NOT ${_effects_config_UPPER} STREQUAL "RELEASE") AND
+ (NOT ${_effects_config_UPPER} STREQUAL "DEBUG"))
+ get_target_property(EFFECTS11_LIBRARY_RELEASE Microsoft::Effects11 IMPORTED_LOCATION_${_effects_config_UPPER})
+ else()
+ get_target_property(EFFECTS11_LIBRARY_${_effects_config_UPPER} Microsoft::Effects11 IMPORTED_LOCATION_${_effects_config_UPPER})
+ endif()
+ endforeach()
+
+ get_target_property(EFFECTS11_INCLUDE_DIR Microsoft::Effects11 INTERFACE_INCLUDE_DIRECTORIES)
+ set(EFFECTS11_VERSION ${effects11_VERSION})
+ endif()
+
+ include(SelectLibraryConfigurations)
+ select_library_configurations(EFFECTS11)
+ unset(EFFECTS11_LIBRARIES)
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Effects11
+ REQUIRED_VARS EFFECTS11_LIBRARY EFFECTS11_INCLUDE_DIR
+ VERSION_VAR EFFECTS11_VERSION)
+
+ if(Effects11_FOUND)
+
+ if(TARGET Microsoft::Effects11 AND NOT TARGET effects11)
+ add_library(windows::Effects11 ALIAS Microsoft::Effects11)
+ else()
+ add_library(windows::Effects11 UNKNOWN IMPORTED)
+ set_target_properties(windows::Effects11 PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${EFFECTS11_INCLUDE_DIR}")
+
+ if(EFFECTS11_LIBRARY_RELEASE)
+ set_target_properties(windows::Effects11 PROPERTIES
+ IMPORTED_CONFIGURATIONS RELEASE
+ IMPORTED_LOCATION_RELEASE "${EFFECTS11_LIBRARY_RELEASE}")
+ endif()
+ if(EFFECTS11_LIBRARY_DEBUG)
+ set_target_properties(windows::Effects11 PROPERTIES
+ IMPORTED_CONFIGURATIONS DEBUG
+ IMPORTED_LOCATION_DEBUG "${EFFECTS11_LIBRARY_DEBUG}")
+ endif()
+ endif()
+
+ if(TARGET effects11)
+ add_dependencies(windows::Effects11 effects11)
+ endif()
+
+ # Add internal build target when a Multi Config Generator is used
+ # We cant add a dependency based off a generator expression for targeted build types,
+ # https://gitlab.kitware.com/cmake/cmake/-/issues/19467
+ # therefore if the find heuristics only find the library, we add the internal build
+ # target to the project to allow user to manually trigger for any build type they need
+ # in case only a specific build type is actually available (eg Release found, Debug Required)
+ # This is mainly targeted for windows who required different runtime libs for different
+ # types, and they arent compatible
+ if(_multiconfig_generator)
+ if(NOT TARGET effects11)
+ buildEffects11()
+ set_target_properties(effects11 PROPERTIES EXCLUDE_FROM_ALL TRUE)
+ endif()
+ add_dependencies(build_internal_depends effects11)
+ endif()
+
+ set_property(GLOBAL APPEND PROPERTY INTERNAL_DEPS_PROP windows::Effects11)
+ else()
+ if(Effects11_FIND_REQUIRED)
+ message(FATAL_ERROR "Could NOT find or build Effects11 library.")
+ endif()
+ endif()
+endif()
diff --git a/cmake/modules/FindFlatBuffers.cmake b/cmake/modules/FindFlatBuffers.cmake
index 6288d1021a..841d14bc6a 100644
--- a/cmake/modules/FindFlatBuffers.cmake
+++ b/cmake/modules/FindFlatBuffers.cmake
@@ -4,18 +4,15 @@
#
# This will define the following target:
#
-# flatbuffers::flatbuffers - The flatbuffers headers
+# flatbuffers::flatheaders - The flatbuffers headers
find_package(FlatC REQUIRED)
-if(NOT TARGET flatbuffers::flatbuffers)
- if(ENABLE_INTERNAL_FLATBUFFERS)
- include(cmake/scripts/common/ModuleHelpers.cmake)
+if(NOT TARGET flatbuffers::flatheaders)
- set(MODULE_LC flatbuffers)
-
- SETUP_BUILD_VARS()
+ include(cmake/scripts/common/ModuleHelpers.cmake)
+ macro(buildflatbuffers)
# Override build type detection and always build as release
set(FLATBUFFERS_BUILD_TYPE Release)
@@ -31,6 +28,22 @@ if(NOT TARGET flatbuffers::flatbuffers)
set(BUILD_BYPRODUCTS ${DEPENDS_PATH}/include/flatbuffers/flatbuffers.h)
BUILD_DEP_TARGET()
+ endmacro()
+
+ set(MODULE_LC flatbuffers)
+
+ SETUP_BUILD_VARS()
+
+ find_package(flatbuffers CONFIG
+ HINTS ${DEPENDS_PATH}/lib/cmake
+ ${${CORE_PLATFORM_NAME_LC}_SEARCH_CONFIG})
+
+ # Check for existing Flatbuffers. If version >= FLATBUFFERS-VERSION file version, dont build
+ # A corner case, but if a linux/freebsd user WANTS to build internal flatbuffers, build anyway
+ if((flatbuffers_VERSION VERSION_LESS ${${MODULE}_VER} AND ENABLE_INTERNAL_FLATBUFFERS) OR
+ ((CORE_SYSTEM_NAME STREQUAL linux OR CORE_SYSTEM_NAME STREQUAL freebsd) AND ENABLE_INTERNAL_FLATBUFFERS))
+
+ buildflatbuffers()
else()
find_path(FLATBUFFERS_INCLUDE_DIR NAMES flatbuffers/flatbuffers.h
HINTS ${DEPENDS_PATH}/include
@@ -43,14 +56,38 @@ if(NOT TARGET flatbuffers::flatbuffers)
REQUIRED_VARS FLATBUFFERS_INCLUDE_DIR
VERSION_VAR FLATBUFFERS_VER)
- add_library(flatbuffers::flatbuffers INTERFACE IMPORTED)
- set_target_properties(flatbuffers::flatbuffers PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${FLATBUFFERS_INCLUDE_DIR}")
+ if(FlatBuffers_FOUND)
+
+ add_library(flatbuffers::flatheaders INTERFACE IMPORTED)
+ set_target_properties(flatbuffers::flatheaders PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${FLATBUFFERS_INCLUDE_DIR}")
+
+ add_dependencies(flatbuffers::flatheaders flatbuffers::flatc)
- add_dependencies(flatbuffers::flatbuffers flatbuffers::flatc)
+ if(TARGET flatbuffers)
+ add_dependencies(flatbuffers::flatheaders flatbuffers)
+ endif()
- if(TARGET flatbuffers)
- add_dependencies(flatbuffers::flatbuffers flatbuffers)
+ # Add internal build target when a Multi Config Generator is used
+ # We cant add a dependency based off a generator expression for targeted build types,
+ # https://gitlab.kitware.com/cmake/cmake/-/issues/19467
+ # therefore if the find heuristics only find the library, we add the internal build
+ # target to the project to allow user to manually trigger for any build type they need
+ # in case only a specific build type is actually available (eg Release found, Debug Required)
+ # This is mainly targeted for windows who required different runtime libs for different
+ # types, and they arent compatible
+ if(_multiconfig_generator)
+ if(NOT TARGET flatbuffers)
+ buildflatbuffers()
+ set_target_properties(flatbuffers PROPERTIES EXCLUDE_FROM_ALL TRUE)
+ endif()
+ add_dependencies(build_internal_depends flatbuffers)
+ endif()
+
+ set_property(GLOBAL APPEND PROPERTY INTERNAL_DEPS_PROP flatbuffers::flatheaders)
+ else()
+ if(FlatBuffers_FIND_REQUIRED)
+ message(FATAL_ERROR "Flatbuffer schema headers were not found. You may want to try -DENABLE_INTERNAL_FLATBUFFERS=ON to build the internal headers package")
+ endif()
endif()
- set_property(GLOBAL APPEND PROPERTY INTERNAL_DEPS_PROP flatbuffers::flatbuffers)
endif()
diff --git a/cmake/modules/FindNGHttp2.cmake b/cmake/modules/FindNGHttp2.cmake
new file mode 100644
index 0000000000..7dba36e0ed
--- /dev/null
+++ b/cmake/modules/FindNGHttp2.cmake
@@ -0,0 +1,52 @@
+#.rst:
+# FindNGHttp2
+# ----------
+# Finds the NGHttp2 library
+#
+# This will define the following target:
+#
+# NGHttp2::NGHttp2 - The NGHttp2 library
+
+if(NOT TARGET NGHttp2::NGHttp2)
+ find_package(PkgConfig)
+ if(PKG_CONFIG_FOUND AND NOT (WIN32 OR WINDOWSSTORE))
+ pkg_check_modules(NGHTTP2 libnghttp2 QUIET)
+
+ # First item is the full path of the library file found
+ # pkg_check_modules does not populate a variable of the found library explicitly
+ list(GET NGHTTP2_LINK_LIBRARIES 0 NGHTTP2_LIBRARY)
+
+ set(NGHTTP2_INCLUDE_DIR ${NGHTTP2_INCLUDEDIR})
+ else()
+
+ find_path(NGHTTP2_INCLUDE_DIR NAMES nghttp2/nghttp2.h
+ HINTS ${DEPENDS_PATH}/include
+ ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
+ find_library(NGHTTP2_LIBRARY NAMES nghttp2 nghttp2_static
+ HINTS ${DEPENDS_PATH}/lib
+ ${${CORE_PLATFORM_LC}_SEARCH_CONFIG})
+ endif()
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(NGHttp2
+ REQUIRED_VARS NGHTTP2_LIBRARY NGHTTP2_INCLUDE_DIR
+ VERSION_VAR NGHTTP2_VERSION)
+
+ if(NGHTTP2_FOUND)
+ add_library(NGHttp2::NGHttp2 UNKNOWN IMPORTED)
+
+ set_target_properties(NGHttp2::NGHttp2 PROPERTIES
+ IMPORTED_LOCATION "${NGHTTP2_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${NGHTTP2_INCLUDE_DIR}")
+
+ # Todo: for windows, do a find_package config call to retrieve this from the cmake config
+ # For now just explicitly say its a static build
+ if(WIN32 OR WINDOWS_STORE)
+ set_property(TARGET NGHttp2::NGHttp2 APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "NGHTTP2_STATICLIB")
+ endif()
+ else()
+ if(NGHttp2_FIND_REQUIRED)
+ message(FATAL_ERROR "NGHttp2 libraries were not found.")
+ endif()
+ endif()
+endif()
diff --git a/cmake/modules/FindSSE.cmake b/cmake/modules/FindSSE.cmake
index d9d5c7af08..f367e2dac8 100644
--- a/cmake/modules/FindSSE.cmake
+++ b/cmake/modules/FindSSE.cmake
@@ -4,74 +4,74 @@ include(TestCXXAcceptsFlag)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(CPU MATCHES "x86_64" OR CPU MATCHES "i.86")
- exec_program(cat ARGS "/proc/cpuinfo" OUTPUT_VARIABLE CPUINFO)
+ execute_process(COMMAND cat /proc/cpuinfo OUTPUT_VARIABLE CPUINFO)
- string(REGEX REPLACE "^.*(sse).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(sse).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "sse" "${_SSE_THERE}" _SSE_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse" _SSE_OK)
- string(REGEX REPLACE "^.*(sse2).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(sse2).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "sse2" "${_SSE_THERE}" _SSE2_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse2" _SSE2_OK)
# SSE3 is also known as the Prescott New Instructions (PNI)
# it's labeled as pni in /proc/cpuinfo
- string(REGEX REPLACE "^.*(pni).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(pni).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "pni" "${_SSE_THERE}" _SSE3_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse3" _SSE3_OK)
- string(REGEX REPLACE "^.*(ssse3).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(ssse3).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "ssse3" "${_SSE_THERE}" _SSSE3_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-mssse3" _SSSE3_OK)
- string(REGEX REPLACE "^.*(sse4_1).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(sse4_1).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "sse4_1" "${_SSE_THERE}" _SSE41_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse4.1" _SSE41_OK)
- string(REGEX REPLACE "^.*(sse4_2).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(sse4_2).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "sse4_2" "${_SSE_THERE}" _SSE42_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse4.2" _SSE42_OK)
- string(REGEX REPLACE "^.*(avx).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(avx).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "avx" "${_SSE_THERE}" _AVX_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-mavx" _AVX_OK)
- string(REGEX REPLACE "^.*(avx2).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(avx2).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "avx2" "${_SSE_THERE}" _AVX2_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-mavx2" _AVX2_OK)
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
if(CPU MATCHES "amd64" OR CPU MATCHES "i.86")
- exec_program(cat ARGS "/var/run/dmesg.boot | grep Features" OUTPUT_VARIABLE CPUINFO)
+ execute_process(COMMAND grep Features /var/run/dmesg.boot OUTPUT_VARIABLE CPUINFO)
- string(REGEX REPLACE "^.*(SSE).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(SSE).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "SSE" "${_SSE_THERE}" _SSE_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse" _SSE_OK)
- string(REGEX REPLACE "^.*(SSE2).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(SSE2).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "SSE2" "${_SSE_THERE}" _SSE2_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse2" _SSE2_OK)
- string(REGEX REPLACE "^.*(SSE3).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(SSE3).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "SSE3" "${_SSE_THERE}" _SSE3_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse3" _SSE3_OK)
- string(REGEX REPLACE "^.*(SSSE3).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(SSSE3).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "SSSE3" "${_SSE_THERE}" _SSSE3_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-mssse3" _SSSE3_OK)
- string(REGEX REPLACE "^.*(SSE4.1).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(SSE4.1).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "SSE4.1" "${_SSE_THERE}" _SSE41_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse4.1" _SSE41_OK)
- string(REGEX REPLACE "^.*(SSE4.2).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(SSE4.2).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "SSE4.2" "${_SSE_THERE}" _SSE42_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-msse4.2" _SSE42_OK)
- string(REGEX REPLACE "^.*(AVX).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(AVX).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "AVX" "${_SSE_THERE}" _AVX_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-mavx" _AVX_OK)
- string(REGEX REPLACE "^.*(AVX2).*$" "\\1" _SSE_THERE ${CPUINFO})
+ string(REGEX REPLACE "^.*(AVX2).*$" "\\1" _SSE_THERE "${CPUINFO}")
string(COMPARE EQUAL "AVX2" "${_SSE_THERE}" _AVX2_TRUE)
CHECK_CXX_ACCEPTS_FLAG("-mavx2" _AVX2_OK)
endif()
@@ -91,42 +91,6 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Android")
CHECK_CXX_ACCEPTS_FLAG("-mavx" _AVX_OK)
CHECK_CXX_ACCEPTS_FLAG("-mavx2" _AVX2_OK)
endif()
-elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
- if(NOT CPU MATCHES "arm")
- exec_program("/usr/sbin/sysctl -n machdep.cpu.features machdep.cpu.leaf7_features" OUTPUT_VARIABLE CPUINFO)
-
- string(REGEX REPLACE "^.*[^S](SSE).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "SSE" "${_SSE_THERE}" _SSE_TRUE)
- CHECK_CXX_ACCEPTS_FLAG("-msse" _SSE_OK)
-
- string(REGEX REPLACE "^.*[^S](SSE2).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "SSE2" "${_SSE_THERE}" _SSE2_TRUE)
- CHECK_CXX_ACCEPTS_FLAG("-msse2" _SSE2_OK)
-
- string(REGEX REPLACE "^.*[^S](SSE3).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "SSE3" "${_SSE_THERE}" _SSE3_TRUE)
- CHECK_CXX_ACCEPTS_FLAG("-msse3" _SSE3_OK)
-
- string(REGEX REPLACE "^.*(SSSE3).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "SSSE3" "${_SSE_THERE}" _SSSE3_TRUE)
- CHECK_CXX_ACCEPTS_FLAG("-mssse3" _SSSE3_OK)
-
- string(REGEX REPLACE "^.*(SSE4.1).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "SSE4.1" "${_SSE_THERE}" _SSE41_TRUE)
- CHECK_CXX_ACCEPTS_FLAG("-msse4.1" _SSE41_OK)
-
- string(REGEX REPLACE "^.*(SSE4.2).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "SSE4.2" "${_SSE_THERE}" _SSE42_TRUE)
- CHECK_CXX_ACCEPTS_FLAG("-msse4.2" _SSE42_OK)
-
- string(REGEX REPLACE "^.*(AVX).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "AVX" "${_SSE_THERE}" _AVX_TRUE)
- CHECK_CXX_ACCEPTS_FLAG("-mavx" _AVX_OK)
-
- string(REGEX REPLACE "^.*(AVX2).*$" "\\1" _SSE_THERE ${CPUINFO})
- string(COMPARE EQUAL "AVX2" "${_SSE_THERE}" _AVX2_TRUE)
- CHECK_CXX_ACCEPTS_FLAG("-mavx2" _AVX2_OK)
- endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "Windows")
# TODO
if(ARCH STREQUAL win32 OR ARCH STREQUAL x64)
diff --git a/cmake/modules/FindTagLib.cmake b/cmake/modules/FindTagLib.cmake
index 78a0eeeccb..1883d3fd9d 100644
--- a/cmake/modules/FindTagLib.cmake
+++ b/cmake/modules/FindTagLib.cmake
@@ -71,7 +71,7 @@ if(NOT TARGET TagLib::TagLib)
# Build Taglib
buildTagLib()
else()
- if(PKG_CONFIG_FOUND)
+ if(PKG_CONFIG_FOUND AND NOT (WIN32 OR WINDOWS_STORE))
if(TagLib_FIND_VERSION)
if(TagLib_FIND_VERSION_EXACT)
set(TagLib_FIND_SPEC "=${TagLib_FIND_VERSION_COMPLETE}")
diff --git a/cmake/modules/buildtools/FindEffectsCompiler.cmake b/cmake/modules/buildtools/FindEffectsCompiler.cmake
new file mode 100644
index 0000000000..49d5b0331f
--- /dev/null
+++ b/cmake/modules/buildtools/FindEffectsCompiler.cmake
@@ -0,0 +1,32 @@
+# FindEffectsCompiler
+# --------
+# Find the DirectX Effects Compiler Tool
+#
+# This will define the following target:
+#
+# windows::FXC - The FXC compiler
+
+if(NOT windows::FXC)
+ find_program(FXC_EXECUTABLE fxc
+ PATHS
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;InstallationFolder]/bin/x86"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;InstallationFolder]/bin/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v10.0;ProductVersion].0/x86"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.1;InstallationFolder]/bin/x86"
+ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v8.0;InstallationFolder]/bin/x86"
+ "$ENV{WindowsSdkDir}bin/x86")
+
+ if(FXC_EXECUTABLE)
+
+ include(FindPackageMessage)
+ find_package_message(EffectsCompiler "Found DX Effects Compiler Tool (FXC): ${FXC_EXECUTABLE}" "[${FXC_EXECUTABLE}]")
+
+ add_executable(windows::FXC IMPORTED)
+ set_target_properties(windows::FXC PROPERTIES
+ IMPORTED_LOCATION "${FXC_EXECUTABLE}"
+ FOLDER "External Projects")
+ else()
+ if(EffectsCompiler_FIND_REQUIRED)
+ message(FATAL_ERROR "Could NOT find DirectX Effects Compiler (FXC)")
+ endif()
+ endif()
+endif()
diff --git a/cmake/platform/windows/windows.cmake b/cmake/platform/windows/windows.cmake
index b3dc4d24e4..0c13ed68e1 100644
--- a/cmake/platform/windows/windows.cmake
+++ b/cmake/platform/windows/windows.cmake
@@ -1,4 +1,5 @@
-set(PLATFORM_REQUIRED_DEPS D3DX11Effects Detours)
+set(PLATFORM_REQUIRED_DEPS Detours Effects11)
+set(PLATFORM_REQUIRED_TOOLS EffectsCompiler)
set(APP_RENDER_SYSTEM dx11)
list(APPEND PLATFORM_DEFINES -DNTDDI_VERSION=NTDDI_WINBLUE -D_WIN32_WINNT=_WIN32_WINNT_WINBLUE)
diff --git a/cmake/platform/windowsstore/windowsstore.cmake b/cmake/platform/windowsstore/windowsstore.cmake
index 6fa4687720..e2c12bb5ac 100644
--- a/cmake/platform/windowsstore/windowsstore.cmake
+++ b/cmake/platform/windowsstore/windowsstore.cmake
@@ -1,4 +1,5 @@
-set(PLATFORM_REQUIRED_DEPS D3DX11Effects)
+set(PLATFORM_REQUIRED_DEPS Effects11)
+set(PLATFORM_REQUIRED_TOOLS EffectsCompiler)
set(PLATFORM_OPTIONAL_DEPS_EXCLUDE CEC)
set(APP_RENDER_SYSTEM dx11)
diff --git a/cmake/scripts/android/ArchSetup.cmake b/cmake/scripts/android/ArchSetup.cmake
index d76ce93a16..73c732c43d 100644
--- a/cmake/scripts/android/ArchSetup.cmake
+++ b/cmake/scripts/android/ArchSetup.cmake
@@ -3,8 +3,7 @@ if(NOT CMAKE_TOOLCHAIN_FILE)
endif()
set(ARCH_DEFINES -DTARGET_POSIX -DTARGET_LINUX -DTARGET_ANDROID)
-set(SYSTEM_DEFINES -D__STDC_CONSTANT_MACROS -D_LARGEFILE64_SOURCE
- -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64=1)
+set(SYSTEM_DEFINES -D__STDC_CONSTANT_MACROS -D_FILE_OFFSET_BITS=64)
# Main cpp
set(CORE_MAIN_SOURCE ${CMAKE_SOURCE_DIR}/xbmc/platform/android/activity/XBMCApp.cpp)
diff --git a/cmake/scripts/android/Install.cmake b/cmake/scripts/android/Install.cmake
index f88957cc9f..b912141007 100644
--- a/cmake/scripts/android/Install.cmake
+++ b/cmake/scripts/android/Install.cmake
@@ -48,6 +48,7 @@ set(package_files strings.xml
src/XBMCProperties.java
src/XBMCVideoView.java
src/XBMCFile.java
+ src/XBMCTextureCache.java
src/XBMCURIUtils.java
src/channels/SyncChannelJobService.java
src/channels/SyncProgramsJobService.java
diff --git a/cmake/scripts/common/Macros.cmake b/cmake/scripts/common/Macros.cmake
index 967010bc54..db9d2e8433 100644
--- a/cmake/scripts/common/Macros.cmake
+++ b/cmake/scripts/common/Macros.cmake
@@ -87,7 +87,6 @@ function(core_add_library name)
if(CORE_SYSTEM_NAME MATCHES windows)
add_precompiled_header(${name} pch.h ${CMAKE_SOURCE_DIR}/xbmc/platform/win32/pch.cpp PCH_TARGET kodi)
set_language_cxx(${name})
- target_link_libraries(${name} PUBLIC effects11)
endif()
else()
foreach(src IN LISTS SOURCES HEADERS OTHERS)
diff --git a/cmake/treedata/common/tests.txt b/cmake/treedata/common/tests.txt
index 1a55b5c6ec..8d8d1107f2 100644
--- a/cmake/treedata/common/tests.txt
+++ b/cmake/treedata/common/tests.txt
@@ -8,6 +8,7 @@ xbmc/games/addons/input/test test/games/addons/input
xbmc/games/controllers/input/test test/games/controllers/input
xbmc/input/keyboard/test test/input/keyboard
xbmc/interfaces/python/test test/python
+xbmc/music/test test/music
xbmc/music/tags/test test/music_tags
xbmc/network/test test/network
xbmc/playlists/test test/playlists
diff --git a/cmake/treedata/windows/externals.txt b/cmake/treedata/windows/externals.txt
deleted file mode 100644
index 989677e6c9..0000000000
--- a/cmake/treedata/windows/externals.txt
+++ /dev/null
@@ -1 +0,0 @@
-lib/win32/Effects11 Effects11
diff --git a/cmake/treedata/windowsstore/externals.txt b/cmake/treedata/windowsstore/externals.txt
deleted file mode 100644
index 989677e6c9..0000000000
--- a/cmake/treedata/windowsstore/externals.txt
+++ /dev/null
@@ -1 +0,0 @@
-lib/win32/Effects11 Effects11
diff --git a/lib/win32/Effects11/Binary/EffectBinaryFormat.h b/lib/win32/Effects11/Binary/EffectBinaryFormat.h
deleted file mode 100644
index 55ccf60d00..0000000000
--- a/lib/win32/Effects11/Binary/EffectBinaryFormat.h
+++ /dev/null
@@ -1,676 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectBinaryFormat.h
-//
-// Direct3D11 Effects Binary Format
-// This is the binary file interface shared between the Effects
-// compiler and runtime.
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-namespace D3DX11Effects
-{
-
-//////////////////////////////////////////////////////////////////////////
-// Version Control
-//////////////////////////////////////////////////////////////////////////
-
-#define D3DX11_FXL_VERSION(_Major,_Minor) (('F' << 24) | ('X' << 16) | ((_Major) << 8) | (_Minor))
-
-struct EVersionTag
-{
- const char* m_pName;
- DWORD m_Version;
- uint32_t m_Tag;
-};
-
-// versions must be listed in ascending order
-static const EVersionTag g_EffectVersions[] =
-{
- { "fx_4_0", D3DX11_FXL_VERSION(4,0), 0xFEFF1001 },
- { "fx_4_1", D3DX11_FXL_VERSION(4,1), 0xFEFF1011 },
- { "fx_5_0", D3DX11_FXL_VERSION(5,0), 0xFEFF2001 },
-};
-
-
-//////////////////////////////////////////////////////////////////////////
-// Reflection & Type structures
-//////////////////////////////////////////////////////////////////////////
-
-// Enumeration of the possible left-hand side values of an assignment,
-// divided up categorically by the type of block they may appear in
-enum ELhsType : int
-{
- ELHS_Invalid,
-
- // Pass block assignment types
-
- ELHS_PixelShaderBlock, // SBlock *pValue points to the block to apply
- ELHS_VertexShaderBlock,
- ELHS_GeometryShaderBlock,
- ELHS_RenderTargetView,
- ELHS_DepthStencilView,
-
- ELHS_RasterizerBlock,
- ELHS_DepthStencilBlock,
- ELHS_BlendBlock,
-
- ELHS_GenerateMips, // This is really a call to D3D::GenerateMips
-
- // Various SAssignment.Value.*
-
- ELHS_DS_StencilRef, // SAssignment.Value.pdValue
- ELHS_B_BlendFactor, // D3D11_BLEND_CONFIG.BlendFactor, points to a float4
- ELHS_B_SampleMask, // D3D11_BLEND_CONFIG.SampleMask
-
- ELHS_GeometryShaderSO, // When setting SO assignments, GeometryShaderSO precedes the actual GeometryShader assn
-
- ELHS_ComputeShaderBlock,
- ELHS_HullShaderBlock,
- ELHS_DomainShaderBlock,
-
- // Rasterizer
-
- ELHS_FillMode = 0x20000,
- ELHS_CullMode,
- ELHS_FrontCC,
- ELHS_DepthBias,
- ELHS_DepthBiasClamp,
- ELHS_SlopeScaledDepthBias,
- ELHS_DepthClipEnable,
- ELHS_ScissorEnable,
- ELHS_MultisampleEnable,
- ELHS_AntialiasedLineEnable,
-
- // Sampler
-
- ELHS_Filter = 0x30000,
- ELHS_AddressU,
- ELHS_AddressV,
- ELHS_AddressW,
- ELHS_MipLODBias,
- ELHS_MaxAnisotropy,
- ELHS_ComparisonFunc,
- ELHS_BorderColor,
- ELHS_MinLOD,
- ELHS_MaxLOD,
- ELHS_Texture,
-
- // DepthStencil
-
- ELHS_DepthEnable = 0x40000,
- ELHS_DepthWriteMask,
- ELHS_DepthFunc,
- ELHS_StencilEnable,
- ELHS_StencilReadMask,
- ELHS_StencilWriteMask,
- ELHS_FrontFaceStencilFailOp,
- ELHS_FrontFaceStencilDepthFailOp,
- ELHS_FrontFaceStencilPassOp,
- ELHS_FrontFaceStencilFunc,
- ELHS_BackFaceStencilFailOp,
- ELHS_BackFaceStencilDepthFailOp,
- ELHS_BackFaceStencilPassOp,
- ELHS_BackFaceStencilFunc,
-
- // BlendState
-
- ELHS_AlphaToCoverage = 0x50000,
- ELHS_BlendEnable,
- ELHS_SrcBlend,
- ELHS_DestBlend,
- ELHS_BlendOp,
- ELHS_SrcBlendAlpha,
- ELHS_DestBlendAlpha,
- ELHS_BlendOpAlpha,
- ELHS_RenderTargetWriteMask,
-};
-
-enum EBlockType
-{
- EBT_Invalid,
- EBT_DepthStencil,
- EBT_Blend,
- EBT_Rasterizer,
- EBT_Sampler,
- EBT_Pass
-};
-
-enum EVarType
-{
- EVT_Invalid,
- EVT_Numeric,
- EVT_Object,
- EVT_Struct,
- EVT_Interface,
- EVT_Count,
-};
-
-enum EScalarType
-{
- EST_Invalid,
- EST_Float,
- EST_Int,
- EST_UInt,
- EST_Bool,
- EST_Count
-};
-
-enum ENumericLayout
-{
- ENL_Invalid,
- ENL_Scalar,
- ENL_Vector,
- ENL_Matrix,
- ENL_Count
-};
-
-enum EObjectType
-{
- EOT_Invalid,
- EOT_String,
- EOT_Blend,
- EOT_DepthStencil,
- EOT_Rasterizer,
- EOT_PixelShader,
- EOT_VertexShader,
- EOT_GeometryShader, // Regular geometry shader
- EOT_GeometryShaderSO, // Geometry shader with a attached StreamOut decl
- EOT_Texture,
- EOT_Texture1D,
- EOT_Texture1DArray,
- EOT_Texture2D,
- EOT_Texture2DArray,
- EOT_Texture2DMS,
- EOT_Texture2DMSArray,
- EOT_Texture3D,
- EOT_TextureCube,
- EOT_ConstantBuffer,
- EOT_RenderTargetView,
- EOT_DepthStencilView,
- EOT_Sampler,
- EOT_Buffer,
- EOT_TextureCubeArray,
- EOT_Count,
- EOT_PixelShader5,
- EOT_VertexShader5,
- EOT_GeometryShader5,
- EOT_ComputeShader5,
- EOT_HullShader5,
- EOT_DomainShader5,
- EOT_RWTexture1D,
- EOT_RWTexture1DArray,
- EOT_RWTexture2D,
- EOT_RWTexture2DArray,
- EOT_RWTexture3D,
- EOT_RWBuffer,
- EOT_ByteAddressBuffer,
- EOT_RWByteAddressBuffer,
- EOT_StructuredBuffer,
- EOT_RWStructuredBuffer,
- EOT_RWStructuredBufferAlloc,
- EOT_RWStructuredBufferConsume,
- EOT_AppendStructuredBuffer,
- EOT_ConsumeStructuredBuffer,
-};
-
-inline bool IsObjectTypeHelper(EVarType InVarType,
- EObjectType InObjType,
- EObjectType TargetObjType)
-{
- return (InVarType == EVT_Object) && (InObjType == TargetObjType);
-}
-
-inline bool IsSamplerHelper(EVarType InVarType,
- EObjectType InObjType)
-{
- return (InVarType == EVT_Object) && (InObjType == EOT_Sampler);
-}
-
-inline bool IsStateBlockObjectHelper(EVarType InVarType,
- EObjectType InObjType)
-{
- return (InVarType == EVT_Object) && ((InObjType == EOT_Blend) || (InObjType == EOT_DepthStencil) || (InObjType == EOT_Rasterizer) || IsSamplerHelper(InVarType, InObjType));
-}
-
-inline bool IsShaderHelper(EVarType InVarType,
- EObjectType InObjType)
-{
- return (InVarType == EVT_Object) && ((InObjType == EOT_VertexShader) ||
- (InObjType == EOT_VertexShader5) ||
- (InObjType == EOT_HullShader5) ||
- (InObjType == EOT_DomainShader5) ||
- (InObjType == EOT_ComputeShader5) ||
- (InObjType == EOT_GeometryShader) ||
- (InObjType == EOT_GeometryShaderSO) ||
- (InObjType == EOT_GeometryShader5) ||
- (InObjType == EOT_PixelShader) ||
- (InObjType == EOT_PixelShader5));
-}
-
-inline bool IsShader5Helper(EVarType InVarType,
- EObjectType InObjType)
-{
- return (InVarType == EVT_Object) && ((InObjType == EOT_VertexShader5) ||
- (InObjType == EOT_HullShader5) ||
- (InObjType == EOT_DomainShader5) ||
- (InObjType == EOT_ComputeShader5) ||
- (InObjType == EOT_GeometryShader5) ||
- (InObjType == EOT_PixelShader5));
-}
-
-inline bool IsInterfaceHelper(EVarType InVarType, EObjectType InObjType)
-{
- UNREFERENCED_PARAMETER(InObjType);
- return (InVarType == EVT_Interface);
-}
-
-inline bool IsShaderResourceHelper(EVarType InVarType,
- EObjectType InObjType)
-{
- return (InVarType == EVT_Object) && ((InObjType == EOT_Texture) ||
- (InObjType == EOT_Texture1D) ||
- (InObjType == EOT_Texture1DArray) ||
- (InObjType == EOT_Texture2D) ||
- (InObjType == EOT_Texture2DArray) ||
- (InObjType == EOT_Texture2DMS) ||
- (InObjType == EOT_Texture2DMSArray) ||
- (InObjType == EOT_Texture3D) ||
- (InObjType == EOT_TextureCube) ||
- (InObjType == EOT_TextureCubeArray) ||
- (InObjType == EOT_Buffer) ||
- (InObjType == EOT_StructuredBuffer) ||
- (InObjType == EOT_ByteAddressBuffer));
-}
-
-inline bool IsUnorderedAccessViewHelper(EVarType InVarType,
- EObjectType InObjType)
-{
- return (InVarType == EVT_Object) &&
- ((InObjType == EOT_RWTexture1D) ||
- (InObjType == EOT_RWTexture1DArray) ||
- (InObjType == EOT_RWTexture2D) ||
- (InObjType == EOT_RWTexture2DArray) ||
- (InObjType == EOT_RWTexture3D) ||
- (InObjType == EOT_RWBuffer) ||
- (InObjType == EOT_RWByteAddressBuffer) ||
- (InObjType == EOT_RWStructuredBuffer) ||
- (InObjType == EOT_RWStructuredBufferAlloc) ||
- (InObjType == EOT_RWStructuredBufferConsume) ||
- (InObjType == EOT_AppendStructuredBuffer) ||
- (InObjType == EOT_ConsumeStructuredBuffer));
-}
-
-inline bool IsRenderTargetViewHelper(EVarType InVarType,
- EObjectType InObjType)
-{
- return (InVarType == EVT_Object) && (InObjType == EOT_RenderTargetView);
-}
-
-inline bool IsDepthStencilViewHelper(EVarType InVarType,
- EObjectType InObjType)
-{
- return (InVarType == EVT_Object) && (InObjType == EOT_DepthStencilView);
-}
-
-inline bool IsObjectAssignmentHelper(ELhsType LhsType)
-{
- switch(LhsType)
- {
- case ELHS_VertexShaderBlock:
- case ELHS_HullShaderBlock:
- case ELHS_DepthStencilView:
- case ELHS_GeometryShaderBlock:
- case ELHS_PixelShaderBlock:
- case ELHS_ComputeShaderBlock:
- case ELHS_DepthStencilBlock:
- case ELHS_RasterizerBlock:
- case ELHS_BlendBlock:
- case ELHS_Texture:
- case ELHS_RenderTargetView:
- case ELHS_DomainShaderBlock:
- return true;
- }
- return false;
-}
-
-
-
-
-// Effect file format structures /////////////////////////////////////////////
-// File format:
-// File header (SBinaryHeader Header)
-// Unstructured data block (uint8_t[Header.cbUnstructured))
-// Structured data block
-// ConstantBuffer (SBinaryConstantBuffer CB) * Header.Effect.cCBs
-// uint32_t NumAnnotations
-// Annotation data (SBinaryAnnotation) * (NumAnnotations) *this structure is variable sized
-// Variable data (SBinaryNumericVariable Var) * (CB.cVariables)
-// uint32_t NumAnnotations
-// Annotation data (SBinaryAnnotation) * (NumAnnotations) *this structure is variable sized
-// Object variables (SBinaryObjectVariable Var) * (Header.cObjectVariables) *this structure is variable sized
-// uint32_t NumAnnotations
-// Annotation data (SBinaryAnnotation) * (NumAnnotations) *this structure is variable sized
-// Interface variables (SBinaryInterfaceVariable Var) * (Header.cInterfaceVariables) *this structure is variable sized
-// uint32_t NumAnnotations
-// Annotation data (SBinaryAnnotation) * (NumAnnotations) *this structure is variable sized
-// Groups (SBinaryGroup Group) * Header.cGroups
-// uint32_t NumAnnotations
-// Annotation data (SBinaryAnnotation) * (NumAnnotations) *this structure is variable sized
-// Techniques (SBinaryTechnique Technique) * Group.cTechniques
-// uint32_t NumAnnotations
-// Annotation data (SBinaryAnnotation) * (NumAnnotations) *this structure is variable sized
-// Pass (SBinaryPass Pass) * Technique.cPasses
-// uint32_t NumAnnotations
-// Annotation data (SBinaryAnnotation) * (NumAnnotations) *this structure is variable sized
-// Pass assignments (SBinaryAssignment) * Pass.cAssignments
-
-struct SBinaryHeader
-{
- struct SVarCounts
- {
- uint32_t cCBs;
- uint32_t cNumericVariables;
- uint32_t cObjectVariables;
- };
-
- uint32_t Tag; // should be equal to c_EffectFileTag
- // this is used to identify ASCII vs Binary files
-
- SVarCounts Effect;
- SVarCounts Pool;
-
- uint32_t cTechniques;
- uint32_t cbUnstructured;
-
- uint32_t cStrings;
- uint32_t cShaderResources;
-
- uint32_t cDepthStencilBlocks;
- uint32_t cBlendStateBlocks;
- uint32_t cRasterizerStateBlocks;
- uint32_t cSamplers;
- uint32_t cRenderTargetViews;
- uint32_t cDepthStencilViews;
-
- uint32_t cTotalShaders;
- uint32_t cInlineShaders; // of the aforementioned shaders, the number that are defined inline within pass blocks
-
- inline bool RequiresPool() const
- {
- return (Pool.cCBs != 0) ||
- (Pool.cNumericVariables != 0) ||
- (Pool.cObjectVariables != 0);
- }
-};
-
-struct SBinaryHeader5 : public SBinaryHeader
-{
- uint32_t cGroups;
- uint32_t cUnorderedAccessViews;
- uint32_t cInterfaceVariables;
- uint32_t cInterfaceVariableElements;
- uint32_t cClassInstanceElements;
-};
-
-// Constant buffer definition
-struct SBinaryConstantBuffer
-{
- // private flags
- static const uint32_t c_IsTBuffer = (1 << 0);
- static const uint32_t c_IsSingle = (1 << 1);
-
- uint32_t oName; // Offset to constant buffer name
- uint32_t Size; // Size, in bytes
- uint32_t Flags;
- uint32_t cVariables; // # of variables inside this buffer
- uint32_t ExplicitBindPoint; // Defined if the effect file specifies a bind point using the register keyword
- // otherwise, -1
-};
-
-struct SBinaryAnnotation
-{
- uint32_t oName; // Offset to variable name
- uint32_t oType; // Offset to type information (SBinaryType)
-
- // For numeric annotations:
- // uint32_t oDefaultValue; // Offset to default initializer value
- //
- // For string annotations:
- // uint32_t oStringOffsets[Elements]; // Elements comes from the type data at oType
-};
-
-struct SBinaryNumericVariable
-{
- uint32_t oName; // Offset to variable name
- uint32_t oType; // Offset to type information (SBinaryType)
- uint32_t oSemantic; // Offset to semantic information
- uint32_t Offset; // Offset in parent constant buffer
- uint32_t oDefaultValue; // Offset to default initializer value
- uint32_t Flags; // Explicit bind point
-};
-
-struct SBinaryInterfaceVariable
-{
- uint32_t oName; // Offset to variable name
- uint32_t oType; // Offset to type information (SBinaryType)
- uint32_t oDefaultValue; // Offset to default initializer array (SBinaryInterfaceInitializer[Elements])
- uint32_t Flags;
-};
-
-struct SBinaryInterfaceInitializer
-{
- uint32_t oInstanceName;
- uint32_t ArrayIndex;
-};
-
-struct SBinaryObjectVariable
-{
- uint32_t oName; // Offset to variable name
- uint32_t oType; // Offset to type information (SBinaryType)
- uint32_t oSemantic; // Offset to semantic information
- uint32_t ExplicitBindPoint; // Used when a variable has been explicitly bound (register(XX)). -1 if not
-
- // Initializer data:
- //
- // The type structure pointed to by oType gives you Elements,
- // VarType (must be EVT_Object), and ObjectType
- //
- // For ObjectType == EOT_Blend, EOT_DepthStencil, EOT_Rasterizer, EOT_Sampler
- // struct
- // {
- // uint32_t cAssignments;
- // SBinaryAssignment Assignments[cAssignments];
- // } Blocks[Elements]
- //
- // For EObjectType == EOT_Texture*, EOT_Buffer
- // <nothing>
- //
- // For EObjectType == EOT_*Shader, EOT_String
- // uint32_t oData[Elements]; // offsets to a shader data block or a nullptr-terminated string
- //
- // For EObjectType == EOT_GeometryShaderSO
- // SBinaryGSSOInitializer[Elements]
- //
- // For EObjectType == EOT_*Shader5
- // SBinaryShaderData5[Elements]
-};
-
-struct SBinaryGSSOInitializer
-{
- uint32_t oShader; // Offset to shader bytecode data block
- uint32_t oSODecl; // Offset to StreamOutput decl string
-};
-
-struct SBinaryShaderData5
-{
- uint32_t oShader; // Offset to shader bytecode data block
- uint32_t oSODecls[4]; // Offset to StreamOutput decl strings
- uint32_t cSODecls; // Count of valid oSODecls entries.
- uint32_t RasterizedStream; // Which stream is used for rasterization
- uint32_t cInterfaceBindings; // Count of interface bindings.
- uint32_t oInterfaceBindings; // Offset to SBinaryInterfaceInitializer[cInterfaceBindings].
-};
-
-struct SBinaryType
-{
- uint32_t oTypeName; // Offset to friendly type name ("float4", "VS_OUTPUT")
- EVarType VarType; // Numeric, Object, or Struct
- uint32_t Elements; // # of array elements (0 for non-arrays)
- uint32_t TotalSize; // Size in bytes; not necessarily Stride * Elements for arrays
- // because of possible gap left in final register
- uint32_t Stride; // If an array, this is the spacing between elements.
- // For unpacked arrays, always divisible by 16-bytes (1 register).
- // No support for packed arrays
- uint32_t PackedSize; // Size, in bytes, of this data typed when fully packed
-
- struct SBinaryMember
- {
- uint32_t oName; // Offset to structure member name ("m_pFoo")
- uint32_t oSemantic; // Offset to semantic ("POSITION0")
- uint32_t Offset; // Offset, in bytes, relative to start of parent structure
- uint32_t oType; // Offset to member's type descriptor
- };
-
- // the data that follows depends on the VarType:
- // Numeric: SType::SNumericType
- // Object: EObjectType
- // Struct:
- // struct
- // {
- // uint32_t cMembers;
- // SBinaryMembers Members[cMembers];
- // } MemberInfo
- // struct
- // {
- // uint32_t oBaseClassType; // Offset to type information (SBinaryType)
- // uint32_t cInterfaces;
- // uint32_t oInterfaceTypes[cInterfaces];
- // } SBinaryTypeInheritance
- // Interface: (nothing)
-};
-
-struct SBinaryNumericType
-{
- ENumericLayout NumericLayout : 3; // scalar (1x1), vector (1xN), matrix (NxN)
- EScalarType ScalarType : 5; // float32, int32, int8, etc.
- uint32_t Rows : 3; // 1 <= Rows <= 4
- uint32_t Columns : 3; // 1 <= Columns <= 4
- uint32_t IsColumnMajor : 1; // applies only to matrices
- uint32_t IsPackedArray : 1; // if this is an array, indicates whether elements should be greedily packed
-};
-
-struct SBinaryTypeInheritance
-{
- uint32_t oBaseClass; // Offset to base class type info or 0 if no base class.
- uint32_t cInterfaces;
-
- // Followed by uint32_t[cInterfaces] with offsets to the type
- // info of each interface.
-};
-
-struct SBinaryGroup
-{
- uint32_t oName;
- uint32_t cTechniques;
-};
-
-struct SBinaryTechnique
-{
- uint32_t oName;
- uint32_t cPasses;
-};
-
-struct SBinaryPass
-{
- uint32_t oName;
- uint32_t cAssignments;
-};
-
-enum ECompilerAssignmentType
-{
- ECAT_Invalid, // Assignment-specific data (always in the unstructured blob)
- ECAT_Constant, // -N SConstant structures
- ECAT_Variable, // -nullptr terminated string with variable name ("foo")
- ECAT_ConstIndex, // -SConstantIndex structure
- ECAT_VariableIndex, // -SVariableIndex structure
- ECAT_ExpressionIndex, // -SIndexedObjectExpression structure
- ECAT_Expression, // -Data block containing FXLVM code
- ECAT_InlineShader, // -Data block containing shader
- ECAT_InlineShader5, // -Data block containing shader with extended 5.0 data (SBinaryShaderData5)
-};
-
-struct SBinaryAssignment
-{
- uint32_t iState; // index into g_lvGeneral
- uint32_t Index; // the particular index to assign to (see g_lvGeneral to find the # of valid indices)
- ECompilerAssignmentType AssignmentType;
- uint32_t oInitializer; // Offset of assignment-specific data
-
- struct SConstantIndex
- {
- uint32_t oArrayName;
- uint32_t Index;
- };
-
- struct SVariableIndex
- {
- uint32_t oArrayName;
- uint32_t oIndexVarName;
- };
-
- struct SIndexedObjectExpression
- {
- uint32_t oArrayName;
- uint32_t oCode;
- };
-
- struct SInlineShader
- {
- uint32_t oShader;
- uint32_t oSODecl;
- };
-};
-
-struct SBinaryConstant
-{
- EScalarType Type;
- union
- {
- BOOL bValue;
- INT iValue;
- float fValue;
- };
-};
-
-static_assert( sizeof(SBinaryHeader) == 76, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryHeader::SVarCounts) == 12, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryHeader5) == 96, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryConstantBuffer) == 20, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryAnnotation) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryNumericVariable) == 24, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryInterfaceVariable) == 16, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryInterfaceInitializer) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryObjectVariable) == 16, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryGSSOInitializer) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryShaderData5) == 36, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryType) == 24, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryType::SBinaryMember) == 16, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryNumericType) == 4, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryTypeInheritance) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryGroup) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryTechnique) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryPass) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryAssignment) == 16, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryAssignment::SConstantIndex) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryAssignment::SVariableIndex) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryAssignment::SIndexedObjectExpression) == 8, "FX11 binary size mismatch" );
-static_assert( sizeof(SBinaryAssignment::SInlineShader) == 8, "FX11 binary size mismatch" );
-
-} // end namespace D3DX11Effects
-
diff --git a/lib/win32/Effects11/Binary/EffectStateBase11.h b/lib/win32/Effects11/Binary/EffectStateBase11.h
deleted file mode 100644
index fcd117a50b..0000000000
--- a/lib/win32/Effects11/Binary/EffectStateBase11.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectStateBase11.h
-//
-// Direct3D 11 Effects States Header
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-namespace D3DX11Effects
-{
-
-//////////////////////////////////////////////////////////////////////////
-// Effect HLSL states and late resolve lists
-//////////////////////////////////////////////////////////////////////////
-
-struct RValue
-{
- const char *m_pName;
- uint32_t m_Value;
-};
-
-#define RVALUE_END() { nullptr, 0U }
-#define RVALUE_ENTRY(prefix, x) { #x, (uint32_t)prefix##x }
-
-enum ELhsType : int;
-
-struct LValue
-{
- const char *m_pName; // name of the LHS side of expression
- EBlockType m_BlockType; // type of block it can appear in
- D3D_SHADER_VARIABLE_TYPE m_Type; // data type allows
- uint32_t m_Cols; // number of [m_Type]'s required (1 for a scalar, 4 for a vector)
- uint32_t m_Indices; // max index allowable (if LHS is an array; otherwise this is 1)
- bool m_VectorScalar; // can be both vector and scalar (setting as a scalar sets all m_Indices values simultaneously)
- const RValue *m_pRValue; // pointer to table of allowable RHS "late resolve" values
- ELhsType m_LhsType; // ELHS_* enum value that corresponds to this entry
- uint32_t m_Offset; // offset into the given block type where this value should be written
- uint32_t m_Stride; // for vectors, byte stride between two consecutive values. if 0, m_Type's size is used
-};
-
-#define LVALUE_END() { nullptr, D3D_SVT_UINT, 0, 0, 0, nullptr }
-
-extern const LValue g_lvGeneral[];
-extern const uint32_t g_lvGeneralCount;
-
-} // end namespace D3DX11Effects
diff --git a/lib/win32/Effects11/Binary/EffectStates11.h b/lib/win32/Effects11/Binary/EffectStates11.h
deleted file mode 100644
index a5fd1e7612..0000000000
--- a/lib/win32/Effects11/Binary/EffectStates11.h
+++ /dev/null
@@ -1,237 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectStates11.h
-//
-// Direct3D 11 Effects States Header
-// This file defines properties of states which can appear in
-// state blocks and pass blocks.
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-#include "EffectStateBase11.h"
-
-namespace D3DX11Effects
-{
-
-//////////////////////////////////////////////////////////////////////////
-// Effect HLSL late resolve lists (state values)
-//////////////////////////////////////////////////////////////////////////
-
-static const RValue g_rvNULL[] =
-{
- { "nullptr", 0 },
- RVALUE_END()
-};
-
-
-static const RValue g_rvBOOL[] =
-{
- { "false", 0 },
- { "true", 1 },
- RVALUE_END()
-};
-
-static const RValue g_rvDEPTH_WRITE_MASK[] =
-{
- { "ZERO", D3D11_DEPTH_WRITE_MASK_ZERO },
- { "ALL", D3D11_DEPTH_WRITE_MASK_ALL },
- RVALUE_END()
-};
-
-static const RValue g_rvFILL[] =
-{
- { "WIREFRAME", D3D11_FILL_WIREFRAME },
- { "SOLID", D3D11_FILL_SOLID },
- RVALUE_END()
-};
-
-static const RValue g_rvFILTER[] =
-{
- RVALUE_ENTRY(D3D11_FILTER_, MIN_MAG_MIP_POINT ),
- RVALUE_ENTRY(D3D11_FILTER_, MIN_MAG_POINT_MIP_LINEAR ),
- RVALUE_ENTRY(D3D11_FILTER_, MIN_POINT_MAG_LINEAR_MIP_POINT ),
- RVALUE_ENTRY(D3D11_FILTER_, MIN_POINT_MAG_MIP_LINEAR ),
- RVALUE_ENTRY(D3D11_FILTER_, MIN_LINEAR_MAG_MIP_POINT ),
- RVALUE_ENTRY(D3D11_FILTER_, MIN_LINEAR_MAG_POINT_MIP_LINEAR ),
- RVALUE_ENTRY(D3D11_FILTER_, MIN_MAG_LINEAR_MIP_POINT ),
- RVALUE_ENTRY(D3D11_FILTER_, MIN_MAG_MIP_LINEAR ),
- RVALUE_ENTRY(D3D11_FILTER_, ANISOTROPIC ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_MIN_MAG_MIP_POINT ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_MIN_MAG_POINT_MIP_LINEAR ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_MIN_POINT_MAG_MIP_LINEAR ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_MIN_LINEAR_MAG_MIP_POINT ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_MIN_MAG_LINEAR_MIP_POINT ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_MIN_MAG_MIP_LINEAR ),
- RVALUE_ENTRY(D3D11_FILTER_, COMPARISON_ANISOTROPIC ),
- RVALUE_END()
-};
-
-static const RValue g_rvBLEND[] =
-{
- { "ZERO", D3D11_BLEND_ZERO },
- { "ONE", D3D11_BLEND_ONE },
- { "SRC_COLOR", D3D11_BLEND_SRC_COLOR },
- { "INV_SRC_COLOR", D3D11_BLEND_INV_SRC_COLOR },
- { "SRC_ALPHA", D3D11_BLEND_SRC_ALPHA },
- { "INV_SRC_ALPHA", D3D11_BLEND_INV_SRC_ALPHA },
- { "DEST_ALPHA", D3D11_BLEND_DEST_ALPHA },
- { "INV_DEST_ALPHA", D3D11_BLEND_INV_DEST_ALPHA },
- { "DEST_COLOR", D3D11_BLEND_DEST_COLOR },
- { "INV_DEST_COLOR", D3D11_BLEND_INV_DEST_COLOR },
- { "SRC_ALPHA_SAT", D3D11_BLEND_SRC_ALPHA_SAT },
- { "BLEND_FACTOR", D3D11_BLEND_BLEND_FACTOR },
- { "INV_BLEND_FACTOR", D3D11_BLEND_INV_BLEND_FACTOR },
- { "SRC1_COLOR", D3D11_BLEND_SRC1_COLOR },
- { "INV_SRC1_COLOR", D3D11_BLEND_INV_SRC1_COLOR },
- { "SRC1_ALPHA", D3D11_BLEND_SRC1_ALPHA },
- { "INV_SRC1_ALPHA", D3D11_BLEND_INV_SRC1_ALPHA },
-
- RVALUE_END()
-};
-
-static const RValue g_rvTADDRESS[] =
-{
- { "CLAMP", D3D11_TEXTURE_ADDRESS_CLAMP },
- { "WRAP", D3D11_TEXTURE_ADDRESS_WRAP },
- { "MIRROR", D3D11_TEXTURE_ADDRESS_MIRROR },
- { "BORDER", D3D11_TEXTURE_ADDRESS_BORDER },
- { "MIRROR_ONCE", D3D11_TEXTURE_ADDRESS_MIRROR_ONCE },
- RVALUE_END()
-};
-
-static const RValue g_rvCULL[] =
-{
- { "NONE", D3D11_CULL_NONE },
- { "FRONT", D3D11_CULL_FRONT },
- { "BACK", D3D11_CULL_BACK },
- RVALUE_END()
-};
-
-static const RValue g_rvCMP[] =
-{
- { "NEVER", D3D11_COMPARISON_NEVER },
- { "LESS", D3D11_COMPARISON_LESS },
- { "EQUAL", D3D11_COMPARISON_EQUAL },
- { "LESS_EQUAL", D3D11_COMPARISON_LESS_EQUAL },
- { "GREATER", D3D11_COMPARISON_GREATER },
- { "NOT_EQUAL", D3D11_COMPARISON_NOT_EQUAL },
- { "GREATER_EQUAL", D3D11_COMPARISON_GREATER_EQUAL },
- { "ALWAYS", D3D11_COMPARISON_ALWAYS },
- RVALUE_END()
-};
-
-static const RValue g_rvSTENCILOP[] =
-{
- { "KEEP", D3D11_STENCIL_OP_KEEP },
- { "ZERO", D3D11_STENCIL_OP_ZERO },
- { "REPLACE", D3D11_STENCIL_OP_REPLACE },
- { "INCR_SAT", D3D11_STENCIL_OP_INCR_SAT },
- { "DECR_SAT", D3D11_STENCIL_OP_DECR_SAT },
- { "INVERT", D3D11_STENCIL_OP_INVERT },
- { "INCR", D3D11_STENCIL_OP_INCR },
- { "DECR", D3D11_STENCIL_OP_DECR },
- RVALUE_END()
-};
-
-static const RValue g_rvBLENDOP[] =
-{
- { "ADD", D3D11_BLEND_OP_ADD },
- { "SUBTRACT", D3D11_BLEND_OP_SUBTRACT },
- { "REV_SUBTRACT", D3D11_BLEND_OP_REV_SUBTRACT },
- { "MIN", D3D11_BLEND_OP_MIN },
- { "MAX", D3D11_BLEND_OP_MAX },
- RVALUE_END()
-};
-
-
-//////////////////////////////////////////////////////////////////////////
-// Effect HLSL states
-//////////////////////////////////////////////////////////////////////////
-
-#define strideof( s, m ) offsetof_fx(s,m[1]) - offsetof_fx(s,m[0])
-
-const LValue g_lvGeneral[] =
-{
- // RObjects
- { "RasterizerState", EBT_Pass, D3D_SVT_RASTERIZER, 1, 1, false, nullptr, ELHS_RasterizerBlock, offsetof_fx(SPassBlock, BackingStore.pRasterizerBlock), 0 },
- { "DepthStencilState", EBT_Pass, D3D_SVT_DEPTHSTENCIL, 1, 1, false, nullptr, ELHS_DepthStencilBlock, offsetof_fx(SPassBlock, BackingStore.pDepthStencilBlock), 0 },
- { "BlendState", EBT_Pass, D3D_SVT_BLEND, 1, 1, false, nullptr, ELHS_BlendBlock, offsetof_fx(SPassBlock, BackingStore.pBlendBlock), 0 },
- { "RenderTargetView", EBT_Pass, D3D_SVT_RENDERTARGETVIEW, 1, 8, false, nullptr, ELHS_RenderTargetView, offsetof_fx(SPassBlock, BackingStore.pRenderTargetViews), 0 },
- { "DepthStencilView", EBT_Pass, D3D_SVT_DEPTHSTENCILVIEW, 1, 8, false, nullptr, ELHS_DepthStencilView, offsetof_fx(SPassBlock, BackingStore.pDepthStencilView), 0 },
- { "GenerateMips", EBT_Pass, D3D_SVT_TEXTURE, 1, 1, false, nullptr, ELHS_GenerateMips, 0, 0 },
- // Shaders
- { "VertexShader", EBT_Pass, D3D_SVT_VERTEXSHADER, 1, 1, false, g_rvNULL, ELHS_VertexShaderBlock, offsetof_fx(SPassBlock, BackingStore.pVertexShaderBlock), 0 },
- { "PixelShader", EBT_Pass, D3D_SVT_PIXELSHADER, 1, 1, false, g_rvNULL, ELHS_PixelShaderBlock, offsetof_fx(SPassBlock, BackingStore.pPixelShaderBlock), 0 },
- { "GeometryShader", EBT_Pass, D3D_SVT_GEOMETRYSHADER, 1, 1, false, g_rvNULL, ELHS_GeometryShaderBlock, offsetof_fx(SPassBlock, BackingStore.pGeometryShaderBlock), 0 },
- // RObject config assignments
- { "DS_StencilRef", EBT_Pass, D3D_SVT_UINT, 1, 1, false, nullptr, ELHS_DS_StencilRef, offsetof_fx(SPassBlock, BackingStore.StencilRef), 0 },
- { "AB_BlendFactor", EBT_Pass, D3D_SVT_FLOAT, 4, 1, false, nullptr, ELHS_B_BlendFactor, offsetof_fx(SPassBlock, BackingStore.BlendFactor), 0 },
- { "AB_SampleMask", EBT_Pass, D3D_SVT_UINT, 1, 1, false, nullptr, ELHS_B_SampleMask, offsetof_fx(SPassBlock, BackingStore.SampleMask), 0 },
-
- { "FillMode", EBT_Rasterizer, D3D_SVT_UINT, 1, 1, false, g_rvFILL, ELHS_FillMode, offsetof_fx(SRasterizerBlock, BackingStore.FillMode), 0 },
- { "CullMode", EBT_Rasterizer, D3D_SVT_UINT, 1, 1, false, g_rvCULL, ELHS_CullMode, offsetof_fx(SRasterizerBlock, BackingStore.CullMode), 0 },
- { "FrontCounterClockwise", EBT_Rasterizer, D3D_SVT_BOOL, 1, 1, false, g_rvBOOL, ELHS_FrontCC, offsetof_fx(SRasterizerBlock, BackingStore.FrontCounterClockwise), 0 },
- { "DepthBias", EBT_Rasterizer, D3D_SVT_UINT, 1, 1, false, nullptr, ELHS_DepthBias, offsetof_fx(SRasterizerBlock, BackingStore.DepthBias), 0 },
- { "DepthBiasClamp", EBT_Rasterizer, D3D_SVT_FLOAT, 1, 1, false, nullptr, ELHS_DepthBiasClamp, offsetof_fx(SRasterizerBlock, BackingStore.DepthBiasClamp), 0 },
- { "SlopeScaledDepthBias", EBT_Rasterizer, D3D_SVT_FLOAT, 1, 1, false, nullptr, ELHS_SlopeScaledDepthBias, offsetof_fx(SRasterizerBlock, BackingStore.SlopeScaledDepthBias), 0 },
- { "DepthClipEnable", EBT_Rasterizer, D3D_SVT_BOOL, 1, 1, false, g_rvBOOL, ELHS_DepthClipEnable, offsetof_fx(SRasterizerBlock, BackingStore.DepthClipEnable), 0 },
- { "ScissorEnable", EBT_Rasterizer, D3D_SVT_BOOL, 1, 1, false, g_rvBOOL, ELHS_ScissorEnable, offsetof_fx(SRasterizerBlock, BackingStore.ScissorEnable), 0 },
- { "MultisampleEnable", EBT_Rasterizer, D3D_SVT_BOOL, 1, 1, false, g_rvBOOL, ELHS_MultisampleEnable, offsetof_fx(SRasterizerBlock, BackingStore.MultisampleEnable), 0 },
- { "AntialiasedLineEnable", EBT_Rasterizer, D3D_SVT_BOOL, 1, 1, false, g_rvBOOL, ELHS_AntialiasedLineEnable, offsetof_fx(SRasterizerBlock, BackingStore.AntialiasedLineEnable), 0 },
-
- { "DepthEnable", EBT_DepthStencil, D3D_SVT_BOOL, 1, 1, false, g_rvBOOL, ELHS_DepthEnable, offsetof_fx(SDepthStencilBlock, BackingStore.DepthEnable), 0 },
- { "DepthWriteMask", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvDEPTH_WRITE_MASK, ELHS_DepthWriteMask, offsetof_fx(SDepthStencilBlock, BackingStore.DepthWriteMask), 0 },
- { "DepthFunc", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvCMP, ELHS_DepthFunc, offsetof_fx(SDepthStencilBlock, BackingStore.DepthFunc), 0 },
- { "StencilEnable", EBT_DepthStencil, D3D_SVT_BOOL, 1, 1, false, g_rvBOOL, ELHS_StencilEnable, offsetof_fx(SDepthStencilBlock, BackingStore.StencilEnable), 0 },
- { "StencilReadMask", EBT_DepthStencil, D3D_SVT_UINT8, 1, 1, false, nullptr, ELHS_StencilReadMask, offsetof_fx(SDepthStencilBlock, BackingStore.StencilReadMask), 0 },
- { "StencilWriteMask", EBT_DepthStencil, D3D_SVT_UINT8, 1, 1, false, nullptr, ELHS_StencilWriteMask, offsetof_fx(SDepthStencilBlock, BackingStore.StencilWriteMask), 0 },
- { "FrontFaceStencilFail", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvSTENCILOP, ELHS_FrontFaceStencilFailOp, offsetof_fx(SDepthStencilBlock, BackingStore.FrontFace.StencilFailOp), 0 },
- { "FrontFaceStencilDepthFail", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvSTENCILOP, ELHS_FrontFaceStencilDepthFailOp,offsetof_fx(SDepthStencilBlock, BackingStore.FrontFace.StencilDepthFailOp), 0 },
- { "FrontFaceStencilPass", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvSTENCILOP, ELHS_FrontFaceStencilPassOp, offsetof_fx(SDepthStencilBlock, BackingStore.FrontFace.StencilPassOp), 0 },
- { "FrontFaceStencilFunc", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvCMP, ELHS_FrontFaceStencilFunc, offsetof_fx(SDepthStencilBlock, BackingStore.FrontFace.StencilFunc), 0 },
- { "BackFaceStencilFail", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvSTENCILOP, ELHS_BackFaceStencilFailOp, offsetof_fx(SDepthStencilBlock, BackingStore.BackFace.StencilFailOp), 0 },
- { "BackFaceStencilDepthFail", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvSTENCILOP, ELHS_BackFaceStencilDepthFailOp,offsetof_fx(SDepthStencilBlock, BackingStore.BackFace.StencilDepthFailOp), 0 },
- { "BackFaceStencilPass", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvSTENCILOP, ELHS_BackFaceStencilPassOp, offsetof_fx(SDepthStencilBlock, BackingStore.BackFace.StencilPassOp), 0 },
- { "BackFaceStencilFunc", EBT_DepthStencil, D3D_SVT_UINT, 1, 1, false, g_rvCMP, ELHS_BackFaceStencilFunc, offsetof_fx(SDepthStencilBlock, BackingStore.BackFace.StencilFunc), 0 },
-
- { "AlphaToCoverageEnable", EBT_Blend, D3D_SVT_BOOL, 1, 1, false, g_rvBOOL, ELHS_AlphaToCoverage, offsetof_fx(SBlendBlock, BackingStore.AlphaToCoverageEnable), 0 },
- { "BlendEnable", EBT_Blend, D3D_SVT_BOOL, 1, 8, false, g_rvBOOL, ELHS_BlendEnable, offsetof_fx(SBlendBlock, BackingStore.RenderTarget[0].BlendEnable), strideof(SBlendBlock, BackingStore.RenderTarget) },
- { "SrcBlend", EBT_Blend, D3D_SVT_UINT, 1, 8, true, g_rvBLEND, ELHS_SrcBlend, offsetof_fx(SBlendBlock, BackingStore.RenderTarget[0].SrcBlend), strideof(SBlendBlock, BackingStore.RenderTarget) },
- { "DestBlend", EBT_Blend, D3D_SVT_UINT, 1, 8, true, g_rvBLEND, ELHS_DestBlend, offsetof_fx(SBlendBlock, BackingStore.RenderTarget[0].DestBlend), strideof(SBlendBlock, BackingStore.RenderTarget) },
- { "BlendOp", EBT_Blend, D3D_SVT_UINT, 1, 8, true, g_rvBLENDOP, ELHS_BlendOp, offsetof_fx(SBlendBlock, BackingStore.RenderTarget[0].BlendOp), strideof(SBlendBlock, BackingStore.RenderTarget) },
- { "SrcBlendAlpha", EBT_Blend, D3D_SVT_UINT, 1, 8, true, g_rvBLEND, ELHS_SrcBlendAlpha, offsetof_fx(SBlendBlock, BackingStore.RenderTarget[0].SrcBlendAlpha), strideof(SBlendBlock, BackingStore.RenderTarget) },
- { "DestBlendAlpha", EBT_Blend, D3D_SVT_UINT, 1, 8, true, g_rvBLEND, ELHS_DestBlendAlpha, offsetof_fx(SBlendBlock, BackingStore.RenderTarget[0].DestBlendAlpha), strideof(SBlendBlock, BackingStore.RenderTarget) },
- { "BlendOpAlpha", EBT_Blend, D3D_SVT_UINT, 1, 8, true, g_rvBLENDOP, ELHS_BlendOpAlpha, offsetof_fx(SBlendBlock, BackingStore.RenderTarget[0].BlendOpAlpha), strideof(SBlendBlock, BackingStore.RenderTarget) },
- { "RenderTargetWriteMask", EBT_Blend, D3D_SVT_UINT8, 1, 8, false, nullptr, ELHS_RenderTargetWriteMask, offsetof_fx(SBlendBlock, BackingStore.RenderTarget[0].RenderTargetWriteMask), strideof(SBlendBlock, BackingStore.RenderTarget) },
-
- { "Filter", EBT_Sampler, D3D_SVT_UINT, 1, 1, false, g_rvFILTER, ELHS_Filter, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.Filter), 0 },
- { "AddressU", EBT_Sampler, D3D_SVT_UINT, 1, 1, false, g_rvTADDRESS, ELHS_AddressU, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.AddressU), 0 },
- { "AddressV", EBT_Sampler, D3D_SVT_UINT, 1, 1, false, g_rvTADDRESS, ELHS_AddressV, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.AddressV), 0 },
- { "AddressW", EBT_Sampler, D3D_SVT_UINT, 1, 1, false, g_rvTADDRESS, ELHS_AddressW, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.AddressW), 0 },
- { "MipLODBias", EBT_Sampler, D3D_SVT_FLOAT, 1, 1, false, nullptr, ELHS_MipLODBias, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.MipLODBias), 0 },
- { "MaxAnisotropy", EBT_Sampler, D3D_SVT_UINT, 1, 1, false, nullptr, ELHS_MaxAnisotropy, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.MaxAnisotropy), 0 },
- { "ComparisonFunc", EBT_Sampler, D3D_SVT_UINT, 1, 1, false, g_rvCMP, ELHS_ComparisonFunc, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.ComparisonFunc), 0 },
- { "BorderColor", EBT_Sampler, D3D_SVT_FLOAT, 4, 1, false, nullptr, ELHS_BorderColor, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.BorderColor), 0 },
- { "MinLOD", EBT_Sampler, D3D_SVT_FLOAT, 1, 1, false, nullptr, ELHS_MinLOD, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.MinLOD), 0 },
- { "MaxLOD", EBT_Sampler, D3D_SVT_FLOAT, 1, 1, false, nullptr, ELHS_MaxLOD, offsetof_fx(SSamplerBlock, BackingStore.SamplerDesc.MaxLOD), 0 },
- { "Texture", EBT_Sampler, D3D_SVT_TEXTURE, 1, 1, false, g_rvNULL, ELHS_Texture, offsetof_fx(SSamplerBlock, BackingStore.pTexture), 0 },
-
- // D3D11
- { "HullShader", EBT_Pass, D3D11_SVT_HULLSHADER, 1, 1, false, g_rvNULL, ELHS_HullShaderBlock, offsetof_fx(SPassBlock, BackingStore.pHullShaderBlock), 0 },
- { "DomainShader", EBT_Pass, D3D11_SVT_DOMAINSHADER, 1, 1, false, g_rvNULL, ELHS_DomainShaderBlock, offsetof_fx(SPassBlock, BackingStore.pDomainShaderBlock), 0 },
- { "ComputeShader", EBT_Pass, D3D11_SVT_COMPUTESHADER, 1, 1, false, g_rvNULL, ELHS_ComputeShaderBlock, offsetof_fx(SPassBlock, BackingStore.pComputeShaderBlock), 0 },
-};
-
-#define NUM_STATES (sizeof(g_lvGeneral) / sizeof(LValue))
-#define MAX_VECTOR_SCALAR_INDEX 8
-
-const uint32_t g_lvGeneralCount = NUM_STATES;
-
-} // end namespace D3DX11Effects
diff --git a/lib/win32/Effects11/Binary/SOParser.h b/lib/win32/Effects11/Binary/SOParser.h
deleted file mode 100644
index 412ea15e91..0000000000
--- a/lib/win32/Effects11/Binary/SOParser.h
+++ /dev/null
@@ -1,315 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: SOParser.h
-//
-// Direct3D 11 Effects Stream Out Decl Parser
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-
-namespace D3DX11Effects
-{
-
-//////////////////////////////////////////////////////////////////////////
-// CSOParser
-//////////////////////////////////////////////////////////////////////////
-
-class CSOParser
-{
-
- CEffectVector<D3D11_SO_DECLARATION_ENTRY> m_vDecls; // Set of parsed decl entries
- D3D11_SO_DECLARATION_ENTRY m_newEntry; // Currently parsing entry
- LPSTR m_SemanticString[D3D11_SO_BUFFER_SLOT_COUNT]; // Copy of strings
-
- static const size_t MAX_ERROR_SIZE = 254;
- char m_pError[ MAX_ERROR_SIZE + 1 ]; // Error buffer
-
-public:
- CSOParser() noexcept :
- m_newEntry{},
- m_SemanticString{},
- m_pError{}
- {
- }
-
- ~CSOParser()
- {
- for( size_t Stream = 0; Stream < D3D11_SO_STREAM_COUNT; ++Stream )
- {
- SAFE_DELETE_ARRAY( m_SemanticString[Stream] );
- }
- }
-
- // Parse a single string, assuming stream 0
- HRESULT Parse( _In_z_ LPCSTR pString )
- {
- m_vDecls.Clear();
- return Parse( 0, pString );
- }
-
- // Parse all 4 streams
- HRESULT Parse( _In_z_ LPSTR pStreams[D3D11_SO_STREAM_COUNT] )
- {
- HRESULT hr = S_OK;
- m_vDecls.Clear();
- for( uint32_t iDecl=0; iDecl < D3D11_SO_STREAM_COUNT; ++iDecl )
- {
- hr = Parse( iDecl, pStreams[iDecl] );
- if( FAILED(hr) )
- {
- char str[16];
- sprintf_s( str, 16, " in stream %u.", iDecl );
- str[15] = 0;
- strcat_s( m_pError, MAX_ERROR_SIZE, str );
- return hr;
- }
- }
- return hr;
- }
-
- // Return resulting declarations
- D3D11_SO_DECLARATION_ENTRY *GetDeclArray()
- {
- return &m_vDecls[0];
- }
-
- char* GetErrorString()
- {
- return m_pError;
- }
-
- uint32_t GetDeclCount() const
- {
- return m_vDecls.GetSize();
- }
-
- // Return resulting buffer strides
- void GetStrides( uint32_t strides[4] )
- {
- size_t len = GetDeclCount();
- strides[0] = strides[1] = strides[2] = strides[3] = 0;
-
- for( size_t i=0; i < len; i++ )
- {
- strides[m_vDecls[i].OutputSlot] += m_vDecls[i].ComponentCount * sizeof(float);
- }
- }
-
-protected:
-
- // Parse a single string "[<slot> :] <semantic>[<index>][.<mask>]; [[<slot> :] <semantic>[<index>][.<mask>][;]]"
- HRESULT Parse( _In_ uint32_t Stream, _In_z_ LPCSTR pString )
- {
- HRESULT hr = S_OK;
-
- m_pError[0] = 0;
-
- if( pString == nullptr )
- return S_OK;
-
- uint32_t len = (uint32_t)strlen( pString );
- if( len == 0 )
- return S_OK;
-
- SAFE_DELETE_ARRAY( m_SemanticString[Stream] );
- VN( m_SemanticString[Stream] = new char[len + 1] );
- strcpy_s( m_SemanticString[Stream], len + 1, pString );
-
- LPSTR pSemantic = m_SemanticString[Stream];
-
- while( true )
- {
- // Each decl entry is delimited by a semi-colon
- LPSTR pSemi = strchr( pSemantic, ';' );
-
- // strip leading and trailing spaces
- LPSTR pEnd;
- if( pSemi != nullptr )
- {
- *pSemi = '\0';
- pEnd = pSemi - 1;
- }
- else
- {
- pEnd = pSemantic + strlen( pSemantic );
- }
- while( isspace( (unsigned char)*pSemantic ) )
- pSemantic++;
- while( pEnd > pSemantic && isspace( (unsigned char)*pEnd ) )
- {
- *pEnd = '\0';
- pEnd--;
- }
-
- if( *pSemantic != '\0' )
- {
- VH( AddSemantic( pSemantic ) );
- m_newEntry.Stream = Stream;
-
- VH( m_vDecls.Add( m_newEntry ) );
- }
- if( pSemi == nullptr )
- break;
- pSemantic = pSemi + 1;
- }
-
-lExit:
- return hr;
- }
-
- // Parse a single decl "[<slot> :] <semantic>[<index>][.<mask>]"
- HRESULT AddSemantic( _Inout_z_ LPSTR pSemantic )
- {
- HRESULT hr = S_OK;
-
- assert( pSemantic );
-
- ZeroMemory( &m_newEntry, sizeof(m_newEntry) );
- VH( ConsumeOutputSlot( &pSemantic ) );
- VH( ConsumeRegisterMask( pSemantic ) );
- VH( ConsumeSemanticIndex( pSemantic ) );
-
- // pSenantic now contains only the SemanticName (all other fields were consumed)
- if( strcmp( "$SKIP", pSemantic ) != 0 )
- {
- m_newEntry.SemanticName = pSemantic;
- }
-
-lExit:
- return hr;
- }
-
- // Parse optional mask "[.<mask>]"
- HRESULT ConsumeRegisterMask( _Inout_z_ LPSTR pSemantic )
- {
- HRESULT hr = S_OK;
- const char *pFullMask1 = "xyzw";
- const char *pFullMask2 = "rgba";
- size_t stringLength;
- size_t startComponent = 0;
- LPCSTR p;
-
- assert( pSemantic );
-
- pSemantic = strchr( pSemantic, '.' );
-
- if( pSemantic == nullptr )
- {
- m_newEntry.ComponentCount = 4;
- return S_OK;
- }
-
- *pSemantic = '\0';
- pSemantic++;
-
- stringLength = strlen( pSemantic );
- p = strstr(pFullMask1, pSemantic );
- if( p )
- {
- startComponent = (uint32_t)( p - pFullMask1 );
- }
- else
- {
- p = strstr( pFullMask2, pSemantic );
- if( p )
- startComponent = (uint32_t)( p - pFullMask2 );
- else
- {
- sprintf_s( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - invalid mask declaration '%s'", pSemantic );
- VH( E_FAIL );
- }
-
- }
-
- if( stringLength == 0 )
- stringLength = 4;
-
- m_newEntry.StartComponent = (uint8_t)startComponent;
- m_newEntry.ComponentCount = (uint8_t)stringLength;
-
-lExit:
- return hr;
- }
-
- // Parse optional output slot "[<slot> :]"
- HRESULT ConsumeOutputSlot( _Inout_z_ LPSTR* ppSemantic )
- {
- assert( ppSemantic && *ppSemantic );
- _Analysis_assume_( ppSemantic && *ppSemantic );
-
- HRESULT hr = S_OK;
- LPSTR pColon = strchr( *ppSemantic, ':' );
-
- if( pColon == nullptr )
- return S_OK;
-
- if( pColon == *ppSemantic )
- {
- strcpy_s( m_pError, MAX_ERROR_SIZE,
- "ID3D11Effect::ParseSODecl - Invalid output slot" );
- VH( E_FAIL );
- }
-
- *pColon = '\0';
- int outputSlot = atoi( *ppSemantic );
- if( outputSlot < 0 || outputSlot > 255 )
- {
- strcpy_s( m_pError, MAX_ERROR_SIZE,
- "ID3D11Effect::ParseSODecl - Invalid output slot" );
- VH( E_FAIL );
- }
- m_newEntry.OutputSlot = (uint8_t)outputSlot;
-
- while( *ppSemantic < pColon )
- {
- if( !isdigit( (unsigned char)**ppSemantic ) )
- {
- sprintf_s( m_pError, MAX_ERROR_SIZE, "ID3D11Effect::ParseSODecl - Non-digit '%c' in output slot", **ppSemantic );
- VH( E_FAIL );
- }
- (*ppSemantic)++;
- }
-
- // skip the colon (which is now '\0')
- (*ppSemantic)++;
-
- while( isspace( (unsigned char)**ppSemantic ) )
- (*ppSemantic)++;
-
-lExit:
- return hr;
- }
-
- // Parse optional index "[<index>]"
- HRESULT ConsumeSemanticIndex( _Inout_z_ LPSTR pSemantic )
- {
- assert( pSemantic );
-
- uint32_t uLen = (uint32_t)strlen( pSemantic );
-
- // Grab semantic index
- while( uLen > 0 && isdigit( (unsigned char)pSemantic[uLen - 1] ) )
- uLen--;
-
- if( isdigit( (unsigned char)pSemantic[uLen] ) )
- {
- m_newEntry.SemanticIndex = atoi( pSemantic + uLen );
- pSemantic[uLen] = '\0';
- }
- else
- {
- m_newEntry.SemanticIndex = 0;
- }
-
- return S_OK;
- }
-};
-
-} // end namespace D3DX11Effects
diff --git a/lib/win32/Effects11/CMakeLists.txt b/lib/win32/Effects11/CMakeLists.txt
deleted file mode 100644
index 8ea61fe7b5..0000000000
--- a/lib/win32/Effects11/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-set(SOURCES d3dxGlobal.cpp
- EffectAPI.cpp
- EffectLoad.cpp
- EffectNonRuntime.cpp
- EffectReflection.cpp
- EffectRuntime.cpp)
-
-add_library(effects11 STATIC ${SOURCES})
-target_include_directories(effects11
- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Binary
-)
-
-target_compile_options(effects11 PRIVATE "/permissive")
-
-if(CORE_SYSTEM_NAME STREQUAL windowsstore)
- target_compile_definitions(effects11 PRIVATE
- WIN32
- _WINDOWS
- _LIB
- D3DXFX_LARGEADDRESS_HANDLE
- _WIN32_WINNT=0x0A00
- _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS
- )
-else()
-target_compile_definitions(effects11 PRIVATE
- WIN32
- _WINDOWS
- _LIB
- D3DXFX_LARGEADDRESS_HANDLE
- _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS
-)
-endif()
-
-add_precompiled_header(effects11 pchfx.h d3dxGlobal.cpp)
-set_target_properties(effects11 PROPERTIES FOLDER lib)
-source_group_by_folder(effects11)
-set(core_DEPENDS effects11 ${core_DEPENDS} CACHE STRING "" FORCE)
-
-if(CORE_SYSTEM_NAME STREQUAL windowsstore)
- set_target_properties(effects11 PROPERTIES STATIC_LIBRARY_FLAGS "/ignore:4264")
-endif()
diff --git a/lib/win32/Effects11/Effect.h b/lib/win32/Effects11/Effect.h
deleted file mode 100644
index c350f02deb..0000000000
--- a/lib/win32/Effects11/Effect.h
+++ /dev/null
@@ -1,1276 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: Effect.h
-//
-// Direct3D 11 Effects Header for ID3DX11Effect Implementation
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-#include "EffectBinaryFormat.h"
-#include "IUnknownImp.h"
-
-#ifdef _DEBUG
-extern void __cdecl D3DXDebugPrintf(UINT lvl, _In_z_ _Printf_format_string_ LPCSTR szFormat, ...);
-#define DPF D3DXDebugPrintf
-#else
-#define DPF
-#endif
-
-#pragma warning(push)
-#pragma warning(disable : 4481)
-// VS 2010 considers 'override' to be a extension, but it's part of C++11 as of VS 2012
-
-//////////////////////////////////////////////////////////////////////////
-
-using namespace D3DX11Core;
-
-namespace D3DX11Effects
-{
-
-//////////////////////////////////////////////////////////////////////////
-// Forward defines
-//////////////////////////////////////////////////////////////////////////
-
-struct SBaseBlock;
-struct SShaderBlock;
-struct SPassBlock;
-struct SClassInstance;
-struct SInterface;
-struct SShaderResource;
-struct SUnorderedAccessView;
-struct SRenderTargetView;
-struct SDepthStencilView;
-struct SSamplerBlock;
-struct SDepthStencilBlock;
-struct SBlendBlock;
-struct SRasterizerBlock;
-struct SString;
-struct SD3DShaderVTable;
-struct SClassInstanceGlobalVariable;
-
-struct SAssignment;
-struct SVariable;
-struct SGlobalVariable;
-struct SAnnotation;
-struct SConstantBuffer;
-
-class CEffect;
-class CEffectLoader;
-
-enum ELhsType : int;
-
-// Allows the use of 32-bit and 64-bit timers depending on platform type
-typedef size_t Timer;
-
-//////////////////////////////////////////////////////////////////////////
-// Reflection & Type structures
-//////////////////////////////////////////////////////////////////////////
-
-// CEffectMatrix is used internally instead of float arrays
-struct CEffectMatrix
-{
- union
- {
- struct
- {
- float _11, _12, _13, _14;
- float _21, _22, _23, _24;
- float _31, _32, _33, _34;
- float _41, _42, _43, _44;
-
- };
- float m[4][4];
- };
-};
-
-struct CEffectVector4
-{
- float x;
- float y;
- float z;
- float w;
-};
-
-union UDataPointer
-{
- void *pGeneric;
- uint8_t *pNumeric;
- float *pNumericFloat;
- uint32_t *pNumericDword;
- int *pNumericInt;
- BOOL *pNumericBool;
- SString *pString;
- SShaderBlock *pShader;
- SBaseBlock *pBlock;
- SBlendBlock *pBlend;
- SDepthStencilBlock *pDepthStencil;
- SRasterizerBlock *pRasterizer;
- SInterface *pInterface;
- SShaderResource *pShaderResource;
- SUnorderedAccessView *pUnorderedAccessView;
- SRenderTargetView *pRenderTargetView;
- SDepthStencilView *pDepthStencilView;
- SSamplerBlock *pSampler;
- CEffectVector4 *pVector;
- CEffectMatrix *pMatrix;
- UINT_PTR Offset;
-};
-
-enum EMemberDataType
-{
- MDT_ClassInstance,
- MDT_BlendState,
- MDT_DepthStencilState,
- MDT_RasterizerState,
- MDT_SamplerState,
- MDT_Buffer,
- MDT_ShaderResourceView,
-};
-
-struct SMemberDataPointer
-{
- EMemberDataType Type;
- union
- {
- IUnknown *pGeneric;
- ID3D11ClassInstance *pD3DClassInstance;
- ID3D11BlendState *pD3DEffectsManagedBlendState;
- ID3D11DepthStencilState *pD3DEffectsManagedDepthStencilState;
- ID3D11RasterizerState *pD3DEffectsManagedRasterizerState;
- ID3D11SamplerState *pD3DEffectsManagedSamplerState;
- ID3D11Buffer *pD3DEffectsManagedConstantBuffer;
- ID3D11ShaderResourceView*pD3DEffectsManagedTextureBuffer;
- } Data;
-};
-
-struct SType : public ID3DX11EffectType
-{
- static const UINT_PTR c_InvalidIndex = (uint32_t) -1;
- static const uint32_t c_ScalarSize = sizeof(uint32_t);
-
- // packing rule constants
- static const uint32_t c_ScalarsPerRegister = 4;
- static const uint32_t c_RegisterSize = c_ScalarsPerRegister * c_ScalarSize; // must be a power of 2!!
-
- EVarType VarType; // numeric, object, struct
- uint32_t Elements; // # of array elements (0 for non-arrays)
- char *pTypeName; // friendly name of the type: "VS_OUTPUT", "float4", etc.
-
- // *Size and stride values are always 0 for object types
- // *Annotations adhere to packing rules (even though they do not reside in constant buffers)
- // for consistency's sake
- //
- // Packing rules:
- // *Structures and array elements are always register aligned
- // *Single-row values (or, for column major matrices, single-column) are greedily
- // packed unless doing so would span a register boundary, in which case they are
- // register aligned
-
- uint32_t TotalSize; // Total size of this data type in a constant buffer from
- // start to finish (padding in between elements is included,
- // but padding at the end is not since that would require
- // knowledge of the following data type).
-
- uint32_t Stride; // Number of bytes to advance between elements.
- // Typically a multiple of 16 for arrays, vectors, matrices.
- // For scalars and small vectors/matrices, this can be 4 or 8.
-
- uint32_t PackedSize; // Size, in bytes, of this data typed when fully packed
-
- union
- {
- SBinaryNumericType NumericType;
- EObjectType ObjectType; // not all values of EObjectType are valid here (e.g. constant buffer)
- struct
- {
- SVariable *pMembers; // array of type instances describing structure members
- uint32_t Members;
- BOOL ImplementsInterface; // true if this type implements an interface
- BOOL HasSuperClass; // true if this type has a parent class
- } StructType;
- void* InterfaceType; // nothing for interfaces
- };
-
-
- SType() noexcept :
- VarType(EVT_Invalid),
- Elements(0),
- pTypeName(nullptr),
- TotalSize(0),
- Stride(0),
- PackedSize(0),
- StructType{}
- {
- static_assert(sizeof(NumericType) <= sizeof(StructType), "SType union issue");
- static_assert(sizeof(ObjectType) <= sizeof(StructType), "SType union issue");
- static_assert(sizeof(InterfaceType) <= sizeof(StructType), "SType union issue");
- }
-
- bool IsEqual(SType *pOtherType) const;
-
- bool IsObjectType(EObjectType ObjType) const
- {
- return IsObjectTypeHelper(VarType, ObjectType, ObjType);
- }
- bool IsShader() const
- {
- return IsShaderHelper(VarType, ObjectType);
- }
- bool BelongsInConstantBuffer() const
- {
- return (VarType == EVT_Numeric) || (VarType == EVT_Struct);
- }
- bool IsStateBlockObject() const
- {
- return IsStateBlockObjectHelper(VarType, ObjectType);
- }
- bool IsClassInstance() const
- {
- return (VarType == EVT_Struct) && StructType.ImplementsInterface;
- }
- bool IsInterface() const
- {
- return IsInterfaceHelper(VarType, ObjectType);
- }
- bool IsShaderResource() const
- {
- return IsShaderResourceHelper(VarType, ObjectType);
- }
- bool IsUnorderedAccessView() const
- {
- return IsUnorderedAccessViewHelper(VarType, ObjectType);
- }
- bool IsSampler() const
- {
- return IsSamplerHelper(VarType, ObjectType);
- }
- bool IsRenderTargetView() const
- {
- return IsRenderTargetViewHelper(VarType, ObjectType);
- }
- bool IsDepthStencilView() const
- {
- return IsDepthStencilViewHelper(VarType, ObjectType);
- }
-
- uint32_t GetTotalUnpackedSize(_In_ bool IsSingleElement) const;
- uint32_t GetTotalPackedSize(_In_ bool IsSingleElement) const;
- HRESULT GetDescHelper(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc, _In_ bool IsSingleElement) const;
-
- STDMETHOD_(bool, IsValid)() override { return true; }
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override { return GetDescHelper(pDesc, false); }
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
- STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
- STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
-
- IUNKNOWN_IMP(SType, ID3DX11EffectType, IUnknown);
-};
-
-// Represents a type structure for a single element.
-// It seems pretty trivial, but it has a different virtual table which enables
-// us to accurately represent a type that consists of a single element
-struct SSingleElementType : public ID3DX11EffectType
-{
- SType *pType;
-
- STDMETHOD_(bool, IsValid)() override { return true; }
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override { return ((SType*)pType)->GetDescHelper(pDesc, true); }
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(uint32_t Index) override { return ((SType*)pType)->GetMemberTypeByIndex(Index); }
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(LPCSTR Name) override { return ((SType*)pType)->GetMemberTypeByName(Name); }
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(LPCSTR Semantic) override { return ((SType*)pType)->GetMemberTypeBySemantic(Semantic); }
- STDMETHOD_(LPCSTR, GetMemberName)(uint32_t Index) override { return ((SType*)pType)->GetMemberName(Index); }
- STDMETHOD_(LPCSTR, GetMemberSemantic)(uint32_t Index) override { return ((SType*)pType)->GetMemberSemantic(Index); }
-
- IUNKNOWN_IMP(SSingleElementType, ID3DX11EffectType, IUnknown);
-
- SSingleElementType() noexcept :
- pType(nullptr)
- {
- }
-};
-
-//////////////////////////////////////////////////////////////////////////
-// Block definitions
-//////////////////////////////////////////////////////////////////////////
-
-void * GetBlockByIndex(EVarType VarType, EObjectType ObjectType, void *pBaseBlock, uint32_t Index);
-
-struct SBaseBlock
-{
- EBlockType BlockType;
-
- bool IsUserManaged:1;
-
- uint32_t AssignmentCount;
- SAssignment *pAssignments;
-
- SBaseBlock() noexcept;
-
- bool ApplyAssignments(CEffect *pEffect);
-
- inline SSamplerBlock *AsSampler() const
- {
- assert( BlockType == EBT_Sampler );
- return (SSamplerBlock*) this;
- }
-
- inline SDepthStencilBlock *AsDepthStencil() const
- {
- assert( BlockType == EBT_DepthStencil );
- return (SDepthStencilBlock*) this;
- }
-
- inline SBlendBlock *AsBlend() const
- {
- assert( BlockType == EBT_Blend );
- return (SBlendBlock*) this;
- }
-
- inline SRasterizerBlock *AsRasterizer() const
- {
- assert( BlockType == EBT_Rasterizer );
- return (SRasterizerBlock*) this;
- }
-
- inline SPassBlock *AsPass() const
- {
- assert( BlockType == EBT_Pass );
- return (SPassBlock*) this;
- }
-};
-
-struct STechnique : public ID3DX11EffectTechnique
-{
- char *pName;
-
- uint32_t PassCount;
- SPassBlock *pPasses;
-
- uint32_t AnnotationCount;
- SAnnotation *pAnnotations;
-
- bool InitiallyValid;
- bool HasDependencies;
-
- STechnique() noexcept;
-
- STDMETHOD_(bool, IsValid)() override;
- STDMETHOD(GetDesc)(_Out_ D3DX11_TECHNIQUE_DESC *pDesc) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD_(ID3DX11EffectPass*, GetPassByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectPass*, GetPassByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override;
-
- IUNKNOWN_IMP(STechnique, ID3DX11EffectTechnique, IUnknown);
-};
-
-struct SGroup : public ID3DX11EffectGroup
-{
- char *pName;
-
- uint32_t TechniqueCount;
- STechnique *pTechniques;
-
- uint32_t AnnotationCount;
- SAnnotation *pAnnotations;
-
- bool InitiallyValid;
- bool HasDependencies;
-
- SGroup() noexcept;
-
- STDMETHOD_(bool, IsValid)() override;
- STDMETHOD(GetDesc)(_Out_ D3DX11_GROUP_DESC *pDesc) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(_In_z_ LPCSTR Name) override;
-
- IUNKNOWN_IMP(SGroup, ID3DX11EffectGroup, IUnknown);
-};
-
-struct SPassBlock : SBaseBlock, public ID3DX11EffectPass
-{
- struct
- {
- ID3D11BlendState* pBlendState;
- FLOAT BlendFactor[4];
- uint32_t SampleMask;
- ID3D11DepthStencilState *pDepthStencilState;
- uint32_t StencilRef;
- union
- {
- D3D11_SO_DECLARATION_ENTRY *pEntry;
- char *pEntryDesc;
- } GSSODesc;
-
- // Pass assignments can write directly into these
- SBlendBlock *pBlendBlock;
- SDepthStencilBlock *pDepthStencilBlock;
- SRasterizerBlock *pRasterizerBlock;
- uint32_t RenderTargetViewCount;
- SRenderTargetView *pRenderTargetViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
- SDepthStencilView *pDepthStencilView;
- SShaderBlock *pVertexShaderBlock;
- SShaderBlock *pPixelShaderBlock;
- SShaderBlock *pGeometryShaderBlock;
- SShaderBlock *pComputeShaderBlock;
- SShaderBlock *pDomainShaderBlock;
- SShaderBlock *pHullShaderBlock;
- } BackingStore;
-
- char *pName;
-
- uint32_t AnnotationCount;
- SAnnotation *pAnnotations;
-
- CEffect *pEffect;
-
- bool InitiallyValid; // validity of all state objects and shaders in pass upon BindToDevice
- bool HasDependencies; // if pass expressions or pass state blocks have dependencies on variables (if true, IsValid != InitiallyValid possibly)
-
- SPassBlock() noexcept;
-
- void ApplyPassAssignments();
- bool CheckShaderDependencies( _In_ const SShaderBlock* pBlock );
- bool CheckDependencies();
-
- template<EObjectType EShaderType>
- HRESULT GetShaderDescHelper(_Out_ D3DX11_PASS_SHADER_DESC *pDesc);
-
- STDMETHOD_(bool, IsValid)() override;
- STDMETHOD(GetDesc)(_Out_ D3DX11_PASS_DESC *pDesc) override;
-
- STDMETHOD(GetVertexShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
- STDMETHOD(GetGeometryShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
- STDMETHOD(GetPixelShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
- STDMETHOD(GetHullShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
- STDMETHOD(GetDomainShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
- STDMETHOD(GetComputeShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD(Apply)(_In_ uint32_t Flags, _In_ ID3D11DeviceContext* pContext) override;
-
- STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override;
-
- IUNKNOWN_IMP(SPassBlock, ID3DX11EffectPass, IUnknown);
-};
-
-struct SDepthStencilBlock : SBaseBlock
-{
- ID3D11DepthStencilState *pDSObject;
- D3D11_DEPTH_STENCIL_DESC BackingStore;
- bool IsValid;
-
- SDepthStencilBlock() noexcept;
-};
-
-struct SBlendBlock : SBaseBlock
-{
- ID3D11BlendState *pBlendObject;
- D3D11_BLEND_DESC BackingStore;
- bool IsValid;
-
- SBlendBlock() noexcept;
-};
-
-struct SRasterizerBlock : SBaseBlock
-{
- ID3D11RasterizerState *pRasterizerObject;
- D3D11_RASTERIZER_DESC BackingStore;
- bool IsValid;
-
- SRasterizerBlock() noexcept;
-};
-
-struct SSamplerBlock : SBaseBlock
-{
- ID3D11SamplerState *pD3DObject;
- struct
- {
- D3D11_SAMPLER_DESC SamplerDesc;
- // Sampler "TEXTURE" assignments can write directly into this
- SShaderResource *pTexture;
- } BackingStore;
-
- SSamplerBlock() noexcept;
-};
-
-struct SInterface
-{
- SClassInstanceGlobalVariable* pClassInstance;
-
- SInterface() noexcept :
- pClassInstance(nullptr)
- {
- }
-};
-
-struct SShaderResource
-{
- ID3D11ShaderResourceView *pShaderResource;
-
- SShaderResource() noexcept :
- pShaderResource(nullptr)
- {
- }
-};
-
-struct SUnorderedAccessView
-{
- ID3D11UnorderedAccessView *pUnorderedAccessView;
-
- SUnorderedAccessView() noexcept :
- pUnorderedAccessView(nullptr)
- {
- }
-};
-
-struct SRenderTargetView
-{
- ID3D11RenderTargetView *pRenderTargetView;
-
- SRenderTargetView() noexcept :
- pRenderTargetView(nullptr)
- {
- }
-};
-
-struct SDepthStencilView
-{
- ID3D11DepthStencilView *pDepthStencilView;
-
- SDepthStencilView() noexcept :
- pDepthStencilView(nullptr)
- {
- }
-};
-
-
-template<class T, class D3DTYPE> struct SShaderDependency
-{
- uint32_t StartIndex;
- uint32_t Count;
-
- T *ppFXPointers; // Array of ptrs to FX objects (CBs, SShaderResources, etc)
- D3DTYPE *ppD3DObjects; // Array of ptrs to matching D3D objects
-
- SShaderDependency() noexcept :
- StartIndex(0),
- Count(0),
- ppFXPointers(nullptr),
- ppD3DObjects(nullptr)
- {
- }
-};
-
-typedef SShaderDependency<SConstantBuffer*, ID3D11Buffer*> SShaderCBDependency;
-typedef SShaderDependency<SSamplerBlock*, ID3D11SamplerState*> SShaderSamplerDependency;
-typedef SShaderDependency<SShaderResource*, ID3D11ShaderResourceView*> SShaderResourceDependency;
-typedef SShaderDependency<SUnorderedAccessView*, ID3D11UnorderedAccessView*> SUnorderedAccessViewDependency;
-typedef SShaderDependency<SInterface*, ID3D11ClassInstance*> SInterfaceDependency;
-
-// Shader VTables are used to eliminate branching in ApplyShaderBlock.
-// The effect owns one D3DShaderVTables for each shader stage
-struct SD3DShaderVTable
-{
- void ( __stdcall ID3D11DeviceContext::*pSetShader)(ID3D11DeviceChild* pShader, ID3D11ClassInstance*const* ppClassInstances, uint32_t NumClassInstances);
- void ( __stdcall ID3D11DeviceContext::*pSetConstantBuffers)(uint32_t StartConstantSlot, uint32_t NumBuffers, ID3D11Buffer *const *pBuffers);
- void ( __stdcall ID3D11DeviceContext::*pSetSamplers)(uint32_t Offset, uint32_t NumSamplers, ID3D11SamplerState*const* pSamplers);
- void ( __stdcall ID3D11DeviceContext::*pSetShaderResources)(uint32_t Offset, uint32_t NumResources, ID3D11ShaderResourceView *const *pResources);
- HRESULT ( __stdcall ID3D11Device::*pCreateShader)(const void *pShaderBlob, size_t ShaderBlobSize, ID3D11ClassLinkage* pClassLinkage, ID3D11DeviceChild **ppShader);
-};
-
-
-struct SShaderBlock
-{
- enum ESigType
- {
- ST_Input,
- ST_Output,
- ST_PatchConstant,
- };
-
- struct SInterfaceParameter
- {
- char *pName;
- uint32_t Index;
- };
-
- // this data is classified as reflection-only and will all be discarded at runtime
- struct SReflectionData
- {
- uint8_t *pBytecode;
- uint32_t BytecodeLength;
- char *pStreamOutDecls[4]; // set with ConstructGSWithSO
- uint32_t RasterizedStream; // set with ConstructGSWithSO
- BOOL IsNullGS;
- ID3D11ShaderReflection *pReflection;
- uint32_t InterfaceParameterCount; // set with BindInterfaces (used for function interface parameters)
- SInterfaceParameter *pInterfaceParameters; // set with BindInterfaces (used for function interface parameters)
- };
-
- bool IsValid;
- SD3DShaderVTable *pVT;
-
- // This value is nullptr if the shader is nullptr or was never initialized
- SReflectionData *pReflectionData;
-
- ID3D11DeviceChild *pD3DObject;
-
- uint32_t CBDepCount;
- SShaderCBDependency *pCBDeps;
-
- uint32_t SampDepCount;
- SShaderSamplerDependency *pSampDeps;
-
- uint32_t InterfaceDepCount;
- SInterfaceDependency *pInterfaceDeps;
-
- uint32_t ResourceDepCount;
- SShaderResourceDependency *pResourceDeps;
-
- uint32_t UAVDepCount;
- SUnorderedAccessViewDependency *pUAVDeps;
-
- uint32_t TBufferDepCount;
- SConstantBuffer **ppTbufDeps;
-
- ID3DBlob *pInputSignatureBlob; // The input signature is separated from the bytecode because it
- // is always available, even after Optimize() has been called.
-
- SShaderBlock(SD3DShaderVTable *pVirtualTable = nullptr) noexcept;
-
- EObjectType GetShaderType();
-
- HRESULT OnDeviceBind();
-
- // Public API helpers
- HRESULT ComputeStateBlockMask(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask);
-
- HRESULT GetShaderDesc(_Out_ D3DX11_EFFECT_SHADER_DESC *pDesc, _In_ bool IsInline);
-
- HRESULT GetVertexShader(_Outptr_ ID3D11VertexShader **ppVS);
- HRESULT GetGeometryShader(_Outptr_ ID3D11GeometryShader **ppGS);
- HRESULT GetPixelShader(_Outptr_ ID3D11PixelShader **ppPS);
- HRESULT GetHullShader(_Outptr_ ID3D11HullShader **ppHS);
- HRESULT GetDomainShader(_Outptr_ ID3D11DomainShader **ppDS);
- HRESULT GetComputeShader(_Outptr_ ID3D11ComputeShader **ppCS);
-
- HRESULT GetSignatureElementDesc(_In_ ESigType SigType, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc);
-};
-
-
-
-struct SString
-{
- char *pString;
-
- SString() noexcept :
- pString(nullptr)
- {
- }
-};
-
-
-
-//////////////////////////////////////////////////////////////////////////
-// Global Variable & Annotation structure/interface definitions
-//////////////////////////////////////////////////////////////////////////
-
-//
-// This is a general structure that can describe
-// annotations, variables, and structure members
-//
-struct SVariable
-{
- // For annotations/variables/variable members:
- // 1) If numeric, pointer to data (for variables: points into backing store,
- // for annotations, points into reflection heap)
- // OR
- // 2) If object, pointer to the block. If object array, subsequent array elements are found in
- // contiguous blocks; the Nth block is found by ((<SpecificBlockType> *) pBlock) + N
- // (this is because variables that are arrays of objects have their blocks allocated contiguously)
- //
- // For structure members:
- // Offset of this member (in bytes) from parent structure (structure members must be numeric/struct)
- UDataPointer Data;
- union
- {
- uint32_t MemberDataOffsetPlus4; // 4 added so that 0 == nullptr can represent "unused"
- SMemberDataPointer *pMemberData;
- };
-
- SType *pType;
- char *pName;
- char *pSemantic;
- uint32_t ExplicitBindPoint;
-
- SVariable() noexcept :
- Data{},
- pMemberData(nullptr),
- pType(nullptr),
- pName(nullptr),
- pSemantic(nullptr),
- ExplicitBindPoint(uint32_t(-1))
- {
- }
-};
-
-// Template definitions for all of the various ID3DX11EffectVariable specializations
-#include "EffectVariable.inl"
-
-
-////////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectShaderVariable (SAnonymousShader implementation)
-////////////////////////////////////////////////////////////////////////////////
-
-struct SAnonymousShader : public TUncastableVariable<ID3DX11EffectShaderVariable>, public ID3DX11EffectType
-{
- SShaderBlock *pShaderBlock;
-
- SAnonymousShader(_In_opt_ SShaderBlock *pBlock = nullptr) noexcept;
-
- // ID3DX11EffectShaderVariable interface
- STDMETHOD_(bool, IsValid)() override;
- STDMETHOD_(ID3DX11EffectType*, GetType)() override;
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index) override;
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override;
-
- // other casts are handled by TUncastableVariable
- STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)() override;
-
- STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetRawValue)(_Out_writes_bytes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(GetShaderDesc)(_In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc) override;
-
- STDMETHOD(GetVertexShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11VertexShader **ppVS) override;
- STDMETHOD(GetGeometryShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11GeometryShader **ppGS) override;
- STDMETHOD(GetPixelShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11PixelShader **ppPS) override;
- STDMETHOD(GetHullShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11HullShader **ppHS) override;
- STDMETHOD(GetDomainShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11DomainShader **ppDS) override;
- STDMETHOD(GetComputeShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11ComputeShader **ppCS) override;
-
- STDMETHOD(GetInputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
- STDMETHOD(GetOutputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
- STDMETHOD(GetPatchConstantSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
-
- // ID3DX11EffectType interface
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
-
- STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
- STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
-
- IUNKNOWN_IMP(SAnonymousShader, ID3DX11EffectShaderVariable, ID3DX11EffectVariable);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectConstantBuffer (SConstantBuffer implementation)
-////////////////////////////////////////////////////////////////////////////////
-
-struct SConstantBuffer : public TUncastableVariable<ID3DX11EffectConstantBuffer>, public ID3DX11EffectType
-{
- ID3D11Buffer *pD3DObject;
- SShaderResource TBuffer; // nullptr iff IsTbuffer == false
-
- uint8_t *pBackingStore;
- uint32_t Size; // in bytes
-
- char *pName;
-
- uint32_t AnnotationCount;
- SAnnotation *pAnnotations;
-
- uint32_t VariableCount; // # of variables contained in this cbuffer
- SGlobalVariable *pVariables; // array of size [VariableCount], points into effect's contiguous variable list
- uint32_t ExplicitBindPoint; // Used when a CB has been explicitly bound (register(bXX)). -1 if not
-
- bool IsDirty:1; // Set when any member is updated; cleared on CB apply
- bool IsTBuffer:1; // true iff TBuffer.pShaderResource != nullptr
- bool IsUserManaged:1; // Set if you don't want effects to update this buffer
- bool IsEffectOptimized:1;// Set if the effect has been optimized
- bool IsUsedByExpression:1;// Set if used by any expressions
- bool IsUserPacked:1; // Set if the elements have user-specified offsets
- bool IsSingle:1; // Set to true if you want to share this CB with cloned Effects
- bool IsNonUpdatable:1; // Set to true if you want to share this CB with cloned Effects
-
- union
- {
- // These are used to store the original ID3D11Buffer* for use in UndoSetConstantBuffer
- uint32_t MemberDataOffsetPlus4; // 4 added so that 0 == nullptr can represent "unused"
- SMemberDataPointer *pMemberData;
- };
-
- CEffect *pEffect;
-
- SConstantBuffer() noexcept :
- pD3DObject(nullptr),
- TBuffer{},
- pBackingStore(nullptr),
- Size(0),
- pName(nullptr),
- AnnotationCount(0),
- pAnnotations(nullptr),
- VariableCount(0),
- pVariables(nullptr),
- ExplicitBindPoint(uint32_t(-1)),
- IsDirty(false),
- IsTBuffer(false),
- IsUserManaged(false),
- IsEffectOptimized(false),
- IsUsedByExpression(false),
- IsUserPacked(false),
- IsSingle(false),
- IsNonUpdatable(false),
- pMemberData(nullptr),
- pEffect(nullptr)
- {
- }
-
- bool ClonedSingle() const;
-
- // ID3DX11EffectConstantBuffer interface
- STDMETHOD_(bool, IsValid)() override;
- STDMETHOD_(ID3DX11EffectType*, GetType)() override;
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index) override;
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override;
-
- // other casts are handled by TUncastableVariable
- STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)() override;
-
- STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetRawValue)(_Out_writes_bytes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(SetConstantBuffer)(_In_ ID3D11Buffer *pConstantBuffer) override;
- STDMETHOD(GetConstantBuffer)(_Outptr_ ID3D11Buffer **ppConstantBuffer) override;
- STDMETHOD(UndoSetConstantBuffer)() override;
-
- STDMETHOD(SetTextureBuffer)(_In_ ID3D11ShaderResourceView *pTextureBuffer) override;
- STDMETHOD(GetTextureBuffer)(_Outptr_ ID3D11ShaderResourceView **ppTextureBuffer) override;
- STDMETHOD(UndoSetTextureBuffer)() override;
-
- // ID3DX11EffectType interface
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override;
-
- STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override;
- STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override;
-
- IUNKNOWN_IMP(SConstantBuffer, ID3DX11EffectConstantBuffer, ID3DX11EffectVariable);
-};
-
-
-//////////////////////////////////////////////////////////////////////////
-// Assignments
-//////////////////////////////////////////////////////////////////////////
-
-enum ERuntimeAssignmentType
-{
- ERAT_Invalid,
- // [Destination] refers to the destination location, which is always the backing store of the pass/state block.
- // [Source] refers to the current source of data, always coming from either a constant buffer's
- // backing store (for numeric assignments), an object variable's block array, or an anonymous (unowned) block
-
- // Numeric variables:
- ERAT_Constant, // Source is unused.
- // No dependencies; this assignment can be safely removed after load.
- ERAT_NumericVariable, // Source points to the CB's backing store where the value lives.
- // 1 dependency: the variable itself.
- ERAT_NumericConstIndex, // Source points to the CB's backing store where the value lives, offset by N.
- // 1 dependency: the variable array being indexed.
- ERAT_NumericVariableIndex, // Source points to the last used element of the variable in the CB's backing store.
- // 2 dependencies: the index variable followed by the array variable.
-
- // Object variables:
- ERAT_ObjectInlineShader, // An anonymous, immutable shader block pointer is copied to the destination immediately.
- // No dependencies; this assignment can be safely removed after load.
- ERAT_ObjectVariable, // A pointer to the block owned by the object variable is copied to the destination immediately.
- // No dependencies; this assignment can be safely removed after load.
- ERAT_ObjectConstIndex, // A pointer to the Nth block owned by an object variable is copied to the destination immediately.
- // No dependencies; this assignment can be safely removed after load.
- ERAT_ObjectVariableIndex, // Source points to the first block owned by an object variable array
- // (the offset from this, N, is taken from another variable).
- // 1 dependency: the variable being used to index the array.
-};
-
-struct SAssignment
-{
- struct SDependency
- {
- SGlobalVariable *pVariable;
-
- SDependency() noexcept :
- pVariable(nullptr)
- {
- }
- };
-
- ELhsType LhsType; // PS, VS, DepthStencil etc.
-
- // The value of SAssignment.AssignmentType determines how the other fields behave
- // (DependencyCount, pDependencies, Destination, and Source)
- ERuntimeAssignmentType AssignmentType;
-
- Timer LastRecomputedTime;
-
- // see comments in ERuntimeAssignmentType for how dependencies and data pointers are handled
- uint32_t DependencyCount;
- SDependency *pDependencies;
-
- UDataPointer Destination; // This value never changes after load, and always refers to the backing store
- UDataPointer Source; // This value, on the other hand, can change if variable- or expression- driven
-
- uint32_t DataSize : 16; // Size of the data element to be copied in bytes (if numeric) or
- // stride of the block type (if object)
- uint32_t MaxElements : 16; // Max allowable index (needed because we don't store object arrays as dependencies,
- // and therefore have no way of getting their Element count)
-
- bool IsObjectAssignment() // True for Shader and RObject assignments (the type that appear in pass blocks)
- {
- return IsObjectAssignmentHelper(LhsType);
- }
-
- SAssignment() noexcept :
- LhsType(ELHS_Invalid),
- AssignmentType(ERAT_Invalid),
- LastRecomputedTime(0),
- DependencyCount(0),
- pDependencies(nullptr),
- Destination{0},
- Source{0},
- DataSize(0),
- MaxElements(0)
- {
- }
-};
-
-//////////////////////////////////////////////////////////////////////////
-// Private effect heaps
-//////////////////////////////////////////////////////////////////////////
-
-// Used to efficiently reallocate data
-// 1) For every piece of data that needs reallocation, move it to its new location
-// and add an entry into the table
-// 2) For everyone that references one of these data blocks, do a quick table lookup
-// to find the old pointer and then replace it with the new one
-struct SPointerMapping
-{
- void *pOld;
- void *pNew;
-
- static bool AreMappingsEqual(const SPointerMapping &pMap1, const SPointerMapping &pMap2)
- {
- return (pMap1.pOld == pMap2.pOld);
- }
-
- uint32_t Hash()
- {
- // hash the pointer itself
- // (using the pointer as a hash would be very bad)
- return ComputeHash((uint8_t*)&pOld, sizeof(pOld));
- }
-};
-
-typedef CEffectHashTableWithPrivateHeap<SPointerMapping, SPointerMapping::AreMappingsEqual> CPointerMappingTable;
-
-// Assist adding data to a block of memory
-class CEffectHeap
-{
-protected:
- uint8_t *m_pData;
- uint32_t m_dwBufferSize;
- uint32_t m_dwSize;
-
- template <bool bCopyData>
- HRESULT AddDataInternal(_In_reads_bytes_(dwSize) const void *pData, _In_ uint32_t dwSize, _Outptr_ void **ppPointer);
-
-public:
- HRESULT ReserveMemory(uint32_t dwSize);
- uint32_t GetSize();
- uint8_t* GetDataStart() { return m_pData; }
-
- // AddData and AddString append existing data to the buffer - they change m_dwSize. Users are
- // not expected to modify the data pointed to by the return pointer
- HRESULT AddString(_In_z_ const char *pString, _Outptr_result_z_ char **ppPointer);
- HRESULT AddData(_In_reads_(dwSize) const void *pData, _In_ uint32_t dwSize, _Outptr_ void **ppPointer);
-
- // Allocate behaves like a standard new - it will allocate memory, move m_dwSize. The caller is
- // expected to use the returned pointer
- void* Allocate(uint32_t dwSize);
-
- // Move data from the general heap and optional free memory
- HRESULT MoveData(_Inout_updates_bytes_(size) void **ppData, _In_ uint32_t size);
- HRESULT MoveString(_Inout_updates_z_(1) char **ppStringData);
- HRESULT MoveInterfaceParameters(_In_ uint32_t InterfaceCount, _Inout_updates_(1) SShaderBlock::SInterfaceParameter **ppInterfaces);
- HRESULT MoveEmptyDataBlock(_Inout_updates_(1) void **ppData, _In_ uint32_t size);
-
- bool IsInHeap(_In_ void *pData) const
- {
- return (pData >= m_pData && pData < (m_pData + m_dwBufferSize));
- }
-
- CEffectHeap() noexcept;
- ~CEffectHeap();
-};
-
-class CEffectReflection
-{
-public:
- // Single memory block support
- CEffectHeap m_Heap;
-};
-
-
-class CEffect : public ID3DX11Effect
-{
- friend struct SBaseBlock;
- friend struct SPassBlock;
- friend class CEffectLoader;
- friend struct SConstantBuffer;
- friend struct TSamplerVariable<TGlobalVariable<ID3DX11EffectSamplerVariable>>;
- friend struct TSamplerVariable<TVariable<TMember<ID3DX11EffectSamplerVariable>>>;
-
-protected:
-
- uint32_t m_RefCount;
- uint32_t m_Flags;
-
- // Private heap - all pointers should point into here
- CEffectHeap m_Heap;
-
- // Reflection object
- CEffectReflection *m_pReflection;
-
- // global variables in the effect (aka parameters)
- uint32_t m_VariableCount;
- SGlobalVariable *m_pVariables;
-
- // anonymous shader variables (one for every inline shader assignment)
- uint32_t m_AnonymousShaderCount;
- SAnonymousShader *m_pAnonymousShaders;
-
- // techniques within this effect (the actual data is located in each group)
- uint32_t m_TechniqueCount;
-
- // groups within this effect
- uint32_t m_GroupCount;
- SGroup *m_pGroups;
- SGroup *m_pNullGroup;
-
- uint32_t m_ShaderBlockCount;
- SShaderBlock *m_pShaderBlocks;
-
- uint32_t m_DepthStencilBlockCount;
- SDepthStencilBlock *m_pDepthStencilBlocks;
-
- uint32_t m_BlendBlockCount;
- SBlendBlock *m_pBlendBlocks;
-
- uint32_t m_RasterizerBlockCount;
- SRasterizerBlock *m_pRasterizerBlocks;
-
- uint32_t m_SamplerBlockCount;
- SSamplerBlock *m_pSamplerBlocks;
-
- uint32_t m_MemberDataCount;
- SMemberDataPointer *m_pMemberDataBlocks;
-
- uint32_t m_InterfaceCount;
- SInterface *m_pInterfaces;
-
- uint32_t m_CBCount;
- SConstantBuffer *m_pCBs;
-
- uint32_t m_StringCount;
- SString *m_pStrings;
-
- uint32_t m_ShaderResourceCount;
- SShaderResource *m_pShaderResources;
-
- uint32_t m_UnorderedAccessViewCount;
- SUnorderedAccessView *m_pUnorderedAccessViews;
-
- uint32_t m_RenderTargetViewCount;
- SRenderTargetView *m_pRenderTargetViews;
-
- uint32_t m_DepthStencilViewCount;
- SDepthStencilView *m_pDepthStencilViews;
-
- Timer m_LocalTimer;
-
- // temporary index variable for assignment evaluation
- uint32_t m_FXLIndex;
-
- ID3D11Device *m_pDevice;
- ID3D11DeviceContext *m_pContext;
- ID3D11ClassLinkage *m_pClassLinkage;
-
- // Master lists of reflection interfaces
- CEffectVectorOwner<SSingleElementType> m_pTypeInterfaces;
- CEffectVectorOwner<SMember> m_pMemberInterfaces;
-
- //////////////////////////////////////////////////////////////////////////
- // String & Type pooling
-
- typedef SType *LPSRUNTIMETYPE;
- static bool AreTypesEqual(const LPSRUNTIMETYPE &pType1, const LPSRUNTIMETYPE &pType2) { return (pType1->IsEqual(pType2)); }
- static bool AreStringsEqual(const LPCSTR &pStr1, const LPCSTR &pStr2) { return strcmp(pStr1, pStr2) == 0; }
-
- typedef CEffectHashTableWithPrivateHeap<SType *, AreTypesEqual> CTypeHashTable;
- typedef CEffectHashTableWithPrivateHeap<LPCSTR, AreStringsEqual> CStringHashTable;
-
- // These are used to pool types & type-related strings
- // until Optimize() is called
- CTypeHashTable *m_pTypePool;
- CStringHashTable *m_pStringPool;
- CDataBlockStore *m_pPooledHeap;
- // After Optimize() is called, the type/string pools should be deleted and all
- // remaining data should be migrated into the optimized type heap
- CEffectHeap *m_pOptimizedTypeHeap;
-
- // Pools a string or type and modifies the pointer
- void AddStringToPool(const char **ppString);
- void AddTypeToPool(SType **ppType);
-
- HRESULT OptimizeTypes(_Inout_ CPointerMappingTable *pMappingTable, _In_ bool Cloning = false);
-
-
- //////////////////////////////////////////////////////////////////////////
- // Runtime (performance critical)
-
- void ApplyShaderBlock(_In_ SShaderBlock *pBlock);
- bool ApplyRenderStateBlock(_In_ SBaseBlock *pBlock);
- bool ApplySamplerBlock(_In_ SSamplerBlock *pBlock);
- void ApplyPassBlock(_Inout_ SPassBlock *pBlock);
- bool EvaluateAssignment(_Inout_ SAssignment *pAssignment);
- bool ValidateShaderBlock(_Inout_ SShaderBlock* pBlock );
- bool ValidatePassBlock(_Inout_ SPassBlock* pBlock );
-
- //////////////////////////////////////////////////////////////////////////
- // Non-runtime functions (not performance critical)
-
- SGlobalVariable *FindLocalVariableByName(_In_z_ LPCSTR pVarName); // Looks in the current effect only
- SGlobalVariable *FindVariableByName(_In_z_ LPCSTR pVarName);
- SVariable *FindVariableByNameWithParsing(_In_z_ LPCSTR pVarName);
- SConstantBuffer *FindCB(_In_z_ LPCSTR pName);
- void ReplaceCBReference(_In_ SConstantBuffer *pOldBufferBlock, _In_ ID3D11Buffer *pNewBuffer); // Used by user-managed CBs
- void ReplaceSamplerReference(_In_ SSamplerBlock *pOldSamplerBlock, _In_ ID3D11SamplerState *pNewSampler);
- void AddRefAllForCloning( _In_ CEffect* pEffectSource );
- HRESULT CopyMemberInterfaces( _In_ CEffect* pEffectSource );
- HRESULT CopyStringPool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTable );
- HRESULT CopyTypePool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableTypes, _Inout_ CPointerMappingTable& mappingTableStrings );
- HRESULT CopyOptimizedTypePool( _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableTypes );
- HRESULT RecreateCBs();
- HRESULT FixupMemberInterface( _Inout_ SMember* pMember, _In_ CEffect* pEffectSource, _Inout_ CPointerMappingTable& mappingTableStrings );
-
- void ValidateIndex(_In_ uint32_t Elements);
-
- void IncrementTimer();
- void HandleLocalTimerRollover();
-
- friend struct SConstantBuffer;
-
-public:
- CEffect( uint32_t Flags = 0 ) noexcept;
- virtual ~CEffect();
- void ReleaseShaderRefection();
-
- // Initialize must be called after the effect is created
- HRESULT LoadEffect(_In_reads_bytes_(cbEffectBuffer) const void *pEffectBuffer, _In_ uint32_t cbEffectBuffer);
-
- // Once the effect is fully loaded, call BindToDevice to attach it to a device
- HRESULT BindToDevice(_In_ ID3D11Device *pDevice, _In_z_ LPCSTR srcName );
-
- Timer GetCurrentTime() const { return m_LocalTimer; }
-
- bool IsReflectionData(void *pData) const { return m_pReflection->m_Heap.IsInHeap(pData); }
- bool IsRuntimeData(void *pData) const { return m_Heap.IsInHeap(pData); }
-
- //////////////////////////////////////////////////////////////////////////
- // Public interface
-
- // IUnknown
- STDMETHOD(QueryInterface)(REFIID iid, _COM_Outptr_ LPVOID *ppv) override;
- STDMETHOD_(ULONG, AddRef)() override;
- STDMETHOD_(ULONG, Release)() override;
-
- // ID3DX11Effect
- STDMETHOD_(bool, IsValid)() override { return true; }
-
- STDMETHOD(GetDevice)(_Outptr_ ID3D11Device** ppDevice) override;
-
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_DESC *pDesc) override;
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetConstantBufferByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetConstantBufferByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetVariableByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetVariableByName)(_In_z_ LPCSTR Name) override;
- STDMETHOD_(ID3DX11EffectVariable*, GetVariableBySemantic)(_In_z_ LPCSTR Semantic) override;
-
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD_(ID3DX11EffectGroup*, GetGroupByIndex)(_In_ uint32_t Index) override;
- STDMETHOD_(ID3DX11EffectGroup*, GetGroupByName)(_In_z_ LPCSTR Name) override;
-
- STDMETHOD_(ID3D11ClassLinkage*, GetClassLinkage)() override;
-
- STDMETHOD(CloneEffect)(_In_ uint32_t Flags, _Outptr_ ID3DX11Effect** ppClonedEffect) override;
- STDMETHOD(Optimize)() override;
- STDMETHOD_(bool, IsOptimized)() override;
-
- //////////////////////////////////////////////////////////////////////////
- // New reflection helpers
-
- ID3DX11EffectType * CreatePooledSingleElementTypeInterface(_In_ SType *pType);
- ID3DX11EffectVariable * CreatePooledVariableMemberInterface(_In_ TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity,
- _In_ const SVariable *pMember,
- _In_ const UDataPointer Data, _In_ bool IsSingleElement, _In_ uint32_t Index);
-
-};
-
-}
-
-#pragma warning(pop)
diff --git a/lib/win32/Effects11/EffectAPI.cpp b/lib/win32/Effects11/EffectAPI.cpp
deleted file mode 100644
index 7b8e222ac5..0000000000
--- a/lib/win32/Effects11/EffectAPI.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectAPI.cpp
-//
-// Effect API entry point
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#include "pchfx.h"
-
-#include <memory>
-
-using namespace D3DX11Effects;
-
-//-------------------------------------------------------------------------------------
-
-struct handle_closer { void operator()(HANDLE h) { if (h) CloseHandle(h); } };
-
-typedef std::unique_ptr<void, handle_closer> ScopedHandle;
-
-inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }
-
-//-------------------------------------------------------------------------------------
-
-static HRESULT LoadBinaryFromFile( _In_z_ LPCWSTR pFileName, _Inout_ std::unique_ptr<uint8_t[]>& data, _Out_ uint32_t& size )
-{
- // open the file
-#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
- ScopedHandle hFile( safe_handle( CreateFile2( pFileName,
- GENERIC_READ,
- FILE_SHARE_READ,
- OPEN_EXISTING,
- nullptr ) ) );
-#else
- ScopedHandle hFile( safe_handle( CreateFileW( pFileName,
- GENERIC_READ,
- FILE_SHARE_READ,
- nullptr,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- nullptr ) ) );
-#endif
-
- if ( !hFile )
- {
- return HRESULT_FROM_WIN32( GetLastError() );
- }
-
- // Get the file size
- FILE_STANDARD_INFO fileInfo;
- if ( !GetFileInformationByHandleEx( hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo) ) )
- {
- return HRESULT_FROM_WIN32( GetLastError() );
- }
-
- // File is too big for 32-bit allocation or contains no data, so reject read
- if ( !fileInfo.EndOfFile.LowPart || fileInfo.EndOfFile.HighPart > 0 )
- {
- return E_FAIL;
- }
-
- // create enough space for the file data
- data.reset( new uint8_t[ fileInfo.EndOfFile.LowPart ] );
- if (!data)
- {
- return E_OUTOFMEMORY;
- }
-
- // read the data in
- DWORD BytesRead = 0;
- if (!ReadFile( hFile.get(),
- data.get(),
- fileInfo.EndOfFile.LowPart,
- &BytesRead,
- nullptr
- ))
- {
- return HRESULT_FROM_WIN32( GetLastError() );
- }
-
- if (BytesRead < fileInfo.EndOfFile.LowPart)
- {
- return E_FAIL;
- }
-
- size = BytesRead;
-
- return S_OK;
-}
-
-//--------------------------------------------------------------------------------------
-
-_Use_decl_annotations_
-HRESULT WINAPI D3DX11CreateEffectFromMemory(LPCVOID pData, SIZE_T DataLength, UINT FXFlags,
- ID3D11Device *pDevice, ID3DX11Effect **ppEffect, LPCSTR srcName )
-{
- if ( !pData || !DataLength || !pDevice || !ppEffect )
- return E_INVALIDARG;
-
- if ( DataLength > UINT32_MAX )
- return E_INVALIDARG;
-
- HRESULT hr = S_OK;
-
- // Note that pData must point to a compiled effect, not HLSL
- VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS) );
- VH( ((CEffect*)(*ppEffect))->LoadEffect(pData, static_cast<uint32_t>(DataLength) ) );
- VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, (srcName) ? srcName : "D3DX11Effect" ) );
-
-lExit:
- if (FAILED(hr))
- {
- SAFE_RELEASE(*ppEffect);
- }
- return hr;
-}
-
-//--------------------------------------------------------------------------------------
-
-_Use_decl_annotations_
-HRESULT WINAPI D3DX11CreateEffectFromFile( LPCWSTR pFileName, UINT FXFlags, ID3D11Device *pDevice, ID3DX11Effect **ppEffect )
-{
- if ( !pFileName || !pDevice || !ppEffect )
- return E_INVALIDARG;
-
- std::unique_ptr<uint8_t[]> fileData;
- uint32_t size;
- HRESULT hr = LoadBinaryFromFile( pFileName, fileData, size );
- if ( FAILED(hr) )
- return hr;
-
- hr = S_OK;
-
- // Note that pData must point to a compiled effect, not HLSL
- VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS) );
- VH( ((CEffect*)(*ppEffect))->LoadEffect( fileData.get(), size ) );
-
- // Create debug object name from input filename
- CHAR strFileA[MAX_PATH];
- int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE );
- if ( !result )
- {
- DPF(0, "Failed to load effect file due to WC to MB conversion failure: %ls", pFileName);
- hr = E_FAIL;
- goto lExit;
- }
-
- const CHAR* pstrName = strrchr( strFileA, '\\' );
- if (!pstrName)
- {
- pstrName = strFileA;
- }
- else
- {
- pstrName++;
- }
-
- VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, pstrName) );
-
-lExit:
- if (FAILED(hr))
- {
- SAFE_RELEASE(*ppEffect);
- }
- return hr;
-}
-
-
-//--------------------------------------------------------------------------------------
-
-_Use_decl_annotations_
-HRESULT D3DX11CompileEffectFromMemory( LPCVOID pData, SIZE_T DataLength, LPCSTR srcName,
- const D3D_SHADER_MACRO *pDefines, ID3DInclude *pInclude, UINT HLSLFlags, UINT FXFlags,
- ID3D11Device *pDevice, ID3DX11Effect **ppEffect, ID3DBlob **ppErrors )
-{
- if ( !pData || !DataLength || !pDevice || !ppEffect )
- return E_INVALIDARG;
-
- if ( FXFlags & D3DCOMPILE_EFFECT_CHILD_EFFECT )
- {
- DPF(0, "Effect pools (i.e. D3DCOMPILE_EFFECT_CHILD_EFFECT) not supported" );
- return E_NOTIMPL;
- }
-
- ID3DBlob *blob = nullptr;
- HRESULT hr = D3DCompile( pData, DataLength, srcName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors );
- if ( FAILED(hr) )
- {
- DPF(0, "D3DCompile of fx_5_0 profile failed: %08X", hr );
- return hr;
- }
-
- hr = S_OK;
-
- VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS ) );
- VH( ((CEffect*)(*ppEffect))->LoadEffect(blob->GetBufferPointer(), static_cast<uint32_t>( blob->GetBufferSize() ) ) );
- SAFE_RELEASE( blob );
-
- VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, (srcName) ? srcName : "D3DX11Effect" ) );
-
-lExit:
- if (FAILED(hr))
- {
- SAFE_RELEASE(*ppEffect);
- }
- return hr;
-}
-
-//--------------------------------------------------------------------------------------
-
-_Use_decl_annotations_
-HRESULT D3DX11CompileEffectFromFile( LPCWSTR pFileName,
- const D3D_SHADER_MACRO *pDefines, ID3DInclude *pInclude, UINT HLSLFlags, UINT FXFlags,
- ID3D11Device *pDevice, ID3DX11Effect **ppEffect, ID3DBlob **ppErrors )
-{
- if ( !pFileName || !pDevice || !ppEffect )
- return E_INVALIDARG;
-
- if ( FXFlags & D3DCOMPILE_EFFECT_CHILD_EFFECT )
- {
- DPF(0, "Effect pools (i.e. D3DCOMPILE_EFFECT_CHILD_EFFECT) not supported" );
- return E_NOTIMPL;
- }
-
- ID3DBlob *blob = nullptr;
-
-#if (D3D_COMPILER_VERSION >= 46) && ( !defined(WINAPI_FAMILY) || ( (WINAPI_FAMILY != WINAPI_FAMILY_APP) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) ) )
-
- HRESULT hr = D3DCompileFromFile( pFileName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors );
- if ( FAILED(hr) )
- {
- DPF(0, "D3DCompileFromFile of fx_5_0 profile failed %08X: %ls", hr, pFileName );
- return hr;
- }
-
-#else // D3D_COMPILER_VERSION < 46
-
- std::unique_ptr<uint8_t[]> fileData;
- uint32_t size;
- HRESULT hr = LoadBinaryFromFile( pFileName, fileData, size );
- if ( FAILED(hr) )
- {
- DPF(0, "Failed to load effect file %08X: %ls", hr, pFileName);
- return hr;
- }
-
- // Create debug object name from input filename
- CHAR strFileA[MAX_PATH];
- int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE );
- if ( !result )
- {
- DPF(0, "Failed to load effect file due to WC to MB conversion failure: %ls", pFileName);
- return E_FAIL;
- }
-
- const CHAR* pstrName = strrchr( strFileA, '\\' );
- if (!pstrName)
- {
- pstrName = strFileA;
- }
- else
- {
- pstrName++;
- }
-
- hr = D3DCompile( fileData.get(), size, pstrName, pDefines, pInclude, "", "fx_5_0", HLSLFlags, FXFlags, &blob, ppErrors );
- if ( FAILED(hr) )
- {
- DPF(0, "D3DCompile of fx_5_0 profile failed: %08X", hr );
- return hr;
- }
-
-#endif // D3D_COMPILER_VERSION
-
- if ( blob->GetBufferSize() > UINT32_MAX)
- {
- SAFE_RELEASE( blob );
- return E_FAIL;
- }
-
- hr = S_OK;
-
- VN( *ppEffect = new CEffect( FXFlags & D3DX11_EFFECT_RUNTIME_VALID_FLAGS ) );
- VH( ((CEffect*)(*ppEffect))->LoadEffect(blob->GetBufferPointer(), static_cast<uint32_t>( blob->GetBufferSize() ) ) );
- SAFE_RELEASE( blob );
-
-#if (D3D_COMPILER_VERSION >= 46) && ( !defined(WINAPI_FAMILY) || ( (WINAPI_FAMILY != WINAPI_FAMILY_APP) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) ) )
- // Create debug object name from input filename
- CHAR strFileA[MAX_PATH];
- int result = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, pFileName, -1, strFileA, MAX_PATH, nullptr, FALSE );
- if ( !result )
- {
- DPF(0, "Failed to load effect file due to WC to MB conversion failure: %ls", pFileName);
- hr = E_FAIL;
- goto lExit;
- }
-
- const CHAR* pstrName = strrchr( strFileA, '\\' );
- if (!pstrName)
- {
- pstrName = strFileA;
- }
- else
- {
- pstrName++;
- }
-#endif
-
- VH( ((CEffect*)(*ppEffect))->BindToDevice(pDevice, pstrName) );
-
-lExit:
- if (FAILED(hr))
- {
- SAFE_RELEASE(*ppEffect);
- }
- return hr;
-}
diff --git a/lib/win32/Effects11/EffectLoad.cpp b/lib/win32/Effects11/EffectLoad.cpp
deleted file mode 100644
index 40dfe0c019..0000000000
--- a/lib/win32/Effects11/EffectLoad.cpp
+++ /dev/null
@@ -1,4030 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectLoad.cpp
-//
-// Direct3D Effects file loading code
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#include "pchfx.h"
-
-#include "EffectStates11.h"
-
-#define PRIVATENEW new(m_BulkHeap)
-
-namespace D3DX11Effects
-{
-
-static LPCSTR g_szEffectLoadArea = "D3D11EffectLoader";
-
-SRasterizerBlock g_NullRasterizer;
-SDepthStencilBlock g_NullDepthStencil;
-SBlendBlock g_NullBlend;
-SShaderResource g_NullTexture;
-SInterface g_NullInterface;
-SUnorderedAccessView g_NullUnorderedAccessView;
-SRenderTargetView g_NullRenderTargetView;
-SDepthStencilView g_NullDepthStencilView;
-
-// these VTables must be setup in the proper order:
-// 1) SetShader
-// 2) SetConstantBuffers
-// 3) SetSamplers
-// 4) SetShaderResources
-// 5) CreateShader
-SD3DShaderVTable g_vtPS = {
- (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::PSSetShader,
- &ID3D11DeviceContext::PSSetConstantBuffers,
- &ID3D11DeviceContext::PSSetSamplers,
- &ID3D11DeviceContext::PSSetShaderResources,
- (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreatePixelShader
-};
-
-SD3DShaderVTable g_vtVS = {
- (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::VSSetShader,
- &ID3D11DeviceContext::VSSetConstantBuffers,
- &ID3D11DeviceContext::VSSetSamplers,
- &ID3D11DeviceContext::VSSetShaderResources,
- (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateVertexShader
-};
-
-SD3DShaderVTable g_vtGS = {
- (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::GSSetShader,
- &ID3D11DeviceContext::GSSetConstantBuffers,
- &ID3D11DeviceContext::GSSetSamplers,
- &ID3D11DeviceContext::GSSetShaderResources,
- (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateGeometryShader
-};
-
-SD3DShaderVTable g_vtHS = {
- (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::HSSetShader,
- &ID3D11DeviceContext::HSSetConstantBuffers,
- &ID3D11DeviceContext::HSSetSamplers,
- &ID3D11DeviceContext::HSSetShaderResources,
- (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateHullShader
-};
-
-SD3DShaderVTable g_vtDS = {
- (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::DSSetShader,
- &ID3D11DeviceContext::DSSetConstantBuffers,
- &ID3D11DeviceContext::DSSetSamplers,
- &ID3D11DeviceContext::DSSetShaderResources,
- (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateDomainShader
-};
-
-SD3DShaderVTable g_vtCS = {
- (void (__stdcall ID3D11DeviceContext::*)(ID3D11DeviceChild*, ID3D11ClassInstance*const*, uint32_t)) &ID3D11DeviceContext::CSSetShader,
- &ID3D11DeviceContext::CSSetConstantBuffers,
- &ID3D11DeviceContext::CSSetSamplers,
- &ID3D11DeviceContext::CSSetShaderResources,
- (HRESULT (__stdcall ID3D11Device::*)(const void *, size_t, ID3D11ClassLinkage*, ID3D11DeviceChild **)) &ID3D11Device::CreateComputeShader
-};
-
-SShaderBlock g_NullVS(&g_vtVS);
-SShaderBlock g_NullGS(&g_vtGS);
-SShaderBlock g_NullPS(&g_vtPS);
-SShaderBlock g_NullHS(&g_vtHS);
-SShaderBlock g_NullDS(&g_vtDS);
-SShaderBlock g_NullCS(&g_vtCS);
-
-D3D_SHADER_VARIABLE_TYPE GetSimpleParameterTypeFromObjectType(EObjectType ObjectType)
-{
- switch (ObjectType)
- {
- case EOT_String:
- return D3D_SVT_STRING;
- case EOT_Blend:
- return D3D_SVT_BLEND;
- case EOT_DepthStencil:
- return D3D_SVT_DEPTHSTENCIL;
- case EOT_Rasterizer:
- return D3D_SVT_RASTERIZER;
- case EOT_PixelShader:
- case EOT_PixelShader5:
- return D3D_SVT_PIXELSHADER;
- case EOT_VertexShader:
- case EOT_VertexShader5:
- return D3D_SVT_VERTEXSHADER;
- case EOT_GeometryShader:
- case EOT_GeometryShaderSO:
- case EOT_GeometryShader5:
- return D3D_SVT_GEOMETRYSHADER;
- case EOT_HullShader5:
- return D3D_SVT_HULLSHADER;
- case EOT_DomainShader5:
- return D3D_SVT_DOMAINSHADER;
- case EOT_ComputeShader5:
- return D3D_SVT_COMPUTESHADER;
- case EOT_RenderTargetView:
- return D3D_SVT_RENDERTARGETVIEW;
- case EOT_DepthStencilView:
- return D3D_SVT_DEPTHSTENCILVIEW;
- case EOT_Texture:
- case EOT_Texture1D:
- case EOT_Texture1DArray:
- case EOT_Texture2D:
- case EOT_Texture2DArray:
- case EOT_Texture2DMS:
- case EOT_Texture2DMSArray:
- case EOT_Texture3D:
- case EOT_TextureCube:
- case EOT_TextureCubeArray:
- return D3D_SVT_TEXTURE;
- case EOT_Buffer:
- return D3D_SVT_BUFFER;
- case EOT_Sampler:
- return D3D_SVT_SAMPLER;
- case EOT_ByteAddressBuffer:
- return D3D_SVT_BYTEADDRESS_BUFFER;
- case EOT_StructuredBuffer:
- return D3D_SVT_STRUCTURED_BUFFER;
- case EOT_RWTexture1D:
- return D3D_SVT_RWTEXTURE1D;
- case EOT_RWTexture1DArray:
- return D3D_SVT_RWTEXTURE1DARRAY;
- case EOT_RWTexture2D:
- return D3D_SVT_RWTEXTURE2D;
- case EOT_RWTexture2DArray:
- return D3D_SVT_RWTEXTURE2DARRAY;
- case EOT_RWTexture3D:
- return D3D_SVT_RWTEXTURE3D;
- case EOT_RWBuffer:
- return D3D_SVT_RWBUFFER;
- case EOT_RWByteAddressBuffer:
- return D3D_SVT_RWBYTEADDRESS_BUFFER;
- case EOT_RWStructuredBuffer:
- case EOT_RWStructuredBufferAlloc:
- case EOT_RWStructuredBufferConsume:
- return D3D_SVT_RWSTRUCTURED_BUFFER;
- case EOT_AppendStructuredBuffer:
- return D3D_SVT_APPEND_STRUCTURED_BUFFER;
- case EOT_ConsumeStructuredBuffer:
- return D3D_SVT_CONSUME_STRUCTURED_BUFFER;
- default:
- assert(0);
- }
- return D3D_SVT_VOID;
-}
-
-inline HRESULT VerifyPointer(uint32_t oBase, uint32_t dwSize, uint32_t dwMaxSize)
-{
- uint32_t dwAdd = oBase + dwSize;
- if (dwAdd < oBase || dwAdd > dwMaxSize)
- return E_FAIL;
- return S_OK;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// EffectHeap
-// A simple class which assists in adding data to a block of memory
-//////////////////////////////////////////////////////////////////////////
-
-CEffectHeap::CEffectHeap() noexcept :
- m_pData(nullptr),
- m_dwBufferSize(0),
- m_dwSize(0)
-{
-}
-
-CEffectHeap::~CEffectHeap()
-{
- SAFE_DELETE_ARRAY(m_pData);
-}
-
-uint32_t CEffectHeap::GetSize()
-{
- return m_dwSize;
-}
-
-HRESULT CEffectHeap::ReserveMemory(uint32_t dwSize)
-{
- HRESULT hr = S_OK;
-
- assert(!m_pData);
- assert(dwSize == AlignToPowerOf2(dwSize, c_DataAlignment));
-
- m_dwBufferSize = dwSize;
-
- VN( m_pData = new uint8_t[m_dwBufferSize] );
-
- // make sure that we have machine word alignment
- assert(m_pData == AlignToPowerOf2(m_pData, c_DataAlignment));
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT CEffectHeap::AddString(const char *pString, char **ppPointer)
-{
- size_t size = strlen(pString) + 1;
- assert( size <= 0xffffffff );
- return AddData(pString, (uint32_t)size, (void**) ppPointer);
-}
-
-// This data is forcibly aligned, so make sure you account for that in calculating heap size
-template <bool bCopyData>
-HRESULT CEffectHeap::AddDataInternal(_In_reads_bytes_(dwSize) const void *pData, _In_ uint32_t dwSize, _Outptr_ void **ppPointer)
-{
- CCheckedDword chkFinalSize( m_dwSize );
- uint32_t finalSize;
- HRESULT hr = S_OK;
-
- chkFinalSize += dwSize;
- chkFinalSize += c_DataAlignment; // account for alignment
-
- VHD( chkFinalSize.GetValue(&finalSize), "Overflow while adding data to Effect heap." );
-
- // align original value
- finalSize = AlignToPowerOf2(finalSize - c_DataAlignment, c_DataAlignment);
- VBD( finalSize <= m_dwBufferSize, "Overflow adding data to Effect heap." );
-
- *ppPointer = m_pData + m_dwSize;
- assert(*ppPointer == AlignToPowerOf2(*ppPointer, c_DataAlignment));
-
- if( bCopyData )
- {
- memcpy(*ppPointer, pData, dwSize);
- }
- m_dwSize = finalSize;
-
-lExit:
- if (FAILED(hr))
- *ppPointer = nullptr;
-
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT CEffectHeap::AddData(const void *pData, uint32_t dwSize, void **ppPointer)
-{
- return AddDataInternal<true>( pData, dwSize, ppPointer );
-}
-
-// Moves a string from the general heap to the private heap and modifies the pointer to
-// point to the new memory block.
-// The general heap is freed as a whole, so we don't worry about leaking the given string pointer.
-// This data is forcibly aligned, so make sure you account for that in calculating heap size
-_Use_decl_annotations_
-HRESULT CEffectHeap::MoveString(char **ppString)
-{
- HRESULT hr;
- char *pNewPointer;
-
- if (*ppString == nullptr)
- return S_OK;
-
- hr = AddString(*ppString, &pNewPointer);
- if ( SUCCEEDED(hr) )
- *ppString = pNewPointer;
-
- return hr;
-}
-
-// Allocates space but does not move data
-// The general heap is freed as a whole, so we don't worry about leaking the given string pointer.
-// This data is forcibly aligned, so make sure you account for that in calculating heap size
-_Use_decl_annotations_
-HRESULT CEffectHeap::MoveEmptyDataBlock(void **ppData, uint32_t size)
-{
- HRESULT hr;
- void *pNewPointer;
-
- hr = AddDataInternal<false>(*ppData, size, &pNewPointer);
-
- if (SUCCEEDED(hr))
- {
- *ppData = pNewPointer;
- if (size == 0)
- {
- // To help catch bugs, set zero-byte blocks to null. There's no real reason to do this
- *ppData = nullptr;
- }
- }
-
- return hr;
-}
-
-// Moves an array of SInterfaceParameters from the general heap to the private heap and modifies the pointer to
-// point to the new memory block.
-// The general heap is freed as a whole, so we don't worry about leaking the given string pointer.
-// This data is forcibly aligned, so make sure you account for that in calculating heap size
-_Use_decl_annotations_
-HRESULT CEffectHeap::MoveInterfaceParameters(uint32_t InterfaceCount, SShaderBlock::SInterfaceParameter **ppInterfaces)
-{
- HRESULT hr;
- SShaderBlock::SInterfaceParameter *pNewPointer;
-
- if (*ppInterfaces == nullptr)
- return S_OK;
-
- VBD( InterfaceCount <= D3D11_SHADER_MAX_INTERFACES, "Internal loading error: InterfaceCount > D3D11_SHADER_MAX_INTERFACES." );
- VH( AddData(*ppInterfaces, InterfaceCount * sizeof(SShaderBlock::SInterfaceParameter), (void**)&pNewPointer) );
-
- for( size_t i=0; i < InterfaceCount; i++ )
- {
- VH( MoveString( &pNewPointer[i].pName ) );
- }
-
- *ppInterfaces = pNewPointer;
-
-lExit:
- return hr;
-}
-
-
-// Moves data from the general heap to the private heap and modifies the pointer to
-// point to the new memory block
-// The general heap is freed as a whole, so we don't worry about leaking the given pointer.
-// This data is forcibly aligned, so make sure you account for that in calculating heap size
-_Use_decl_annotations_
-HRESULT CEffectHeap::MoveData(void **ppData, uint32_t size)
-{
- HRESULT hr;
- void *pNewPointer;
-
- hr = AddData(*ppData, size, &pNewPointer);
- if ( SUCCEEDED(hr) )
- {
- *ppData = pNewPointer;
- if (size == 0)
- {
- // To help catch bugs, set zero-byte blocks to null. There's no real reason to do this
- *ppData = nullptr;
- }
- }
-
- return hr;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// Load API
-//////////////////////////////////////////////////////////////////////////
-
-_Use_decl_annotations_
-HRESULT CEffect::LoadEffect(const void *pEffectBuffer, uint32_t cbEffectBuffer)
-{
- HRESULT hr = S_OK;
- CEffectLoader loader;
-
- if (!pEffectBuffer)
- {
- DPF(0, "%s: pEffectBuffer is nullptr.", g_szEffectLoadArea);
- VH( E_INVALIDARG );
- }
-
- VH( loader.LoadEffect(this, pEffectBuffer, cbEffectBuffer) );
-
-lExit:
- if( FAILED( hr ) )
- {
- // Release here because m_pShaderBlocks may still be in loader.m_BulkHeap if loading failed before we reallocated the memory
- ReleaseShaderRefection();
- }
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// CEffectLoader
-// A helper class which loads an effect
-//////////////////////////////////////////////////////////////////////////
-
-CEffectLoader::CEffectLoader() noexcept :
- m_pData(nullptr),
- m_pHeader(nullptr),
- m_Version(0),
- m_pEffect(nullptr),
- m_pReflection(nullptr),
- m_dwBufferSize(0),
- m_pOldVars(nullptr),
- m_pOldShaders(nullptr),
- m_pOldDS(nullptr),
- m_pOldAB(nullptr),
- m_pOldRS(nullptr),
- m_pOldCBs(nullptr),
- m_pOldSamplers(nullptr),
- m_OldInterfaceCount(0),
- m_pOldInterfaces(nullptr),
- m_pOldShaderResources(nullptr),
- m_pOldUnorderedAccessViews(nullptr),
- m_pOldRenderTargetViews(nullptr),
- m_pOldDepthStencilViews(nullptr),
- m_pOldStrings(nullptr),
- m_pOldMemberDataBlocks(nullptr),
- m_pvOldMemberInterfaces(nullptr),
- m_pOldGroups(nullptr),
- m_EffectMemory(0),
- m_ReflectionMemory(0)
-{
-}
-
-_Use_decl_annotations_
-HRESULT CEffectLoader::GetUnstructuredDataBlock(uint32_t offset, uint32_t *pdwSize, void **ppData)
-{
- HRESULT hr = S_OK;
- uint32_t *pBlockSize;
-
- VH( m_msUnstructured.ReadAtOffset(offset, sizeof(*pBlockSize), (void**) &pBlockSize ) );
- *pdwSize = *pBlockSize;
-
- VH( m_msUnstructured.Read(ppData, *pdwSize) );
-
-lExit:
- return hr;
-}
-
-// position in buffer is lost on error
-//
-// This function should be used in 1:1 conjunction with CEffectHeap::MoveString;
-// that is, any string added to the reflection heap with this function
-// must be relocated with MoveString at some point later on.
-_Use_decl_annotations_
-HRESULT CEffectLoader::GetStringAndAddToReflection(uint32_t offset, char **ppString)
-{
- HRESULT hr = S_OK;
- LPCSTR pName;
- size_t oldPos;
-
- if (offset == 0)
- {
- *ppString = nullptr;
- goto lExit;
- }
-
- oldPos = m_msUnstructured.GetPosition();
-
- VH( m_msUnstructured.ReadAtOffset(offset, &pName) );
- m_ReflectionMemory += AlignToPowerOf2( (uint32_t)strlen(pName) + 1, c_DataAlignment);
- *ppString = const_cast<char*>(pName);
-
- m_msUnstructured.Seek(oldPos);
-
-lExit:
- return hr;
-}
-
-// position in buffer is lost on error
-//
-// This function should be used in 1:1 conjunction with CEffectHeap::MoveInterfaceParameters;
-// that is, any array of parameters added to the reflection heap with this function
-// must be relocated with MoveInterfaceParameters at some point later on.
-_Use_decl_annotations_
-HRESULT CEffectLoader::GetInterfaceParametersAndAddToReflection( uint32_t InterfaceCount, uint32_t offset, SShaderBlock::SInterfaceParameter **ppInterfaces )
-{
- HRESULT hr = S_OK;
- SBinaryInterfaceInitializer* pInterfaceInitializer;
- size_t oldPos;
-
- if (offset == 0)
- {
- *ppInterfaces = nullptr;
- goto lExit;
- }
-
- oldPos = m_msUnstructured.GetPosition();
-
- VBD( InterfaceCount <= D3D11_SHADER_MAX_INTERFACES, "Internal loading error: InterfaceCount > D3D11_SHADER_MAX_INTERFACES." );
- m_ReflectionMemory += AlignToPowerOf2(InterfaceCount * sizeof(SShaderBlock::SInterfaceParameter), c_DataAlignment);
- assert( ppInterfaces != 0 );
- _Analysis_assume_( ppInterfaces != 0 );
- (*ppInterfaces) = PRIVATENEW SShaderBlock::SInterfaceParameter[InterfaceCount];
- VN( *ppInterfaces );
-
- VHD( m_msUnstructured.ReadAtOffset(offset, sizeof(SBinaryInterfaceInitializer) * InterfaceCount, (void**)&pInterfaceInitializer),
- "Invalid pEffectBuffer: cannot read interface initializer." );
-
- for( size_t i=0; i < InterfaceCount; i++ )
- {
- (*ppInterfaces)[i].Index = pInterfaceInitializer[i].ArrayIndex;
- VHD( m_msUnstructured.ReadAtOffset(pInterfaceInitializer[i].oInstanceName, const_cast<LPCSTR*>(&(*ppInterfaces)[i].pName)),
- "Invalid pEffectBuffer: cannot read interface initializer." );
- m_ReflectionMemory += AlignToPowerOf2( (uint32_t)strlen((*ppInterfaces)[i].pName) + 1, c_DataAlignment);
- }
-
- m_msUnstructured.Seek(oldPos);
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupCBPointer(_Inout_ SConstantBuffer **ppCB)
-{
- HRESULT hr = S_OK;
-
- size_t index = (SConstantBuffer*)*ppCB - m_pOldCBs;
- assert( index * sizeof(SConstantBuffer) == ((size_t)(SConstantBuffer*)*ppCB - (size_t)m_pOldCBs) );
- VBD( index < m_pEffect->m_CBCount, "Internal loading error: invalid constant buffer index." );
- *ppCB = (SConstantBuffer*)(m_pEffect->m_pCBs + index);
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupShaderPointer(_Inout_ SShaderBlock **ppShaderBlock)
-{
- HRESULT hr = S_OK;
- if (*ppShaderBlock != &g_NullVS && *ppShaderBlock != &g_NullGS && *ppShaderBlock != &g_NullPS &&
- *ppShaderBlock != &g_NullHS && *ppShaderBlock != &g_NullDS && *ppShaderBlock != &g_NullCS &&
- *ppShaderBlock != nullptr)
- {
- size_t index = *ppShaderBlock - m_pOldShaders;
- assert( index * sizeof(SShaderBlock) == ((size_t)*ppShaderBlock - (size_t)m_pOldShaders) );
- VBD( index < m_pEffect->m_ShaderBlockCount, "Internal loading error: invalid shader index." );
- *ppShaderBlock = m_pEffect->m_pShaderBlocks + index;
- }
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupDSPointer(_Inout_ SDepthStencilBlock **ppDSBlock)
-{
- HRESULT hr = S_OK;
- if (*ppDSBlock != &g_NullDepthStencil && *ppDSBlock != nullptr)
- {
- size_t index = *ppDSBlock - m_pOldDS;
- assert( index * sizeof(SDepthStencilBlock) == ((size_t)*ppDSBlock - (size_t)m_pOldDS) );
- VBD( index < m_pEffect->m_DepthStencilBlockCount, "Internal loading error: invalid depth-stencil state index." );
- *ppDSBlock = m_pEffect->m_pDepthStencilBlocks + index;
- }
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupABPointer(_Inout_ SBlendBlock **ppABBlock)
-{
- HRESULT hr = S_OK;
- if (*ppABBlock != &g_NullBlend && *ppABBlock != nullptr)
- {
- size_t index = *ppABBlock - m_pOldAB;
- assert( index * sizeof(SBlendBlock) == ((size_t)*ppABBlock - (size_t)m_pOldAB) );
- VBD( index < m_pEffect->m_BlendBlockCount, "Internal loading error: invalid blend state index." );
- *ppABBlock = m_pEffect->m_pBlendBlocks + index;
- }
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupRSPointer(_Inout_ SRasterizerBlock **ppRSBlock)
-{
- HRESULT hr = S_OK;
- if (*ppRSBlock != &g_NullRasterizer && *ppRSBlock != nullptr)
- {
- size_t index = *ppRSBlock - m_pOldRS;
- assert( index * sizeof(SRasterizerBlock) == ((size_t)*ppRSBlock - (size_t)m_pOldRS) );
- VBD( index < m_pEffect->m_RasterizerBlockCount, "Internal loading error: invalid rasterizer state index." );
- *ppRSBlock = m_pEffect->m_pRasterizerBlocks + index;
- }
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupSamplerPointer(_Inout_ SSamplerBlock **ppSampler)
-{
- HRESULT hr = S_OK;
- size_t index = *ppSampler - m_pOldSamplers;
- assert( index * sizeof(SSamplerBlock) == ((size_t)*ppSampler - (size_t)m_pOldSamplers) );
- VBD( index < m_pEffect->m_SamplerBlockCount, "Internal loading error: invalid sampler index." );
- *ppSampler = m_pEffect->m_pSamplerBlocks + index;
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupInterfacePointer(_Inout_ SInterface **ppInterface, _In_ bool CheckBackgroundInterfaces)
-{
- HRESULT hr = S_OK;
- if (*ppInterface != &g_NullInterface && *ppInterface != nullptr)
- {
- size_t index = *ppInterface - m_pOldInterfaces;
- if(index < m_OldInterfaceCount)
- {
- assert( index * sizeof(SInterface) == ((size_t)*ppInterface - (size_t)m_pOldInterfaces) );
- *ppInterface = m_pEffect->m_pInterfaces + index;
- }
- else
- {
- VBD( CheckBackgroundInterfaces, "Internal loading error: invalid interface pointer." );
- for( index=0; index < m_BackgroundInterfaces.GetSize(); index++ )
- {
- if( *ppInterface == m_BackgroundInterfaces[ (uint32_t)index ] )
- {
- // The interfaces m_BackgroundInterfaces were concatenated to the original ones in m_pEffect->m_pInterfaces
- *ppInterface = m_pEffect->m_pInterfaces + (m_OldInterfaceCount + index);
- break;
- }
- }
- VBD( index < m_BackgroundInterfaces.GetSize(), "Internal loading error: invalid interface pointer." );
- }
- }
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupShaderResourcePointer(_Inout_ SShaderResource **ppResource)
-{
- HRESULT hr = S_OK;
- if (*ppResource != &g_NullTexture && *ppResource != nullptr)
- {
- size_t index = *ppResource - m_pOldShaderResources;
- assert( index * sizeof(SShaderResource) == ((size_t)*ppResource - (size_t)m_pOldShaderResources) );
-
- // could be a TBuffer or a texture; better check first
- if (index < m_pEffect->m_ShaderResourceCount)
- {
- *ppResource = m_pEffect->m_pShaderResources + index;
- }
- else
- {
- // if this is a TBuffer, then the shader resource pointer
- // actually points into a SConstantBuffer's TBuffer field
- index = (SConstantBuffer*)*ppResource - (SConstantBuffer*)&m_pOldCBs->TBuffer;
- assert( index * sizeof(SConstantBuffer) == ((size_t)(SConstantBuffer*)*ppResource - (size_t)(SConstantBuffer*)&m_pOldCBs->TBuffer) );
- VBD( index < m_pEffect->m_CBCount, "Internal loading error: invalid SRV index." );
- *ppResource = &m_pEffect->m_pCBs[index].TBuffer;
- }
- }
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupUnorderedAccessViewPointer(_Inout_ SUnorderedAccessView **ppUnorderedAccessView)
-{
- HRESULT hr = S_OK;
- if (*ppUnorderedAccessView != &g_NullUnorderedAccessView && *ppUnorderedAccessView != nullptr)
- {
- size_t index = *ppUnorderedAccessView - m_pOldUnorderedAccessViews;
- assert( index * sizeof(SUnorderedAccessView) == ((size_t)*ppUnorderedAccessView - (size_t)m_pOldUnorderedAccessViews) );
-
- VBD( index < m_pEffect->m_UnorderedAccessViewCount, "Internal loading error: invalid UAV index." );
- *ppUnorderedAccessView = m_pEffect->m_pUnorderedAccessViews + index;
- }
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupRenderTargetViewPointer(_Inout_ SRenderTargetView **ppRenderTargetView)
-{
- HRESULT hr = S_OK;
- if (*ppRenderTargetView != &g_NullRenderTargetView && *ppRenderTargetView != nullptr)
- {
- size_t index = *ppRenderTargetView - m_pOldRenderTargetViews;
- assert( index * sizeof(SRenderTargetView) == ((size_t)*ppRenderTargetView - (size_t)m_pOldRenderTargetViews) );
- VBD( index < m_pEffect->m_RenderTargetViewCount, "Internal loading error: invalid RTV index." );
- *ppRenderTargetView = m_pEffect->m_pRenderTargetViews + index;
- }
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupDepthStencilViewPointer(_Inout_ SDepthStencilView **ppDepthStencilView)
-{
- HRESULT hr = S_OK;
- if (*ppDepthStencilView != &g_NullDepthStencilView && *ppDepthStencilView != nullptr)
- {
- size_t index = *ppDepthStencilView - m_pOldDepthStencilViews;
- assert( index * sizeof(SDepthStencilView) == ((size_t)*ppDepthStencilView - (size_t)m_pOldDepthStencilViews) );
- VBD( index < m_pEffect->m_DepthStencilViewCount, "Internal loading error: invalid DSV index." );
- *ppDepthStencilView = m_pEffect->m_pDepthStencilViews + index;
- }
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupStringPointer(_Inout_ SString **ppString)
-{
- HRESULT hr = S_OK;
- size_t index = *ppString - m_pOldStrings;
- assert( index * sizeof(SString) == ((size_t)*ppString - (size_t)m_pOldStrings) );
- VBD(index < m_pEffect->m_StringCount, "Internal loading error: invalid string index." );
- *ppString = m_pEffect->m_pStrings + index;
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupMemberDataPointer(_Inout_ SMemberDataPointer **ppMemberData)
-{
- HRESULT hr = S_OK;
- size_t index = *ppMemberData - m_pOldMemberDataBlocks;
- assert( index * sizeof(SMemberDataPointer) == ((size_t)*ppMemberData - (size_t)m_pOldMemberDataBlocks) );
- VBD( index < m_pEffect->m_MemberDataCount, "Internal loading error: invalid member block index." );
- *ppMemberData = m_pEffect->m_pMemberDataBlocks + index;
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupVariablePointer(_Inout_ SGlobalVariable **ppVar)
-{
- HRESULT hr = S_OK;
- size_t index = *ppVar - m_pOldVars;
-
- if( index < m_pEffect->m_VariableCount )
- {
- assert( index * sizeof(SGlobalVariable) == ((size_t)*ppVar - (size_t)m_pOldVars) );
- *ppVar = m_pEffect->m_pVariables + index;
- }
- else if( m_pvOldMemberInterfaces )
- {
- // When cloning, m_pvOldMemberInterfaces may be non-nullptr, and *ppVar may point to a variable in it.
- const size_t Members = m_pvOldMemberInterfaces->GetSize();
- for( index=0; index < Members; index++ )
- {
- if( (ID3DX11EffectVariable*)(*m_pvOldMemberInterfaces)[ (uint32_t)index] == (ID3DX11EffectVariable*)*ppVar )
- {
- break;
- }
- }
- VBD( index < Members, "Internal loading error: invalid member pointer." );
- *ppVar = (SGlobalVariable*)m_pEffect->m_pMemberInterfaces[ (uint32_t)index];
- }
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::FixupGroupPointer(_Inout_ SGroup **ppGroup)
-{
- HRESULT hr = S_OK;
- if( *ppGroup != nullptr )
- {
- size_t index = *ppGroup - m_pOldGroups;
- assert( index * sizeof(SGroup) == ((size_t)*ppGroup - (size_t)m_pOldGroups) );
- VBD( index < m_pEffect->m_GroupCount, "Internal loading error: invalid group index." );
- *ppGroup = m_pEffect->m_pGroups + index;
- }
-lExit:
- return hr;
-}
-
-static HRESULT GetEffectVersion( _In_ uint32_t effectFileTag, _Out_ DWORD* pVersion )
-{
- assert( pVersion != nullptr );
- if( !pVersion )
- return E_FAIL;
-
- for( size_t i = 0; i < _countof(g_EffectVersions); i++ )
- {
- if( g_EffectVersions[i].m_Tag == effectFileTag )
- {
- *pVersion = g_EffectVersions[i].m_Version;
- return S_OK;
- }
- }
-
- return E_FAIL;
-}
-
-_Use_decl_annotations_
-HRESULT CEffectLoader::LoadEffect(CEffect *pEffect, const void *pEffectBuffer, uint32_t cbEffectBuffer)
-{
-
- HRESULT hr = S_OK;
- uint32_t i, varSize, cMemberDataBlocks;
- CCheckedDword chkVariables = 0;
-
- // Used for cloning
- m_pvOldMemberInterfaces = nullptr;
-
- m_BulkHeap.EnableAlignment();
-
- assert(pEffect && pEffectBuffer);
- m_pEffect = pEffect;
- m_EffectMemory = m_ReflectionMemory = 0;
-
- VN( m_pEffect->m_pReflection = new CEffectReflection() );
- m_pReflection = m_pEffect->m_pReflection;
-
- // Begin effect load
- VN( m_pEffect->m_pTypePool = new CEffect::CTypeHashTable );
- VN( m_pEffect->m_pStringPool = new CEffect::CStringHashTable );
- VN( m_pEffect->m_pPooledHeap = new CDataBlockStore );
- m_pEffect->m_pPooledHeap->EnableAlignment();
- m_pEffect->m_pTypePool->SetPrivateHeap(m_pEffect->m_pPooledHeap);
- m_pEffect->m_pStringPool->SetPrivateHeap(m_pEffect->m_pPooledHeap);
-
- VH( m_pEffect->m_pTypePool->AutoGrow() );
- VH( m_pEffect->m_pStringPool->AutoGrow() );
-
- // Load from blob
- m_pData = (uint8_t*)pEffectBuffer;
- m_dwBufferSize = cbEffectBuffer;
-
- VH( m_msStructured.SetData(m_pData, m_dwBufferSize) );
-
- // At this point, we assume that the blob is valid
- VHD( m_msStructured.Read((void**) &m_pHeader, sizeof(*m_pHeader)), "pEffectBuffer is too small." );
-
- // Verify the version
- if( FAILED( hr = GetEffectVersion( m_pHeader->Tag, &m_Version ) ) )
- {
- DPF(0, "Effect version is unrecognized. This runtime supports fx_5_0 to %s.", g_EffectVersions[_countof(g_EffectVersions)-1].m_pName );
- VH( hr );
- }
-
- if( m_pHeader->RequiresPool() || m_pHeader->Pool.cObjectVariables > 0 || m_pHeader->Pool.cNumericVariables > 0 )
- {
- DPF(0, "Effect11 does not support EffectPools." );
- VH( E_FAIL );
- }
-
- // Get shader block count
- VBD( m_pHeader->cInlineShaders <= m_pHeader->cTotalShaders, "Invalid Effect header: cInlineShaders > cTotalShaders." );
-
- // Make sure the counts for the Effect don't overflow
- chkVariables = m_pHeader->Effect.cObjectVariables;
- chkVariables += m_pHeader->Effect.cNumericVariables;
- chkVariables += m_pHeader->cInterfaceVariables;
- chkVariables *= sizeof(SGlobalVariable);
- VH( chkVariables.GetValue(&varSize) );
-
- // Make sure the counts for the SMemberDataPointers don't overflow
- chkVariables = m_pHeader->cClassInstanceElements;
- chkVariables += m_pHeader->cBlendStateBlocks;
- chkVariables += m_pHeader->cRasterizerStateBlocks;
- chkVariables += m_pHeader->cDepthStencilBlocks;
- chkVariables += m_pHeader->cSamplers;
- chkVariables += m_pHeader->Effect.cCBs; // Buffer (for CBuffers and TBuffers)
- chkVariables += m_pHeader->Effect.cCBs; // SRV (for TBuffers)
- VHD( chkVariables.GetValue(&cMemberDataBlocks), "Overflow: too many Effect variables." );
-
- // Allocate effect resources
- VN( m_pEffect->m_pCBs = PRIVATENEW SConstantBuffer[m_pHeader->Effect.cCBs] );
- VN( m_pEffect->m_pDepthStencilBlocks = PRIVATENEW SDepthStencilBlock[m_pHeader->cDepthStencilBlocks] );
- VN( m_pEffect->m_pRasterizerBlocks = PRIVATENEW SRasterizerBlock[m_pHeader->cRasterizerStateBlocks] );
- VN( m_pEffect->m_pBlendBlocks = PRIVATENEW SBlendBlock[m_pHeader->cBlendStateBlocks] );
- VN( m_pEffect->m_pSamplerBlocks = PRIVATENEW SSamplerBlock[m_pHeader->cSamplers] );
-
- // we allocate raw bytes for variables because they are polymorphic types that need to be placement new'ed
- VN( m_pEffect->m_pVariables = (SGlobalVariable *)PRIVATENEW uint8_t[varSize] );
- VN( m_pEffect->m_pAnonymousShaders = PRIVATENEW SAnonymousShader[m_pHeader->cInlineShaders] );
-
- VN( m_pEffect->m_pGroups = PRIVATENEW SGroup[m_pHeader->cGroups] );
- VN( m_pEffect->m_pShaderBlocks = PRIVATENEW SShaderBlock[m_pHeader->cTotalShaders] );
- VN( m_pEffect->m_pStrings = PRIVATENEW SString[m_pHeader->cStrings] );
- VN( m_pEffect->m_pShaderResources = PRIVATENEW SShaderResource[m_pHeader->cShaderResources] );
- VN( m_pEffect->m_pUnorderedAccessViews = PRIVATENEW SUnorderedAccessView[m_pHeader->cUnorderedAccessViews] );
- VN( m_pEffect->m_pInterfaces = PRIVATENEW SInterface[m_pHeader->cInterfaceVariableElements] );
- VN( m_pEffect->m_pMemberDataBlocks = PRIVATENEW SMemberDataPointer[cMemberDataBlocks] );
- VN( m_pEffect->m_pRenderTargetViews = PRIVATENEW SRenderTargetView[m_pHeader->cRenderTargetViews] );
- VN( m_pEffect->m_pDepthStencilViews = PRIVATENEW SDepthStencilView[m_pHeader->cDepthStencilViews] );
-
- uint32_t oStructured = m_pHeader->cbUnstructured + sizeof(SBinaryHeader5);
- VHD( m_msStructured.Seek(oStructured), "Invalid pEffectBuffer: Missing structured data block." );
- VH( m_msUnstructured.SetData(m_pData + sizeof(SBinaryHeader5), oStructured - sizeof(SBinaryHeader5)) );
-
- VH( LoadCBs() );
- VH( LoadObjectVariables() );
- VH( LoadInterfaceVariables() );
- VH( LoadGroups() );
-
- // Build shader dependencies
- for (i=0; i<m_pEffect->m_ShaderBlockCount; i++)
- {
- VH( BuildShaderBlock(&m_pEffect->m_pShaderBlocks[i]) );
- }
-
- for( size_t iGroup=0; iGroup<m_pHeader->cGroups; iGroup++ )
- {
- SGroup *pGroup = &m_pEffect->m_pGroups[iGroup];
- pGroup->HasDependencies = false;
-
- for( size_t iTechnique=0; iTechnique < pGroup->TechniqueCount; iTechnique++ )
- {
- STechnique* pTech = &pGroup->pTechniques[iTechnique];
- pTech->HasDependencies = false;
-
- for( size_t iPass=0; iPass < pTech->PassCount; iPass++ )
- {
- SPassBlock *pPass = &pTech->pPasses[iPass];
-
- pTech->HasDependencies |= pPass->CheckDependencies();
- }
- pGroup->HasDependencies |= pTech->HasDependencies;
- }
- }
-
- VH( InitializeReflectionDataAndMoveStrings() );
- VH( ReallocateReflectionData() );
- VH( ReallocateEffectData() );
-
- VB( m_pReflection->m_Heap.GetSize() == m_ReflectionMemory );
-
- // Verify that all of the various block/variable types were loaded
- VBD( m_pEffect->m_VariableCount == (m_pHeader->Effect.cObjectVariables + m_pHeader->Effect.cNumericVariables + m_pHeader->cInterfaceVariables), "Internal loading error: mismatched variable count." );
- VBD( m_pEffect->m_ShaderBlockCount == m_pHeader->cTotalShaders, "Internal loading error: mismatched shader block count." );
- VBD( m_pEffect->m_AnonymousShaderCount == m_pHeader->cInlineShaders, "Internal loading error: mismatched anonymous variable count." );
- VBD( m_pEffect->m_ShaderResourceCount == m_pHeader->cShaderResources, "Internal loading error: mismatched SRV count." );
- VBD( m_pEffect->m_InterfaceCount == m_pHeader->cInterfaceVariableElements + m_BackgroundInterfaces.GetSize(), "Internal loading error: mismatched interface count." );
- VBD( m_pEffect->m_UnorderedAccessViewCount == m_pHeader->cUnorderedAccessViews, "Internal loading error: mismatched UAV count." );
- VBD( m_pEffect->m_MemberDataCount == cMemberDataBlocks, "Internal loading error: mismatched member data block count." );
- VBD( m_pEffect->m_RenderTargetViewCount == m_pHeader->cRenderTargetViews, "Internal loading error: mismatched RTV count." );
- VBD( m_pEffect->m_DepthStencilViewCount == m_pHeader->cDepthStencilViews, "Internal loading error: mismatched DSV count." );
- VBD( m_pEffect->m_DepthStencilBlockCount == m_pHeader->cDepthStencilBlocks, "Internal loading error: mismatched depth-stencil state count." );
- VBD( m_pEffect->m_BlendBlockCount == m_pHeader->cBlendStateBlocks, "Internal loading error: mismatched blend state count." );
- VBD( m_pEffect->m_RasterizerBlockCount == m_pHeader->cRasterizerStateBlocks, "Internal loading error: mismatched rasterizer state count." );
- VBD( m_pEffect->m_SamplerBlockCount == m_pHeader->cSamplers, "Internal loading error: mismatched sampler count." );
- VBD( m_pEffect->m_StringCount == m_pHeader->cStrings, "Internal loading error: mismatched string count." );
-
- // Uncomment if you really need this information
- // DPF(0, "Effect heap size: %d, reflection heap size: %d, allocations avoided: %d", m_EffectMemory, m_ReflectionMemory, m_BulkHeap.m_cAllocations);
-
-lExit:
- return hr;
-}
-
-// position in buffer is lost on error
-_Use_decl_annotations_
-HRESULT CEffectLoader::LoadStringAndAddToPool(char **ppString, uint32_t dwOffset)
-{
- HRESULT hr = S_OK;
- char *pName;
- uint32_t hash;
- size_t oldPos;
- CEffect::CStringHashTable::CIterator iter;
- uint32_t len;
-
- if (dwOffset == 0)
- {
- *ppString = nullptr;
- goto lExit;
- }
-
- oldPos = m_msUnstructured.GetPosition();
-
- VHD( m_msUnstructured.ReadAtOffset(dwOffset, (LPCSTR *) &pName), "Invalid pEffectBuffer: cannot read string." );
- len = (uint32_t)strlen(pName);
- hash = ComputeHash((uint8_t *)pName, len);
- if (FAILED(m_pEffect->m_pStringPool->FindValueWithHash(pName, hash, &iter)))
- {
- assert( m_pEffect->m_pPooledHeap != 0 );
- _Analysis_assume_( m_pEffect->m_pPooledHeap != 0 );
- VN( (*ppString) = new(*m_pEffect->m_pPooledHeap) char[len + 1] );
- memcpy(*ppString, pName, len + 1);
- VHD( m_pEffect->m_pStringPool->AddValueWithHash(*ppString, hash), "Internal loading error: failed to add string to pool." );
- }
- else
- {
- *ppString = const_cast<LPSTR>(iter.GetData());
- }
-
- m_msUnstructured.Seek(oldPos);
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT CEffectLoader::LoadTypeAndAddToPool(SType **ppType, uint32_t dwOffset)
-{
- HRESULT hr = S_OK;
- SBinaryType *psType;
- SBinaryNumericType *pNumericType;
- EObjectType *pObjectType;
- uint32_t cMembers, iMember, cInterfaces;
- uint32_t oBaseClassType;
- SType temporaryType;
- CEffect::CTypeHashTable::CIterator iter;
- uint8_t *pHashBuffer;
- uint32_t hash;
- SVariable *pTempMembers = nullptr;
-
- m_HashBuffer.Empty();
-
- VHD( m_msUnstructured.ReadAtOffset(dwOffset, sizeof(SBinaryType), (void**) &psType), "Invalid pEffectBuffer: cannot read type." );
- VHD( LoadStringAndAddToPool(&temporaryType.pTypeName, psType->oTypeName), "Invalid pEffectBuffer: cannot read type name." );
- temporaryType.VarType = psType->VarType;
- temporaryType.Elements = psType->Elements;
- temporaryType.TotalSize = psType->TotalSize;
- temporaryType.Stride = psType->Stride;
- temporaryType.PackedSize = psType->PackedSize;
-
- // sanity check elements, size, stride, etc.
- uint32_t cElements = std::max<uint32_t>(1, temporaryType.Elements);
- VBD( cElements * temporaryType.Stride == AlignToPowerOf2(temporaryType.TotalSize, SType::c_RegisterSize), "Invalid pEffectBuffer: invalid type size." );
- VBD( temporaryType.Stride % SType::c_RegisterSize == 0, "Invalid pEffectBuffer: invalid type stride." );
- VBD( temporaryType.PackedSize <= temporaryType.TotalSize && temporaryType.PackedSize % cElements == 0, "Invalid pEffectBuffer: invalid type packed size." );
-
- switch(temporaryType.VarType)
- {
- case EVT_Object:
- VHD( m_msUnstructured.Read((void**) &pObjectType, sizeof(uint32_t)), "Invalid pEffectBuffer: cannot read object type." );
- temporaryType.ObjectType = *pObjectType;
- VBD( temporaryType.VarType > EVT_Invalid && temporaryType.VarType < EVT_Count, "Invalid pEffectBuffer: invalid object type." );
-
- VN( pHashBuffer = m_HashBuffer.AddRange(sizeof(temporaryType.VarType) + sizeof(temporaryType.Elements) +
- sizeof(temporaryType.pTypeName) + sizeof(temporaryType.ObjectType)) );
- memcpy(pHashBuffer, &temporaryType.VarType, sizeof(temporaryType.VarType));
- pHashBuffer += sizeof(temporaryType.VarType);
- memcpy(pHashBuffer, &temporaryType.Elements, sizeof(temporaryType.Elements));
- pHashBuffer += sizeof(temporaryType.Elements);
- memcpy(pHashBuffer, &temporaryType.pTypeName, sizeof(temporaryType.pTypeName));
- pHashBuffer += sizeof(temporaryType.pTypeName);
- memcpy(pHashBuffer, &temporaryType.ObjectType, sizeof(temporaryType.ObjectType));
- break;
-
- case EVT_Interface:
- temporaryType.InterfaceType = nullptr;
-
- VN( pHashBuffer = m_HashBuffer.AddRange(sizeof(temporaryType.VarType) + sizeof(temporaryType.Elements) +
- sizeof(temporaryType.pTypeName) + sizeof(temporaryType.ObjectType)) );
- memcpy(pHashBuffer, &temporaryType.VarType, sizeof(temporaryType.VarType));
- pHashBuffer += sizeof(temporaryType.VarType);
- memcpy(pHashBuffer, &temporaryType.Elements, sizeof(temporaryType.Elements));
- pHashBuffer += sizeof(temporaryType.Elements);
- memcpy(pHashBuffer, &temporaryType.pTypeName, sizeof(temporaryType.pTypeName));
- pHashBuffer += sizeof(temporaryType.pTypeName);
- memcpy(pHashBuffer, &temporaryType.ObjectType, sizeof(temporaryType.ObjectType));
- break;
-
- case EVT_Numeric:
- VHD( m_msUnstructured.Read((void**) &pNumericType, sizeof(SBinaryNumericType)), "Invalid pEffectBuffer: cannot read numeric type." );
- temporaryType.NumericType = *pNumericType;
- VBD( temporaryType.NumericType.Rows >= 1 && temporaryType.NumericType.Rows <= 4 &&
- temporaryType.NumericType.Columns >= 1 && temporaryType.NumericType.Columns <= 4 &&
- temporaryType.NumericType.NumericLayout != ENL_Invalid && temporaryType.NumericType.NumericLayout < ENL_Count &&
- temporaryType.NumericType.ScalarType > EST_Invalid && temporaryType.NumericType.ScalarType < EST_Count,
- "Invalid pEffectBuffer: invalid numeric type.");
-
- if (temporaryType.NumericType.NumericLayout != ENL_Matrix)
- {
- VBD( temporaryType.NumericType.IsColumnMajor == false, "Invalid pEffectBuffer: only matricies can be column major." );
- }
-
- VN( pHashBuffer = m_HashBuffer.AddRange(sizeof(temporaryType.VarType) + sizeof(temporaryType.Elements) +
- sizeof(temporaryType.pTypeName) + sizeof(temporaryType.NumericType)) );
- memcpy(pHashBuffer, &temporaryType.VarType, sizeof(temporaryType.VarType));
- pHashBuffer += sizeof(temporaryType.VarType);
- memcpy(pHashBuffer, &temporaryType.Elements, sizeof(temporaryType.Elements));
- pHashBuffer += sizeof(temporaryType.Elements);
- memcpy(pHashBuffer, &temporaryType.pTypeName, sizeof(temporaryType.pTypeName));
- pHashBuffer += sizeof(temporaryType.pTypeName);
- memcpy(pHashBuffer, &temporaryType.NumericType, sizeof(temporaryType.NumericType));
- break;
-
- case EVT_Struct:
- VHD( m_msUnstructured.Read(&cMembers), "Invalid pEffectBuffer: cannot read struct." );
-
- temporaryType.StructType.Members = cMembers;
-
- VN( pTempMembers = new SVariable[cMembers] );
- temporaryType.StructType.pMembers = pTempMembers;
-
- // read up all of the member descriptors at once
- SBinaryType::SBinaryMember *psMember;
- VHD( m_msUnstructured.Read((void**) &psMember, cMembers * sizeof(*psMember)), "Invalid pEffectBuffer: cannot read struct members." );
-
- {
- // Determine if this type implements an interface
- VHD( m_msUnstructured.Read(&oBaseClassType), "Invalid pEffectBuffer: cannot read base class type." );
- VHD( m_msUnstructured.Read(&cInterfaces), "Invalid pEffectBuffer: cannot read interfaces." );
- if( cInterfaces > 0 )
- {
- temporaryType.StructType.ImplementsInterface = 1;
- temporaryType.StructType.HasSuperClass = ( oBaseClassType > 0 ) ? 1 : 0;
- }
- else if( oBaseClassType > 0 )
- {
- // Get parent type and copy its ImplementsInterface
- SType* pBaseClassType;
- VH( LoadTypeAndAddToPool(&pBaseClassType, oBaseClassType) );
- temporaryType.StructType.ImplementsInterface = pBaseClassType->StructType.ImplementsInterface;
- temporaryType.StructType.HasSuperClass = 1;
- }
- // Read (and ignore) the interface types
- uint32_t *poInterface;
- VHD( m_msUnstructured.Read((void**) &poInterface, cInterfaces * sizeof(poInterface)), "Invalid pEffectBuffer: cannot read interface types." );
- }
-
- uint32_t totalSize;
- totalSize = 0;
- for (iMember=0; iMember<cMembers; iMember++)
- {
- SVariable *pMember;
-
- pMember = temporaryType.StructType.pMembers + iMember;
-
- VBD( psMember[iMember].Offset == totalSize ||
- psMember[iMember].Offset == AlignToPowerOf2(totalSize, SType::c_RegisterSize),
- "Internal loading error: invalid member offset." );
-
- pMember->Data.Offset = psMember[iMember].Offset;
-
- VH( LoadTypeAndAddToPool(&pMember->pType, psMember[iMember].oType) );
- VH( LoadStringAndAddToPool(&pMember->pName, psMember[iMember].oName) );
- VH( LoadStringAndAddToPool(&pMember->pSemantic, psMember[iMember].oSemantic) );
-
- totalSize = psMember[iMember].Offset + pMember->pType->TotalSize;
- }
- VBD( AlignToPowerOf2(totalSize, SType::c_RegisterSize) == temporaryType.Stride, "Internal loading error: invlid type size." );
-
- VN( pHashBuffer = m_HashBuffer.AddRange(sizeof(temporaryType.VarType) + sizeof(temporaryType.Elements) +
- sizeof(temporaryType.pTypeName) + sizeof(temporaryType.StructType.Members) + cMembers * sizeof(SVariable)) );
-
- memcpy(pHashBuffer, &temporaryType.VarType, sizeof(temporaryType.VarType));
- pHashBuffer += sizeof(temporaryType.VarType);
- memcpy(pHashBuffer, &temporaryType.Elements, sizeof(temporaryType.Elements));
- pHashBuffer += sizeof(temporaryType.Elements);
- memcpy(pHashBuffer, &temporaryType.pTypeName, sizeof(temporaryType.pTypeName));
- pHashBuffer += sizeof(temporaryType.pTypeName);
- memcpy(pHashBuffer, &temporaryType.StructType.Members, sizeof(temporaryType.StructType.Members));
- pHashBuffer += sizeof(temporaryType.StructType.Members);
- memcpy(pHashBuffer, temporaryType.StructType.pMembers, cMembers * sizeof(SVariable));
- break;
-
- default:
- assert(0);
- VHD( E_FAIL, "Internal loading error: invalid variable type." );
- }
-
- hash = ComputeHash(&m_HashBuffer[0], m_HashBuffer.GetSize());
- if (FAILED(m_pEffect->m_pTypePool->FindValueWithHash(&temporaryType, hash, &iter)))
- {
- assert( m_pEffect->m_pPooledHeap != nullptr );
-
- // allocate real member array, if necessary
- if (temporaryType.VarType == EVT_Struct)
- {
- VN( temporaryType.StructType.pMembers = new(*m_pEffect->m_pPooledHeap) SVariable[temporaryType.StructType.Members] );
- memcpy(temporaryType.StructType.pMembers, pTempMembers, temporaryType.StructType.Members * sizeof(SVariable));
- }
-
- // allocate real type
- VN( (*ppType) = new(*m_pEffect->m_pPooledHeap) SType );
- memcpy(*ppType, &temporaryType, sizeof(temporaryType));
- ZeroMemory(&temporaryType, sizeof(temporaryType));
- VH( m_pEffect->m_pTypePool->AddValueWithHash(*ppType, hash) );
- }
- else
- {
- *ppType = iter.GetData();
- }
-
-lExit:
- SAFE_DELETE_ARRAY(pTempMembers);
- return hr;
-}
-
-// Numeric data in annotations are tightly packed (unlike in CBs which follow D3D11 packing rules). This unpacks them.
-uint32_t CEffectLoader::UnpackData(uint8_t *pDestData, uint8_t *pSrcData, uint32_t PackedDataSize, SType *pType, uint32_t *pBytesRead)
-{
- uint32_t bytesRead = 0;
- HRESULT hr = S_OK;
- uint32_t elementsToCopy = std::max<uint32_t>(pType->Elements, 1);
-
- switch (pType->VarType)
- {
- case EVT_Struct:
- for (size_t i = 0; i < elementsToCopy; ++ i)
- {
- for (size_t j = 0; j < pType->StructType.Members; ++ j)
- {
- uint32_t br;
- assert(PackedDataSize > bytesRead);
-
- VH( UnpackData(pDestData + pType->StructType.pMembers[j].Data.Offset,
- pSrcData + bytesRead, PackedDataSize - bytesRead,
- pType->StructType.pMembers[j].pType, &br) );
-
- bytesRead += br;
- }
- pDestData += pType->Stride;
- }
- break;
-
- case EVT_Numeric:
- if (pType->NumericType.IsPackedArray)
- {
- // No support for packed arrays
- assert(0);
- VHD(E_FAIL, "Internal loading error: packed arrays are not supported." );
- }
- else
- {
- uint32_t bytesToCopy;
-
- if (pType->NumericType.IsColumnMajor)
- {
- uint32_t registers = pType->NumericType.Columns;
- uint32_t entries = pType->NumericType.Rows;
- bytesToCopy = entries * registers * SType::c_ScalarSize;
-
- for (size_t i = 0; i < elementsToCopy; ++ i)
- {
- for (size_t j = 0; j < registers; ++ j)
- {
- for (size_t k = 0; k < entries; ++ k)
- {
- // type cast to an arbitrary scalar
- ((uint32_t*)pDestData)[k] = ((uint32_t*)pSrcData)[k * registers + j];
- }
- pDestData += SType::c_RegisterSize; // advance to next register
- }
- pSrcData += bytesToCopy;
- bytesRead += bytesToCopy;
- }
- }
- else
- {
- uint32_t registers = pType->NumericType.Rows;
- uint32_t entries = pType->NumericType.Columns;
- bytesToCopy = entries * SType::c_ScalarSize;
-
- for (size_t i = 0; i < elementsToCopy; ++ i)
- {
- for (size_t j = 0; j < registers; ++ j)
- {
- memcpy(pDestData, pSrcData, bytesToCopy);
-
- pDestData += SType::c_RegisterSize; // advance to next register
- pSrcData += bytesToCopy;
- bytesRead += bytesToCopy;
- }
- }
- }
- }
- break;
-
- default:
- // shouldn't be called on non-struct/numeric types
- assert(0);
- VHD(E_FAIL, "Internal loading error: UnpackData should not be called on non-struct, non-numeric types." );
- }
-
-lExit:
- *pBytesRead = bytesRead;
- return hr;
-}
-
-// Read info from the compiled blob and initialize a numeric variable
-HRESULT CEffectLoader::LoadNumericVariable(_In_ SConstantBuffer *pParentCB)
-{
- HRESULT hr = S_OK;
- SBinaryNumericVariable *psVar;
- SGlobalVariable *pVar;
- SType *pType;
- void *pDefaultValue;
-
- // Read variable info
- VHD( m_msStructured.Read((void**) &psVar, sizeof(*psVar)), "Invalid pEffectBuffer: cannot read numeric variable." );
- VBD( m_pEffect->m_VariableCount < (m_pHeader->Effect.cObjectVariables + m_pHeader->Effect.cNumericVariables + m_pHeader->cInterfaceVariables),
- "Internal loading error: invalid variable counts.");
- pVar = &m_pEffect->m_pVariables[m_pEffect->m_VariableCount];
-
- // Get type
- VH( LoadTypeAndAddToPool(&pType, psVar->oType) );
-
- // Make sure the right polymorphic type is created
- VH( PlacementNewVariable(pVar, pType, false) );
-
- if (psVar->Flags & D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT)
- {
- pVar->ExplicitBindPoint = psVar->Offset;
- }
- else
- {
- pVar->ExplicitBindPoint = uint32_t(-1);
- }
-
- pVar->pEffect = m_pEffect;
- pVar->pType = pType;
- pVar->pCB = pParentCB;
- pVar->Data.pGeneric = pParentCB->pBackingStore + psVar->Offset;
- VBD( psVar->Offset + pVar->pType->TotalSize <= pVar->pCB->Size, "Invalid pEffectBuffer: invalid variable offset." );
-
- if (pType->VarType == EVT_Struct && pType->StructType.ImplementsInterface && !pParentCB->IsTBuffer)
- {
- pVar->MemberDataOffsetPlus4 = m_pEffect->m_MemberDataCount * sizeof(SMemberDataPointer) + 4;
- m_pEffect->m_MemberDataCount += std::max<uint32_t>(pType->Elements,1);
- }
-
- // Get name & semantic
- VHD( GetStringAndAddToReflection(psVar->oName, &pVar->pName), "Invalid pEffectBuffer: cannot read variable name." );
- VHD( GetStringAndAddToReflection(psVar->oSemantic, &pVar->pSemantic), "Invalid pEffectBuffer: cannot read variable semantic." );
-
- // Ensure the variable fits in the CBuffer and doesn't overflow
- VBD( pType->TotalSize + psVar->Offset <= pParentCB->Size &&
- pType->TotalSize + psVar->Offset >= pType->TotalSize, "Invalid pEffectBuffer: variable does not fit in CB." );
-
- ZeroMemory(pVar->Data.pGeneric, pType->TotalSize);
-
- // Get default value
- if (0 != psVar->oDefaultValue)
- {
- uint32_t bytesUnpacked;
- VHD( m_msUnstructured.ReadAtOffset(psVar->oDefaultValue, pType->PackedSize, &pDefaultValue), "Invalid pEffectBuffer: cannot read default value." );
- VH( UnpackData((uint8_t*) pVar->Data.pGeneric, (uint8_t*) pDefaultValue, pType->PackedSize, pType, &bytesUnpacked) );
- VBD( bytesUnpacked == pType->PackedSize, "Invalid pEffectBuffer: invalid type packed size.");
- }
-
- // We need to use offsets until we fixup
- pVar->Data.Offset = psVar->Offset;
-
- // Read annotations
- VH( LoadAnnotations(&pVar->AnnotationCount, &pVar->pAnnotations) );
-
- m_pEffect->m_VariableCount++;
-
-lExit:
- return hr;
-}
-
-// Read info from the compiled blob and initialize a constant buffer
-HRESULT CEffectLoader::LoadCBs()
-{
- HRESULT hr = S_OK;
- uint32_t iCB, iVar;
-
- for (iCB=0; iCB<m_pHeader->Effect.cCBs; iCB++)
- {
- SBinaryConstantBuffer *psCB;
- SConstantBuffer *pCB;
-
- VHD( m_msStructured.Read((void**) &psCB, sizeof(*psCB)), "Invalid pEffectBuffer: cannot read CB." );
- pCB = &m_pEffect->m_pCBs[iCB];
-
- VHD( GetStringAndAddToReflection(psCB->oName, &pCB->pName), "Invalid pEffectBuffer: cannot read CB name." );
-
- pCB->IsTBuffer = (psCB->Flags & SBinaryConstantBuffer::c_IsTBuffer) != 0 ? true : false;
- pCB->IsSingle = (psCB->Flags & SBinaryConstantBuffer::c_IsSingle) != 0 ? true : false;
- pCB->Size = psCB->Size;
- pCB->ExplicitBindPoint = psCB->ExplicitBindPoint;
- VBD( pCB->Size == AlignToPowerOf2(pCB->Size, SType::c_RegisterSize), "Invalid pEffectBuffer: CB size not a power of 2." );
- VN( pCB->pBackingStore = PRIVATENEW uint8_t[pCB->Size] );
-
- pCB->MemberDataOffsetPlus4 = m_pEffect->m_MemberDataCount * sizeof(SMemberDataPointer) + 4;
- m_pEffect->m_MemberDataCount += 2;
-
- // point this CB to variables that it owns
- pCB->VariableCount = psCB->cVariables;
- if (pCB->VariableCount > 0)
- {
- pCB->pVariables = &m_pEffect->m_pVariables[m_pEffect->m_VariableCount];
- }
- else
- {
- pCB->pVariables = nullptr;
- }
-
- // Read annotations
- VH( LoadAnnotations(&pCB->AnnotationCount, &pCB->pAnnotations) );
-
- for (iVar=0; iVar<psCB->cVariables; iVar++)
- {
- VH( LoadNumericVariable(pCB) );
- }
- }
-
- m_pEffect->m_CBCount = m_pHeader->Effect.cCBs;
-
-lExit:
- return hr;
-}
-
-// Used by LoadAssignment to initialize members on load
-_Use_decl_annotations_
-HRESULT CEffectLoader::ExecuteConstantAssignment(const SBinaryConstant *pConstant, void *pLHS, D3D_SHADER_VARIABLE_TYPE lhsType)
-{
- HRESULT hr = S_OK;
-
- switch(pConstant->Type)
- {
- case EST_UInt:
- case EST_Int:
- case EST_Bool:
- switch(lhsType)
- {
- case D3D_SVT_BOOL:
- case D3D_SVT_INT:
- case D3D_SVT_UINT:
- *(uint32_t*) pLHS = pConstant->iValue;
- break;
-
- case D3D_SVT_UINT8:
- *(uint8_t*) pLHS = (uint8_t) pConstant->iValue;
- break;
-
- case D3D_SVT_FLOAT:
- *(float*) pLHS = (float) pConstant->iValue;
- break;
-
- default:
- VHD( E_FAIL, "Internal loading error: invalid left-hand assignment type." );
- }
- break;
-
- case EST_Float:
- switch(lhsType)
- {
- case D3D_SVT_BOOL:
- case D3D_SVT_INT:
- case D3D_SVT_UINT:
- *(uint32_t*) pLHS = (uint32_t) pConstant->fValue;
- break;
-
- case D3D_SVT_UINT8:
- *(uint8_t*) pLHS = (uint8_t) pConstant->fValue;
- break;
-
- case D3D_SVT_FLOAT:
- *(float*) pLHS = pConstant->fValue;
- break;
-
- default:
- VHD( E_FAIL, "Internal loading error: invalid left-hand assignment type." );
- }
- break;
-
- default:
- VHD( E_FAIL, "Internal loading error: invalid left-hand assignment type." );
- }
-
-lExit:
- return hr;
-}
-
-
-// Read info from the compiled blob and initialize a set of assignments
-_Use_decl_annotations_
-HRESULT CEffectLoader::LoadAssignments( uint32_t Assignments, SAssignment **ppAssignments,
- uint8_t *pBackingStore, uint32_t *pRTVAssignments, uint32_t *pFinalAssignments )
-{
- HRESULT hr = S_OK;
- uint32_t i, j;
-
- SBinaryAssignment *psAssignments;
- uint32_t finalAssignments = 0; // the number of assignments worth keeping
- uint32_t renderTargetViewAssns = 0; // Number of render target view assns, used by passes since SetRTV is a vararg call
-
- *pFinalAssignments = 0;
- if (pRTVAssignments)
- *pRTVAssignments = 0;
-
- VHD( m_msStructured.Read((void**) &psAssignments, sizeof(*psAssignments) * Assignments), "Invalid pEffectBuffer: cannot read assignments." );
-
- // allocate enough room to store all of the assignments (even though some may go unused)
- VN( (*ppAssignments) = PRIVATENEW SAssignment[Assignments] )
-
- //
- // In this loop, we read assignments 1-by-1, keeping some and discarding others.
- // We write to the "next" assignment which is given by &(*ppAssignments)[finalAssignments];
- // if an assignment is worth keeping, we increment finalAssignments.
- // This means that if you want to keep an assignment, you must be careful to initialize
- // all members of SAssignment because old values from preceding discarded assignments might remain.
- //
- for (i = 0; i < Assignments; ++ i)
- {
- SGlobalVariable *pVarArray, *pVarIndex, *pVar;
- const char *pGlobalVarName;
- SAssignment *pAssignment = &(*ppAssignments)[finalAssignments];
- uint8_t *pLHS;
-
- VBD( psAssignments[i].iState < NUM_STATES, "Invalid pEffectBuffer: invalid assignment state." );
- VBD( psAssignments[i].Index < g_lvGeneral[psAssignments[i].iState].m_Indices, "Invalid pEffectBuffer: invalid assignment index." );
-
- pAssignment->LhsType = g_lvGeneral[psAssignments[i].iState].m_LhsType;
-
- // Count RenderTargetView assignments
- if (pAssignment->LhsType == ELHS_RenderTargetView)
- renderTargetViewAssns++;
-
- switch (g_lvGeneral[psAssignments[i].iState].m_Type)
- {
- case D3D_SVT_UINT8:
- assert(g_lvGeneral[psAssignments[i].iState].m_Cols == 1); // uint8_t arrays not supported
- pAssignment->DataSize = sizeof(uint8_t);
- // Store an offset for destination instead of a pointer so that it's easy to relocate it later
-
- break;
-
- case D3D_SVT_BOOL:
- case D3D_SVT_INT:
- case D3D_SVT_UINT:
- case D3D_SVT_FLOAT:
- pAssignment->DataSize = SType::c_ScalarSize * g_lvGeneral[psAssignments[i].iState].m_Cols;
- break;
-
- case D3D_SVT_RASTERIZER:
- pAssignment->DataSize = sizeof(SRasterizerBlock);
- break;
-
- case D3D_SVT_DEPTHSTENCIL:
- pAssignment->DataSize = sizeof(SDepthStencilBlock);
- break;
-
- case D3D_SVT_BLEND:
- pAssignment->DataSize = sizeof(SBlendBlock);
- break;
-
- case D3D_SVT_VERTEXSHADER:
- case D3D_SVT_GEOMETRYSHADER:
- case D3D_SVT_PIXELSHADER:
- case D3D_SVT_HULLSHADER:
- case D3D_SVT_DOMAINSHADER:
- case D3D_SVT_COMPUTESHADER:
- pAssignment->DataSize = sizeof(SShaderBlock);
- break;
-
- case D3D_SVT_TEXTURE:
- case D3D_SVT_TEXTURE1D:
- case D3D_SVT_TEXTURE2D:
- case D3D_SVT_TEXTURE2DMS:
- case D3D_SVT_TEXTURE3D:
- case D3D_SVT_TEXTURECUBE:
- case D3D_SVT_TEXTURECUBEARRAY:
- case D3D_SVT_BYTEADDRESS_BUFFER:
- case D3D_SVT_STRUCTURED_BUFFER:
- pAssignment->DataSize = sizeof(SShaderResource);
- break;
-
- case D3D_SVT_RENDERTARGETVIEW:
- pAssignment->DataSize = sizeof(SRenderTargetView);
- break;
-
- case D3D_SVT_DEPTHSTENCILVIEW:
- pAssignment->DataSize = sizeof(SDepthStencilView);
- break;
-
- case D3D_SVT_RWTEXTURE1D:
- case D3D_SVT_RWTEXTURE1DARRAY:
- case D3D_SVT_RWTEXTURE2D:
- case D3D_SVT_RWTEXTURE2DARRAY:
- case D3D_SVT_RWTEXTURE3D:
- case D3D_SVT_RWBUFFER:
- case D3D_SVT_RWBYTEADDRESS_BUFFER:
- case D3D_SVT_RWSTRUCTURED_BUFFER:
- case D3D_SVT_APPEND_STRUCTURED_BUFFER:
- case D3D_SVT_CONSUME_STRUCTURED_BUFFER:
- pAssignment->DataSize = sizeof(SUnorderedAccessView);
- break;
-
- case D3D_SVT_INTERFACE_POINTER:
- pAssignment->DataSize = sizeof(SInterface);
- break;
-
- default:
- assert(0);
- VHD( E_FAIL, "Internal loading error: invalid assignment type.");
- }
-
- uint32_t lhsStride;
- if( g_lvGeneral[psAssignments[i].iState].m_Stride > 0 )
- lhsStride = g_lvGeneral[psAssignments[i].iState].m_Stride;
- else
- lhsStride = pAssignment->DataSize;
-
- // Store only the destination offset so that the backing store pointers can be easily fixed up later
- pAssignment->Destination.Offset = g_lvGeneral[psAssignments[i].iState].m_Offset + lhsStride * psAssignments[i].Index;
-
- // As a result, you should use pLHS in this function instead of the destination pointer
- pLHS = pBackingStore + pAssignment->Destination.Offset;
-
- switch (psAssignments[i].AssignmentType)
- {
- case ECAT_Constant: // e.g. LHS = 1; or LHS = nullptr;
- uint32_t *pNumConstants;
- SBinaryConstant *pConstants;
-
- VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(uint32_t), (void**) &pNumConstants), "Invalid pEffectBuffer: cannot read NumConstants." );
- VHD( m_msUnstructured.Read((void **)&pConstants, sizeof(SBinaryConstant) * (*pNumConstants)), "Invalid pEffectBuffer: cannot read constants." );
-
- if(pAssignment->IsObjectAssignment())
- {
- // make sure this is a nullptr assignment
- VBD( *pNumConstants == 1 && (pConstants[0].Type == EST_Int || pConstants[0].Type == EST_UInt) && pConstants[0].iValue == 0,
- "Invalid pEffectBuffer: non-nullptr constant assignment to object.");
-
- switch (pAssignment->LhsType)
- {
- case ELHS_DepthStencilBlock:
- *((void **)pLHS) = &g_NullDepthStencil;
- break;
- case ELHS_BlendBlock:
- *((void **)pLHS) = &g_NullBlend;
- break;
- case ELHS_RasterizerBlock:
- *((void **)pLHS) = &g_NullRasterizer;
- break;
- case ELHS_VertexShaderBlock:
- *((void **)pLHS) = &g_NullVS;
- break;
- case ELHS_PixelShaderBlock:
- *((void **)pLHS) = &g_NullPS;
- break;
- case ELHS_GeometryShaderBlock:
- *((void **)pLHS) = &g_NullGS;
- break;
- case ELHS_HullShaderBlock:
- *((void **)pLHS) = &g_NullHS;
- break;
- case ELHS_DomainShaderBlock:
- *((void **)pLHS) = &g_NullDS;
- break;
- case ELHS_ComputeShaderBlock:
- *((void **)pLHS) = &g_NullCS;
- break;
- case ELHS_Texture:
- *((void **)pLHS) = &g_NullTexture;
- break;
- case ELHS_DepthStencilView:
- *((void **)pLHS) = &g_NullDepthStencilView;
- break;
- case ELHS_RenderTargetView:
- *((void **)pLHS) = &g_NullRenderTargetView;
- break;
- default:
- assert(0);
- }
- }
- else
- {
- VBD( *pNumConstants == g_lvGeneral[psAssignments[i].iState].m_Cols, "Internal loading error: mismatch constant count." );
- for (j = 0; j < *pNumConstants; ++ j)
- {
- VH( ExecuteConstantAssignment(pConstants + j, pLHS, g_lvGeneral[psAssignments[i].iState].m_Type) );
- pLHS += SType::c_ScalarSize; // arrays of constants will always be regular scalar sized, never byte-sized
- }
- }
-
- // Can get rid of this assignment
- break;
-
- case ECAT_Variable: // e.g. LHS = myVar;
- VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, &pGlobalVarName), "Invalid pEffectBuffer: cannot read variable name." );
-
- VBD( pVar = m_pEffect->FindVariableByName(pGlobalVarName), "Loading error: cannot find variable name." );
-
- if (pAssignment->IsObjectAssignment())
- {
- VBD( pVar->pType->VarType == EVT_Object &&
- GetSimpleParameterTypeFromObjectType(pVar->pType->ObjectType) == g_lvGeneral[psAssignments[i].iState].m_Type,
- "Loading error: invalid variable type or object type." );
-
- // Write directly into the state block's backing store
- *((void **)pLHS) = pVar->Data.pGeneric;
-
- // Now we can get rid of this assignment
- }
- else
- {
- VBD( pVar->pType->BelongsInConstantBuffer(), "Invalid pEffectBuffer: assignment type mismatch." );
-
- pAssignment->DependencyCount = 1;
- VN( pAssignment->pDependencies = PRIVATENEW SAssignment::SDependency[pAssignment->DependencyCount] );
- pAssignment->pDependencies->pVariable = pVar;
-
- // Store an offset for numeric values instead of a pointer so that it's easy to relocate it later
- pAssignment->Source.Offset = pVar->Data.Offset;
- pAssignment->AssignmentType = ERAT_NumericVariable;
-
- // Can't get rid of this assignment
- ++ finalAssignments;
- }
- break;
-
- case ECAT_ConstIndex: // e.g. LHS = myGS[1]
- SBinaryAssignment::SConstantIndex *psConstIndex;
-
- VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(*psConstIndex), (void**) &psConstIndex),
- "Invalid pEffectBuffer: cannot read assignment initializer." );
- VHD( m_msUnstructured.ReadAtOffset(psConstIndex->oArrayName, &pGlobalVarName), "Invalid pEffectBuffer: cannot read array name." );
-
- VBD( pVarArray = m_pEffect->FindVariableByName(pGlobalVarName), "Loading error: cannot find array name." );
-
- if (pAssignment->IsObjectAssignment())
- {
- VBD( psConstIndex->Index < pVarArray->pType->Elements, "Invalid pEffectBuffer: out of bounds array index." );
- VBD( pVarArray->pType->VarType == EVT_Object &&
- GetSimpleParameterTypeFromObjectType(pVarArray->pType->ObjectType) == g_lvGeneral[psAssignments[i].iState].m_Type,
- "Loading error: invalid variable type or object type." );
-
- // Write directly into the state block's backing store
- *((void **)pLHS) = GetBlockByIndex(pVarArray->pType->VarType, pVarArray->pType->ObjectType, pVarArray->Data.pGeneric, psConstIndex->Index);
- VBD( nullptr != *((void **)pLHS), "Internal loading error: invalid block." );
-
- // Now we can get rid of this assignment
- }
- else
- {
- VBD( pVarArray->pType->BelongsInConstantBuffer(), "Invalid pEffectBuffer: assignment type mismatch." );
-
- pAssignment->DependencyCount = 1;
- VN( pAssignment->pDependencies = PRIVATENEW SAssignment::SDependency[pAssignment->DependencyCount] );
- pAssignment->pDependencies->pVariable = pVarArray;
-
- CCheckedDword chkDataLen = psConstIndex->Index;
- uint32_t dataLen;
- chkDataLen *= SType::c_ScalarSize;
- chkDataLen += pAssignment->DataSize;
- VHD( chkDataLen.GetValue(&dataLen), "Overflow: assignment size." );
- VBD( dataLen <= pVarArray->pType->TotalSize, "Internal loading error: assignment size mismatch" );
-
- pAssignment->Source.Offset = pVarArray->Data.Offset + psConstIndex->Index * SType::c_ScalarSize;
-
- // _NumericConstIndex is not used here because _NumericVariable
- // does the same stuff in a more general fashion with no perf hit.
- pAssignment->AssignmentType = ERAT_NumericVariable;
-
- // Can't get rid of this assignment
- ++ finalAssignments;
- }
- break;
-
- case ECAT_VariableIndex: // e.g. LHS = myVar[numLights];
- SBinaryAssignment::SVariableIndex *psVarIndex;
-
- VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(*psVarIndex), (void**) &psVarIndex),
- "Invalid pEffectBuffer: cannot read assignment initializer." );
- VHD( m_msUnstructured.ReadAtOffset(psVarIndex->oArrayName, &pGlobalVarName), "Invalid pEffectBuffer: cannot read variable name." );
- VBD( pVarArray = m_pEffect->FindVariableByName(pGlobalVarName), "Loading error: cannot find variable name." );
-
- VHD( m_msUnstructured.ReadAtOffset(psVarIndex->oIndexVarName, &pGlobalVarName), "Invalid pEffectBuffer: cannot read index variable name." );
- VBD( pVarIndex = m_pEffect->FindVariableByName(pGlobalVarName), "Loading error: cannot find index variable name." );
-
- // Only support integer indices
- VBD( pVarIndex->pType->VarType == EVT_Numeric && (pVarIndex->pType->NumericType.ScalarType == EST_Int || pVarIndex->pType->NumericType.ScalarType == EST_UInt),
- "Invalid pEffectBuffer: invalid index variable type.");
- VBD( pVarArray->pType->Elements > 0, "Invalid pEffectBuffer: array variable is not an array." );
-
- pVarIndex->pCB->IsUsedByExpression = true;
-
- if (pAssignment->IsObjectAssignment())
- {
- VBD( pVarArray->pType->VarType == EVT_Object &&
- GetSimpleParameterTypeFromObjectType(pVarArray->pType->ObjectType) == g_lvGeneral[psAssignments[i].iState].m_Type,
- "Loading error: invalid variable type or object type." );
-
- // MaxElements is only 16-bits wide
- VBD( pVarArray->pType->Elements <= 0xFFFF, "Internal error: array size is too large." );
- pAssignment->MaxElements = pVarArray->pType->Elements;
-
- pAssignment->DependencyCount = 1;
- VN( pAssignment->pDependencies = PRIVATENEW SAssignment::SDependency[pAssignment->DependencyCount] );
- pAssignment->pDependencies[0].pVariable = pVarIndex;
-
- // Point this assignment to the start of the variable's object array.
- // When this assignment is dirty, we write the value of this pointer plus
- // the index given by its one dependency directly into the destination
- pAssignment->Source = pVarArray->Data;
- pAssignment->AssignmentType = ERAT_ObjectVariableIndex;
- }
- else
- {
- VBD( pVarArray->pType->BelongsInConstantBuffer(), "Invalid pEffectBuffer: assignment type mismatch." );
-
- pAssignment->DependencyCount = 2;
- VN( pAssignment->pDependencies = PRIVATENEW SAssignment::SDependency[pAssignment->DependencyCount] );
- pAssignment->pDependencies[0].pVariable = pVarIndex;
- pAssignment->pDependencies[1].pVariable = pVarArray;
-
- // When pVarIndex is updated, we update the source pointer.
- // When pVarArray is updated, we copy data from the source to the destination.
- pAssignment->Source.pGeneric = nullptr;
- pAssignment->AssignmentType = ERAT_NumericVariableIndex;
- }
-
- // Can't get rid of this assignment
- ++ finalAssignments;
-
- break;
-
- case ECAT_ExpressionIndex:// e.g. LHS = myVar[a + b * c];
- case ECAT_Expression: // e.g. LHS = a + b * c;
- // we do not support FXLVM
- VHD( E_NOTIMPL, "FXLVM Expressions (complex assignments like myVar[i*2]) are not supported in Effects11." );
- break;
-
- case ECAT_InlineShader:
- case ECAT_InlineShader5:
- uint32_t cbShaderBin;
- uint8_t *pShaderBin;
- SShaderBlock *pShaderBlock;
- SAnonymousShader *pAnonShader;
- union
- {
- SBinaryAssignment::SInlineShader *psInlineShader;
- SBinaryShaderData5 *psInlineShader5;
- };
-
- // Inline shader assignments must be object types
- assert(pAssignment->IsObjectAssignment());
-
- static_assert(offsetof(SBinaryAssignment::SInlineShader, oShader) == offsetof(SBinaryShaderData5, oShader), "ECAT_InlineShader issue");
- static_assert(offsetof(SBinaryAssignment::SInlineShader, oSODecl) == offsetof(SBinaryShaderData5, oSODecls), "ECAT_InlineShader5 issue");
- if( psAssignments[i].AssignmentType == ECAT_InlineShader )
- {
- VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(*psInlineShader), (void**) &psInlineShader),
- "Invalid pEffectBuffer: cannot read inline shader." );
- }
- else
- {
- VHD( m_msUnstructured.ReadAtOffset(psAssignments[i].oInitializer, sizeof(*psInlineShader5), (void**) &psInlineShader5),
- "Invalid pEffectBuffer: cannot read inline shader." );
- }
-
- VBD( m_pEffect->m_ShaderBlockCount < m_pHeader->cTotalShaders, "Internal loading error: shader count is out incorrect." );
- VBD( m_pEffect->m_AnonymousShaderCount < m_pHeader->cInlineShaders, "Internal loading error: anonymous shader count is out incorrect." );
-
- pShaderBlock = &m_pEffect->m_pShaderBlocks[m_pEffect->m_ShaderBlockCount];
- pAnonShader = &m_pEffect->m_pAnonymousShaders[m_pEffect->m_AnonymousShaderCount];
- pAnonShader->pShaderBlock = pShaderBlock;
-
- ++ m_pEffect->m_ShaderBlockCount;
- ++ m_pEffect->m_AnonymousShaderCount;
-
- // Write directly into the state block's backing store
- *((void **)pLHS) = pShaderBlock;
-
- VHD( GetUnstructuredDataBlock(psInlineShader->oShader, &cbShaderBin, (void **) &pShaderBin), "Invalid pEffectBuffer: cannot read inline shader block." );
-
- if (cbShaderBin > 0)
- {
- VN( pShaderBlock->pReflectionData = PRIVATENEW SShaderBlock::SReflectionData );
-
- pShaderBlock->pReflectionData->BytecodeLength = cbShaderBin;
- pShaderBlock->pReflectionData->pBytecode = (uint8_t*) pShaderBin;
- pShaderBlock->pReflectionData->pStreamOutDecls[0] =
- pShaderBlock->pReflectionData->pStreamOutDecls[1] =
- pShaderBlock->pReflectionData->pStreamOutDecls[2] =
- pShaderBlock->pReflectionData->pStreamOutDecls[3] = nullptr;
- pShaderBlock->pReflectionData->RasterizedStream = 0;
- pShaderBlock->pReflectionData->IsNullGS = FALSE;
- pShaderBlock->pReflectionData->pReflection = nullptr;
- pShaderBlock->pReflectionData->InterfaceParameterCount = 0;
- pShaderBlock->pReflectionData->pInterfaceParameters = nullptr;
- }
-
- switch (pAssignment->LhsType)
- {
- case ELHS_PixelShaderBlock:
- pShaderBlock->pVT = &g_vtPS;
- VBD( psInlineShader->oSODecl == 0, "Internal loading error: pixel shaders cannot have stream out decls." );
- break;
-
- case ELHS_GeometryShaderBlock:
- pShaderBlock->pVT = &g_vtGS;
- if( psAssignments[i].AssignmentType == ECAT_InlineShader )
- {
- if (psInlineShader->oSODecl)
- {
- // This is a GS with SO
- VHD( GetStringAndAddToReflection(psInlineShader->oSODecl, &pShaderBlock->pReflectionData->pStreamOutDecls[0]),
- "Invalid pEffectBuffer: cannot read SO decl." );
- }
- }
- else
- {
- // This is a GS with addressable stream out
- for( size_t iDecl=0; iDecl < psInlineShader5->cSODecls; ++iDecl )
- {
- if (psInlineShader5->oSODecls[iDecl])
- {
- VHD( GetStringAndAddToReflection(psInlineShader5->oSODecls[iDecl], &pShaderBlock->pReflectionData->pStreamOutDecls[iDecl]),
- "Invalid pEffectBuffer: cannot read SO decl." );
- }
- }
- pShaderBlock->pReflectionData->RasterizedStream = psInlineShader5->RasterizedStream;
- }
- break;
-
- case ELHS_VertexShaderBlock:
- pShaderBlock->pVT = &g_vtVS;
- VBD( psInlineShader->oSODecl == 0, "Internal loading error: vertex shaders cannot have stream out decls." );
- break;
-
- case ELHS_HullShaderBlock:
- pShaderBlock->pVT = &g_vtHS;
- VBD( psInlineShader->oSODecl == 0, "Internal loading error: hull shaders cannot have stream out decls." );
- break;
-
- case ELHS_DomainShaderBlock:
- pShaderBlock->pVT = &g_vtDS;
- VBD( psInlineShader->oSODecl == 0, "Internal loading error: domain shaders cannot have stream out decls." );
- break;
-
- case ELHS_ComputeShaderBlock:
- pShaderBlock->pVT = &g_vtCS;
- VBD( psInlineShader->oSODecl == 0, "Internal loading error: compute shaders cannot have stream out decls." );
- break;
-
- case ELHS_GeometryShaderSO:
- assert(0); // Should never happen
-
- default:
- VHD( E_FAIL, "Internal loading error: invalid shader type." );
- }
-
- if( psAssignments[i].AssignmentType == ECAT_InlineShader5 )
- {
- pShaderBlock->pReflectionData->InterfaceParameterCount = psInlineShader5->cInterfaceBindings;
- VH( GetInterfaceParametersAndAddToReflection( psInlineShader5->cInterfaceBindings, psInlineShader5->oInterfaceBindings, &pShaderBlock->pReflectionData->pInterfaceParameters ) );
- }
-
- // Now we can get rid of this assignment
- break;
-
- default:
- assert(0);
-
- }
- }
-
- *pFinalAssignments = finalAssignments;
- if (pRTVAssignments)
- *pRTVAssignments = renderTargetViewAssns;
-
-lExit:
- return hr;
-}
-
-
-// Read info from the compiled blob and initialize an object variable
-HRESULT CEffectLoader::LoadObjectVariables()
-{
- HRESULT hr = S_OK;
-
- size_t cBlocks = m_pHeader->Effect.cObjectVariables;
-
- for (size_t iBlock=0; iBlock<cBlocks; iBlock++)
- {
- SBinaryObjectVariable *psBlock;
- SGlobalVariable *pVar;
- SType *pType;
- uint32_t elementsToRead;
- CCheckedDword chkElementsTotal;
- uint32_t elementsTotal;
-
- // Read variable info
- VHD( m_msStructured.Read((void**) &psBlock, sizeof(*psBlock)), "Invalid pEffectBuffer: cannot read object variable." );
- VBD( m_pEffect->m_VariableCount < (m_pHeader->Effect.cObjectVariables + m_pHeader->Effect.cNumericVariables + m_pHeader->cInterfaceVariables),
- "Internal loading error: variable count mismatch." );
- pVar = &m_pEffect->m_pVariables[m_pEffect->m_VariableCount];
-
- // Get type
- VH( LoadTypeAndAddToPool(&pType, psBlock->oType) );
-
- // Make sure the right polymorphic type is created
- VH( PlacementNewVariable(pVar, pType, false) );
-
- pVar->pEffect = m_pEffect;
- pVar->pType = pType;
- pVar->pCB = nullptr;
- pVar->ExplicitBindPoint = psBlock->ExplicitBindPoint;
-
- if( pType->IsStateBlockObject() )
- {
- pVar->MemberDataOffsetPlus4 = m_pEffect->m_MemberDataCount * sizeof(SMemberDataPointer) + 4;
- m_pEffect->m_MemberDataCount += std::max<uint32_t>(pType->Elements,1);
- }
-
- // Get name
- VHD( GetStringAndAddToReflection(psBlock->oName, &pVar->pName), "Invalid pEffectBuffer: cannot read object variable name." );
- VHD( GetStringAndAddToReflection(psBlock->oSemantic, &pVar->pSemantic), "Invalid pEffectBuffer: cannot read object variable semantic." );
-
- m_pEffect->m_VariableCount++;
- elementsToRead = std::max<uint32_t>(1, pType->Elements);
- chkElementsTotal = elementsToRead;
-
- if (pType->IsStateBlockObject())
- {
- // State blocks
- EBlockType blockType;
- uint32_t *maxBlockCount;
- uint32_t *currentBlockCount;
-
- switch (pType->ObjectType)
- {
- case EOT_Blend:
- pVar->Data.pBlock = &m_pEffect->m_pBlendBlocks[m_pEffect->m_BlendBlockCount];
- maxBlockCount = &m_pHeader->cBlendStateBlocks;
- currentBlockCount = &m_pEffect->m_BlendBlockCount;
- blockType = EBT_Blend;
- break;
-
- case EOT_DepthStencil:
- pVar->Data.pBlock = &m_pEffect->m_pDepthStencilBlocks[m_pEffect->m_DepthStencilBlockCount];
- maxBlockCount = &m_pHeader->cDepthStencilBlocks;
- currentBlockCount = &m_pEffect->m_DepthStencilBlockCount;
- blockType = EBT_DepthStencil;
- break;
-
- case EOT_Rasterizer:
- pVar->Data.pBlock = &m_pEffect->m_pRasterizerBlocks[m_pEffect->m_RasterizerBlockCount];
- maxBlockCount = &m_pHeader->cRasterizerStateBlocks;
- currentBlockCount = &m_pEffect->m_RasterizerBlockCount;
- blockType = EBT_Rasterizer;
- break;
-
- default:
- VB(pType->IsSampler());
- pVar->Data.pBlock = &m_pEffect->m_pSamplerBlocks[m_pEffect->m_SamplerBlockCount];
- maxBlockCount = &m_pHeader->cSamplers;
- currentBlockCount = &m_pEffect->m_SamplerBlockCount;
- blockType = EBT_Sampler;
- }
-
- chkElementsTotal += *currentBlockCount;
- VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: vaiable elements." );
- VBD( elementsTotal <= *maxBlockCount, "Internal loading error: element count overflow." );
-
- *currentBlockCount += elementsToRead;
-
- for (uint32_t iElement = 0; iElement < elementsToRead; ++ iElement)
- {
- SBaseBlock *pCurrentBlock;
- uint32_t cAssignments;
-
- pCurrentBlock = (SBaseBlock *) GetBlockByIndex(pVar->pType->VarType, pVar->pType->ObjectType, pVar->Data.pGeneric, iElement);
- VBD( nullptr != pCurrentBlock, "Internal loading error: find state block." );
-
- pCurrentBlock->BlockType = blockType;
-
- VHD( m_msStructured.Read(&cAssignments), "Invalid pEffectBuffer: cannot read state block assignments." );
-
- VH( LoadAssignments( cAssignments, &pCurrentBlock->pAssignments, (uint8_t*)pCurrentBlock, nullptr, &pCurrentBlock->AssignmentCount ) );
- }
- }
- else if (pType->IsShader())
- {
- // Shaders
-
- chkElementsTotal += m_pEffect->m_ShaderBlockCount;
- VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: shader block count." );
- VBD( elementsTotal <= m_pHeader->cTotalShaders, "Invalid pEffectBuffer: shader count mismatch." );
-
- pVar->Data.pShader = &m_pEffect->m_pShaderBlocks[m_pEffect->m_ShaderBlockCount];
-
- for (size_t iElement=0; iElement<elementsToRead; iElement++)
- {
- uint32_t cbShaderBin;
- void *pShaderBin;
- SShaderBlock *pShaderBlock;
-
- union
- {
- uint32_t *pOffset;
- SBinaryGSSOInitializer *psInlineGSSO4;
- SBinaryShaderData5 *psInlineShader5;
- };
-
- static_assert(offsetof(SBinaryGSSOInitializer, oShader) == 0, "Union issue");
- static_assert(offsetof(SBinaryShaderData5, oShader) == 0, "Union issue");
-
-
- pShaderBlock = &m_pEffect->m_pShaderBlocks[m_pEffect->m_ShaderBlockCount];
- m_pEffect->m_ShaderBlockCount++;
-
- // Get shader binary
- switch (pType->ObjectType)
- {
- case EOT_VertexShader:
- case EOT_GeometryShader:
- case EOT_PixelShader:
- VHD( m_msStructured.Read((void**)&pOffset, sizeof(*pOffset)), "Invalid pEffectBuffer: cannot read shader block." );
- break;
-
- case EOT_GeometryShaderSO:
- VHD( m_msStructured.Read((void**)&psInlineGSSO4, sizeof(*psInlineGSSO4)), "Invalid pEffectBuffer: cannot read inline GS with SO." );
- break;
-
- case EOT_VertexShader5:
- case EOT_GeometryShader5:
- case EOT_HullShader5:
- case EOT_DomainShader5:
- case EOT_PixelShader5:
- case EOT_ComputeShader5:
- VHD( m_msStructured.Read((void**)&psInlineShader5, sizeof(*psInlineShader5)), "Invalid pEffectBuffer: cannot read inline shader." );
- break;
-
- default:
- VH( E_FAIL );
- }
-
- VHD( GetUnstructuredDataBlock(*pOffset, &cbShaderBin, &pShaderBin), "Invalid pEffectBuffer: cannot read shader byte code." );
-
- if (cbShaderBin > 0)
- {
- VN( pShaderBlock->pReflectionData = PRIVATENEW SShaderBlock::SReflectionData );
-
- pShaderBlock->pReflectionData->BytecodeLength = cbShaderBin;
- pShaderBlock->pReflectionData->pBytecode = (uint8_t*) pShaderBin;
- pShaderBlock->pReflectionData->pStreamOutDecls[0] =
- pShaderBlock->pReflectionData->pStreamOutDecls[1] =
- pShaderBlock->pReflectionData->pStreamOutDecls[2] =
- pShaderBlock->pReflectionData->pStreamOutDecls[3] = nullptr;
- pShaderBlock->pReflectionData->RasterizedStream = 0;
- pShaderBlock->pReflectionData->IsNullGS = FALSE;
- pShaderBlock->pReflectionData->pReflection = nullptr;
- pShaderBlock->pReflectionData->InterfaceParameterCount = 0;
- pShaderBlock->pReflectionData->pInterfaceParameters = nullptr;
- }
-
- switch (pType->ObjectType)
- {
- case EOT_PixelShader:
- pShaderBlock->pVT = &g_vtPS;
- break;
-
- case EOT_GeometryShaderSO:
- // Get StreamOut decl
- //VH( m_msStructured.Read(&dwOffset) );
- if (cbShaderBin > 0)
- {
- VHD( GetStringAndAddToReflection(psInlineGSSO4->oSODecl, &pShaderBlock->pReflectionData->pStreamOutDecls[0]),
- "Invalid pEffectBuffer: cannot read stream out decl." );
- }
- pShaderBlock->pVT = &g_vtGS;
- break;
-
- case EOT_VertexShader5:
- case EOT_GeometryShader5:
- case EOT_HullShader5:
- case EOT_DomainShader5:
- case EOT_PixelShader5:
- case EOT_ComputeShader5:
- // Get StreamOut decls
- if (cbShaderBin > 0)
- {
- for( size_t iDecl=0; iDecl < psInlineShader5->cSODecls; ++iDecl )
- {
- VHD( GetStringAndAddToReflection(psInlineShader5->oSODecls[iDecl], &pShaderBlock->pReflectionData->pStreamOutDecls[iDecl]),
- "Invalid pEffectBuffer: cannot read stream out decls." );
- }
- pShaderBlock->pReflectionData->RasterizedStream = psInlineShader5->RasterizedStream;
- pShaderBlock->pReflectionData->InterfaceParameterCount = psInlineShader5->cInterfaceBindings;
- VH( GetInterfaceParametersAndAddToReflection( psInlineShader5->cInterfaceBindings, psInlineShader5->oInterfaceBindings, &pShaderBlock->pReflectionData->pInterfaceParameters ) );
- }
- switch (pType->ObjectType)
- {
- case EOT_VertexShader5:
- pShaderBlock->pVT = &g_vtVS;
- break;
- case EOT_GeometryShader5:
- pShaderBlock->pVT = &g_vtGS;
- break;
- case EOT_HullShader5:
- pShaderBlock->pVT = &g_vtHS;
- break;
- case EOT_DomainShader5:
- pShaderBlock->pVT = &g_vtDS;
- break;
- case EOT_PixelShader5:
- pShaderBlock->pVT = &g_vtPS;
- break;
- case EOT_ComputeShader5:
- pShaderBlock->pVT = &g_vtCS;
- break;
- default:
- VH( E_FAIL );
- }
- break;
-
- case EOT_GeometryShader:
- pShaderBlock->pVT = &g_vtGS;
- break;
-
- case EOT_VertexShader:
- pShaderBlock->pVT = &g_vtVS;
- break;
-
- default:
- VHD( E_FAIL, "Invalid pEffectBuffer: invalid shader type." );
- }
- }
- }
- else if (pType->IsObjectType(EOT_String))
- {
- // Strings
-
- chkElementsTotal += m_pEffect->m_StringCount;
- VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: string object count." );
- VBD( elementsTotal <= m_pHeader->cStrings, "Invalid pEffectBuffer: string count mismatch." );
-
- pVar->Data.pString = &m_pEffect->m_pStrings[m_pEffect->m_StringCount];
-
- for (size_t iElement=0; iElement<elementsToRead; iElement++)
- {
- uint32_t dwOffset;
- SString *pString;
-
- pString = &m_pEffect->m_pStrings[m_pEffect->m_StringCount];
- m_pEffect->m_StringCount++;
-
- // Get string
- VHD( m_msStructured.Read(&dwOffset), "Invalid pEffectBuffer: cannot read string offset." );
- VHD( GetStringAndAddToReflection(dwOffset, &pString->pString), "Invalid pEffectBuffer: cannot read string." );
- }
- }
- else if (pType->IsShaderResource())
- {
- // Textures/buffers
-
- chkElementsTotal += m_pEffect->m_ShaderResourceCount;
- VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: SRV object count." );
- VBD( elementsTotal <= m_pHeader->cShaderResources, "Invalid pEffectBuffer: SRV count mismatch." );
-
- pVar->Data.pShaderResource = &m_pEffect->m_pShaderResources[m_pEffect->m_ShaderResourceCount];
- m_pEffect->m_ShaderResourceCount += elementsToRead;
- }
- else if (pType->IsUnorderedAccessView())
- {
- // UnorderedAccessViews
-
- chkElementsTotal += m_pEffect->m_UnorderedAccessViewCount;
- VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: UAV object count." );
- VBD( elementsTotal <= m_pHeader->cUnorderedAccessViews, "Invalid pEffectBuffer: UAV count mismatch." );
-
- pVar->Data.pUnorderedAccessView = &m_pEffect->m_pUnorderedAccessViews[m_pEffect->m_UnorderedAccessViewCount];
- m_pEffect->m_UnorderedAccessViewCount += elementsToRead;
- }
- else if (pType->IsRenderTargetView())
- {
- // RenderTargets
-
- chkElementsTotal += m_pEffect->m_RenderTargetViewCount;
- VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: RTV object count." );
- VBD( elementsTotal <= m_pHeader->cRenderTargetViews, "Invalid pEffectBuffer: RTV count mismatch." );
-
- pVar->Data.pRenderTargetView = &m_pEffect->m_pRenderTargetViews[m_pEffect->m_RenderTargetViewCount];
- m_pEffect->m_RenderTargetViewCount += elementsToRead;
- }
- else if (pType->IsDepthStencilView())
- {
- // DepthStencilViews
-
- chkElementsTotal += m_pEffect->m_DepthStencilViewCount;
- VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: DSV object count." );
- VBD( elementsTotal <= m_pHeader->cDepthStencilViews, "Invalid pEffectBuffer: DSV count mismatch." );
-
- pVar->Data.pDepthStencilView = &m_pEffect->m_pDepthStencilViews[m_pEffect->m_DepthStencilViewCount];
- m_pEffect->m_DepthStencilViewCount += elementsToRead;
- }
- else
- {
- VHD( E_FAIL, "Invalid pEffectBuffer: DSV count mismatch." );
- }
-
- // Read annotations
- VH( LoadAnnotations(&pVar->AnnotationCount, &pVar->pAnnotations) );
- }
-lExit:
- return hr;
-}
-
-
-// Read info from the compiled blob and initialize an interface variable
-HRESULT CEffectLoader::LoadInterfaceVariables()
-{
- HRESULT hr = S_OK;
- uint32_t iBlock;
- uint32_t cBlocks;
-
- cBlocks = m_pHeader->cInterfaceVariables;
-
- for (iBlock=0; iBlock<cBlocks; iBlock++)
- {
- SBinaryInterfaceVariable *psBlock;
- SGlobalVariable *pVar;
- SType *pType;
- uint32_t elementsToRead;
- CCheckedDword chkElementsTotal;
- uint32_t elementsTotal;
- void *pDefaultValue;
-
- // Read variable info
- VHD( m_msStructured.Read((void**) &psBlock, sizeof(*psBlock)), "Invalid pEffectBuffer: cannot read interface block." );
- VBD( m_pEffect->m_VariableCount < (m_pHeader->Effect.cObjectVariables + m_pHeader->Effect.cNumericVariables + m_pHeader->cInterfaceVariables),
- "Internal loading error: variable count mismatch." );
- pVar = &m_pEffect->m_pVariables[m_pEffect->m_VariableCount];
-
- // Get type
- VH( LoadTypeAndAddToPool(&pType, psBlock->oType) );
-
- // Make sure the right polymorphic type is created
- VH( PlacementNewVariable(pVar, pType, false) );
-
- pVar->pEffect = m_pEffect;
- pVar->pType = pType;
- pVar->pCB = nullptr;
- pVar->ExplicitBindPoint = (uint32_t)-1;
- pVar->pSemantic = nullptr;
-
- // Get name
- VHD( GetStringAndAddToReflection(psBlock->oName, &pVar->pName), "Invalid pEffectBuffer: cannot read interface name." );
-
- m_pEffect->m_VariableCount++;
- elementsToRead = std::max<uint32_t>(1, pType->Elements);
- chkElementsTotal = elementsToRead;
-
- VBD( pType->IsInterface(), "Internal loading error: invlaid type for interface." );
-
- chkElementsTotal += m_pEffect->m_InterfaceCount;
- VHD( chkElementsTotal.GetValue(&elementsTotal), "Overflow: interface count." );
- VBD( elementsTotal <= m_pHeader->cInterfaceVariableElements, "Invalid pEffectBuffer: interface count mismatch." );
-
- pVar->Data.pInterface = &m_pEffect->m_pInterfaces[m_pEffect->m_InterfaceCount];
- m_pEffect->m_InterfaceCount += elementsToRead;
-
- // Get default value
- if (0 != psBlock->oDefaultValue)
- {
- VHD( m_msUnstructured.ReadAtOffset(psBlock->oDefaultValue, elementsToRead * sizeof(SBinaryInterfaceInitializer), &pDefaultValue),
- "Invalid pEffectBuffer: cannot read interface initializer offset." );
- for( size_t i=0; i < elementsToRead; i++ )
- {
- SBinaryInterfaceInitializer* pInterfaceInit = &((SBinaryInterfaceInitializer*)pDefaultValue)[i];
- LPCSTR pClassInstanceName;
- VHD( m_msUnstructured.ReadAtOffset(pInterfaceInit->oInstanceName, &pClassInstanceName), "Invalid pEffectBuffer: cannot read interface initializer." );
-
- SGlobalVariable *pCIVariable = m_pEffect->FindVariableByName(pClassInstanceName);
- VBD( pCIVariable != nullptr, "Loading error: cannot find class instance for interface initializer." );
- VBD( pCIVariable->pType->IsClassInstance(), "Loading error: variable type mismatch for interface initializer." );
- if( pInterfaceInit->ArrayIndex == (uint32_t)-1 )
- {
- VBD( pCIVariable->pType->Elements == 0, "Loading error: array mismatch for interface initializer." );
- pVar->Data.pInterface[i].pClassInstance = (SClassInstanceGlobalVariable*)pCIVariable;
- }
- else
- {
- VBD( pCIVariable->pType->Elements > 0, "Loading error: array mismatch for interface initializer." );
- VBD( pInterfaceInit->ArrayIndex < pCIVariable->pType->Elements, "Loading error: array index out of range." );
-
- SMember* pMember = (SMember*)pCIVariable->GetElement( pInterfaceInit->ArrayIndex );
- VBD( pMember->IsValid(), "Loading error: cannot find member by name." );
- VBD( pMember->pType->IsClassInstance(), "Loading error: member type mismatch for interface initializer." );
- pVar->Data.pInterface[i].pClassInstance = (SClassInstanceGlobalVariable*)pMember;
- }
- }
- }
-
-
- // Read annotations
- VH( LoadAnnotations(&pVar->AnnotationCount, &pVar->pAnnotations) );
- }
-lExit:
- return hr;
-}
-
-
-// Read info from the compiled blob and initialize a group (and contained techniques and passes)
-HRESULT CEffectLoader::LoadGroups()
-{
- HRESULT hr = S_OK;
- uint32_t TechniquesInEffect = 0;
-
- for( size_t iGroup=0; iGroup<m_pHeader->cGroups; iGroup++ )
- {
- SGroup *pGroup = &m_pEffect->m_pGroups[iGroup];
- SBinaryGroup *psGroup;
-
- // Read group info
- VHD( m_msStructured.Read((void**) &psGroup, sizeof(*psGroup)), "Invalid pEffectBuffer: cannot read group." );
- pGroup->TechniqueCount = psGroup->cTechniques;
- VN( pGroup->pTechniques = PRIVATENEW STechnique[pGroup->TechniqueCount] );
- VHD( GetStringAndAddToReflection(psGroup->oName, &pGroup->pName), "Invalid pEffectBuffer: cannot read group name." );
-
- if( pGroup->pName == nullptr )
- {
- VBD( m_pEffect->m_pNullGroup == nullptr, "Internal loading error: multiple nullptr groups." );
- m_pEffect->m_pNullGroup = pGroup;
- }
-
- // Read annotations
- VH( LoadAnnotations(&pGroup->AnnotationCount, &pGroup->pAnnotations) );
-
- for( size_t iTechnique=0; iTechnique < psGroup->cTechniques; iTechnique++ )
- {
- VH( LoadTechnique( &pGroup->pTechniques[iTechnique] ) );
- }
- TechniquesInEffect += psGroup->cTechniques;
- }
-
- VBD( TechniquesInEffect == m_pHeader->cTechniques, "Loading error: technique count mismatch." );
- m_pEffect->m_TechniqueCount = m_pHeader->cTechniques;
- m_pEffect->m_GroupCount = m_pHeader->cGroups;
-
-lExit:
- return hr;
-}
-
-
-// Read info from the compiled blob and initialize a technique (and contained passes)
-HRESULT CEffectLoader::LoadTechnique( STechnique* pTech )
-{
- HRESULT hr = S_OK;
- uint32_t iPass;
-
- SBinaryTechnique *psTech;
-
- // Read technique info
- VHD( m_msStructured.Read((void**) &psTech, sizeof(*psTech)), "Invalid pEffectBuffer: cannot read technique." );
- pTech->PassCount = psTech->cPasses;
- VN( pTech->pPasses = PRIVATENEW SPassBlock[pTech->PassCount] );
- VHD( GetStringAndAddToReflection(psTech->oName, &pTech->pName), "Invalid pEffectBuffer: cannot read technique name." );
-
- // Read annotations
- VH( LoadAnnotations(&pTech->AnnotationCount, &pTech->pAnnotations) );
-
- for (iPass=0; iPass<psTech->cPasses; iPass++)
- {
- SBinaryPass *psPass;
- SPassBlock *pPass = &pTech->pPasses[iPass];
-
- // Read pass info
- VHD( m_msStructured.Read((void**) &psPass, sizeof(SBinaryPass)), "Invalid pEffectBuffer: cannot read pass." );
- VHD( GetStringAndAddToReflection(psPass->oName, &pPass->pName), "Invalid pEffectBuffer: cannot read pass name." );
-
- // Read annotations
- VH( LoadAnnotations(&pPass->AnnotationCount, &pPass->pAnnotations) );
-
- VH( LoadAssignments( psPass->cAssignments, &pPass->pAssignments, (uint8_t*)pPass, &pPass->BackingStore.RenderTargetViewCount, &pPass->AssignmentCount ) );
- VBD( pPass->BackingStore.RenderTargetViewCount <= D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, "Invalid pEffectBuffer: too many RTVs in pass." );
-
- // Initialize other pass information
- pPass->pEffect = m_pEffect;
- pPass->BlockType = EBT_Pass;
- }
-
-lExit:
- return hr;
-}
-
-
-// Read info from the compiled blob and initialize a set of annotations
-HRESULT CEffectLoader::LoadAnnotations(uint32_t *pcAnnotations, SAnnotation **ppAnnotations)
-{
- HRESULT hr = S_OK;
- uint32_t cAnnotations, i, oData;
- SAnnotation *pAnnotations = nullptr;
-
- VHD( m_msStructured.Read(&cAnnotations), "Invalid pEffectBuffer: cannot read anootation count." );
-
- if (cAnnotations)
- {
- uint32_t annotationsSize;
- CCheckedDword chkAnnotationsSize;
-
- chkAnnotationsSize = cAnnotations;
- chkAnnotationsSize *= sizeof(SAnnotation);
- VHD( chkAnnotationsSize.GetValue(&annotationsSize), "Overflow in annotations." );
-
- // we allocate raw bytes for annotations because they are polymorphic types that need to be placement new'ed
- VN( pAnnotations = (SAnnotation *) PRIVATENEW uint8_t[annotationsSize] );
-
- for (i=0; i<cAnnotations; i++)
- {
- SBinaryAnnotation *psAnnotation;
- SAnnotation *pAn = &pAnnotations[i];
- SType *pType;
-
- VHD( m_msStructured.Read((void**) &psAnnotation, sizeof(SBinaryAnnotation)), "Invalid pEffectBuffer: cannot read annotation." );
-
- VH( LoadTypeAndAddToPool(&pType, psAnnotation->oType) );
-
- // Make sure the right polymorphic type is created
- VH( PlacementNewVariable(pAn, pType, true) );
-
- pAn->pEffect = m_pEffect;
- pAn->pType = pType;
-
- VHD( GetStringAndAddToReflection(psAnnotation->oName, &pAn->pName), "Invalid pEffectBuffer: cannot read annotation name." );
-
- if (pType->IsObjectType(EOT_String))
- {
- uint32_t cElements = std::max<uint32_t>(1, pType->Elements);
- uint32_t j;
- VN( pAn->Data.pString = PRIVATENEW SString[cElements] );
- for (j = 0; j < cElements; ++ j)
- {
- // Read initializer offset
- VHD( m_msStructured.Read(&oData), "Invalid pEffectBuffer: cannot read string." );
-#pragma warning( disable : 6011 )
- VHD( GetStringAndAddToReflection(oData, &pAn->Data.pString[j].pString), "Invalid pEffectBuffer: cannot read string initializer." );
- }
- }
- else if (pType->BelongsInConstantBuffer())
- {
- void *pDefaultValue;
- uint32_t bytesUnpacked;
-
- // Read initializer offset
- VHD( m_msStructured.Read(&oData), "Invalid pEffectBuffer: cannot read annotation." );
-
- VBD( oData != 0, "Invalid pEffectBuffer: invalid anotation offset." );
-
- VN( pAn->Data.pGeneric = PRIVATENEW uint8_t[pType->TotalSize] );
- ZeroMemory(pAn->Data.pGeneric, pType->TotalSize);
- VHD( m_msUnstructured.ReadAtOffset(oData, pType->PackedSize, &pDefaultValue), "Invalid pEffectBuffer: cannot read variable default value." );
- VH( UnpackData((uint8_t*) pAn->Data.pGeneric, (uint8_t*) pDefaultValue, pType->PackedSize, pType, &bytesUnpacked) );
- VBD( bytesUnpacked == pType->PackedSize, "Invalid pEffectBuffer: packed sizes to not match." );
- }
- else
- {
- VHD( E_FAIL, "Invalid pEffectBuffer: invalid annotation type." );
- }
- }
- }
-
- *pcAnnotations = cAnnotations;
- *ppAnnotations = pAnnotations;
-lExit:
-
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Build shader block dependencies from shader metadata
-//////////////////////////////////////////////////////////////////////////
-
-//
-// Grabs shader resource dependency information from the bytecode of the shader
-// (cbuffer, tbuffer, texture, buffer, sampler, and UAV dependencies),
-// and sets up the given SShaderBlock to point to the dependencies within the effect
-//
-HRESULT CEffectLoader::GrabShaderData(SShaderBlock *pShaderBlock)
-{
- HRESULT hr = S_OK;
- CEffectVector<SRange> vRanges[ER_Count], *pvRange;
-
- SRange *pRange = nullptr;
- CEffectVector<SConstantBuffer*> vTBuffers;
-
- //////////////////////////////////////////////////////////////////////////
- // Step 1: iterate through the resource binding structures and build
- // an "optimized" list of all of the dependencies
-
- D3D11_SHADER_DESC ShaderDesc;
- hr = pShaderBlock->pReflectionData->pReflection->GetDesc( &ShaderDesc );
- if ( FAILED(hr) )
- return hr;
-
- // Since we have the shader desc, let's find out if this is a nullptr GS
- if( D3D11_SHVER_GET_TYPE( ShaderDesc.Version ) == D3D11_SHVER_VERTEX_SHADER && pShaderBlock->GetShaderType() == EOT_GeometryShader )
- {
- pShaderBlock->pReflectionData->IsNullGS = true;
- }
-
- pShaderBlock->CBDepCount = pShaderBlock->ResourceDepCount = pShaderBlock->TBufferDepCount = pShaderBlock->SampDepCount = 0;
- pShaderBlock->UAVDepCount = pShaderBlock->InterfaceDepCount = 0;
-
- for(uint32_t i = 0; i < ShaderDesc.BoundResources; i++)
- {
- LPCSTR pName;
- uint32_t bindPoint, size;
- ERanges eRange = ER_CBuffer;
- SShaderResource *pShaderResource = nullptr;
- SUnorderedAccessView *pUnorderedAccessView = nullptr;
- SSamplerBlock *pSampler = nullptr;
- SConstantBuffer *pCB = nullptr;
- SVariable *pVariable = nullptr;
- bool isFX9TextureLoad = false;
- D3D11_SHADER_INPUT_BIND_DESC ResourceDesc;
-
- pShaderBlock->pReflectionData->pReflection->GetResourceBindingDesc( i, &ResourceDesc );
-
- // HUGE ASSUMPTION: the bindpoints we read in the shader metadata are sorted;
- // i.e. bindpoints are steadily increasing
- // If this assumption is not met, then we will hit an assert below
-
- pName = ResourceDesc.Name;
- bindPoint = ResourceDesc.BindPoint;
- size = ResourceDesc.BindCount;
-
- switch( ResourceDesc.Type )
- {
- case D3D_SIT_CBUFFER:
- eRange = ER_CBuffer;
-
- pCB = m_pEffect->FindCB(pName);
- VBD( nullptr != pCB, "Loading error: cannot find cbuffer." );
- VBD( size == 1, "Loading error: cbuffer arrays are not supported." );
- break;
-
- case D3D_SIT_TBUFFER:
- eRange = ER_Texture;
-
- pCB = m_pEffect->FindCB(pName);
- VBD( nullptr != pCB, "Loading error: cannot find tbuffer." );
- VBD( false != pCB->IsTBuffer, "Loading error: cbuffer found where tbuffer is expected." );
- VBD( size == 1, "Loading error: tbuffer arrays are not supported." );
- pShaderResource = &pCB->TBuffer;
- break;
-
- case D3D_SIT_TEXTURE:
- case D3D_SIT_STRUCTURED:
- case D3D_SIT_BYTEADDRESS:
- {
- eRange = ER_Texture;
-
- pVariable = m_pEffect->FindVariableByNameWithParsing(pName);
- VBD( pVariable != nullptr, "Loading error: cannot find SRV variable." );
- uint32_t elements = std::max<uint32_t>(1, pVariable->pType->Elements);
- VBD( size <= elements, "Loading error: SRV array size mismatch." );
-
- if (pVariable->pType->IsShaderResource())
- {
- // this is just a straight texture assignment
- pShaderResource = pVariable->Data.pShaderResource;
- }
- else
- {
- // This is a FX9/HLSL9-style texture load instruction that specifies only a sampler
- VBD( pVariable->pType->IsSampler(), "Loading error: shader dependency is neither an SRV nor sampler.");
- isFX9TextureLoad = true;
- pSampler = pVariable->Data.pSampler;
- // validate that all samplers actually used (i.e. based on size, not elements) in this variable have a valid TEXTURE assignment
- for (size_t j = 0; j < size; ++ j)
- {
- if (nullptr == pSampler[j].BackingStore.pTexture)
- {
- // print spew appropriately for samplers vs sampler arrays
- if (0 == pVariable->pType->Elements)
- {
- DPF(0, "%s: Sampler %s does not have a texture bound to it, even though the sampler is used in a DX9-style texture load instruction", g_szEffectLoadArea, pName);
- }
- else
- {
- DPF(0, "%s: Sampler %s[%zu] does not have a texture bound to it, even though the sampler array is used in a DX9-style texture load instruction", g_szEffectLoadArea, pName, j);
- }
-
- VH( E_FAIL );
- }
- }
- }
- }
- break;
-
- case D3D_SIT_UAV_RWTYPED:
- case D3D_SIT_UAV_RWSTRUCTURED:
- case D3D_SIT_UAV_RWBYTEADDRESS:
- case D3D_SIT_UAV_APPEND_STRUCTURED:
- case D3D_SIT_UAV_CONSUME_STRUCTURED:
- case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
- eRange = ER_UnorderedAccessView;
-
- pVariable = m_pEffect->FindVariableByNameWithParsing(pName);
- VBD( pVariable != nullptr, "Loading error: cannot find UAV variable." );
- VBD( size <= std::max<uint32_t>(1, pVariable->pType->Elements), "Loading error: UAV array index out of range." );
- VBD( pVariable->pType->IsUnorderedAccessView(), "Loading error: UAV variable expected." );
- pUnorderedAccessView = pVariable->Data.pUnorderedAccessView;
- break;
-
- case D3D_SIT_SAMPLER:
- eRange = ER_Sampler;
-
- pVariable = m_pEffect->FindVariableByNameWithParsing(pName);
- VBD( pVariable != nullptr, "Loading error: cannot find sampler variable." );
- VBD( size <= std::max<uint32_t>(1, pVariable->pType->Elements), "Loading error: sampler array index out of range." );
- VBD( pVariable->pType->IsSampler(), "Loading error: sampler variable expected." );
- pSampler = pVariable->Data.pSampler;
- break;
-
- default:
- VHD( E_FAIL, "Internal loading error: unexpected shader dependency type." );
- };
-
- //
- // Here's where the "optimized" part comes in; whenever there's
- // a resource dependency, see if it's located contiguous to
- // an existing resource dependency and merge them together
- // if possible
- //
- uint32_t rangeCount;
- pvRange = &vRanges[eRange];
- rangeCount = pvRange->GetSize();
-
- if ( rangeCount > 0 )
- {
- // Can we continue an existing range?
- pRange = &( (*pvRange)[rangeCount - 1] );
-
- // Make sure that bind points are strictly increasing,
- // otherwise this algorithm breaks and we'd get worse runtime performance
- assert(pRange->last <= bindPoint);
-
- if ( pRange->last != bindPoint )
- {
- if( eRange != ER_UnorderedAccessView )
- {
- // No we can't. Begin a new range by setting rangeCount to 0 and triggering the next IF
- rangeCount = 0;
- }
- else
- {
- // UAVs will always be located in one range, as they are more expensive to set
- while(pRange->last < bindPoint)
- {
- VHD( pRange->vResources.Add(&g_NullUnorderedAccessView), "Internal loading error: cannot add UAV to range." );
- pRange->last++;
- }
- }
- }
- }
-
- if ( rangeCount == 0 )
- {
- VN( pRange = pvRange->Add() );
- pRange->start = bindPoint;
- }
-
- pRange->last = bindPoint + size;
-
- switch( ResourceDesc.Type )
- {
- case D3D_SIT_CBUFFER:
- VHD( pRange->vResources.Add(pCB), "Internal loading error: cannot add cbuffer to range." );
- break;
- case D3D_SIT_TBUFFER:
- VHD( pRange->vResources.Add(pShaderResource), "Internal loading error: cannot add tbuffer to range." );
- VHD( vTBuffers.Add( (SConstantBuffer*)pCB ), "Internal loading error: cannot add tbuffer to vector." );
- break;
- case D3D_SIT_TEXTURE:
- case D3D_SIT_STRUCTURED:
- case D3D_SIT_BYTEADDRESS:
- if (isFX9TextureLoad)
- {
- // grab all of the textures from each sampler
- for (size_t j = 0; j < size; ++ j)
- {
- VHD( pRange->vResources.Add(pSampler[j].BackingStore.pTexture), "Internal loading error: cannot add SRV to range." );
- }
- }
- else
- {
- // add the whole array
- for (size_t j = 0; j < size; ++ j)
- {
- VHD( pRange->vResources.Add(pShaderResource + j), "Internal loading error: cannot add SRV to range." );
- }
- }
- break;
- case D3D_SIT_UAV_RWTYPED:
- case D3D_SIT_UAV_RWSTRUCTURED:
- case D3D_SIT_UAV_RWBYTEADDRESS:
- case D3D_SIT_UAV_APPEND_STRUCTURED:
- case D3D_SIT_UAV_CONSUME_STRUCTURED:
- case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:
- // add the whole array
- for (size_t j = 0; j < size; ++ j)
- {
- VHD( pRange->vResources.Add(pUnorderedAccessView + j), "Internal loading error: cannot add UAV to range." );
- }
- break;
- case D3D_SIT_SAMPLER:
- // add the whole array
- for (size_t j = 0; j < size; ++ j)
- {
- VHD( pRange->vResources.Add(pSampler + j), "Internal loading error: cannot add sampler to range." );
- }
- break;
- default:
- VHD( E_FAIL, "Internal loading error: unexpected shader dependency type." );
- }
- }
-
-
- //////////////////////////////////////////////////////////////////////////
- // Step 2: iterate through the interfaces and build
- // an "optimized" list of all of the dependencies
-
- uint32_t NumInterfaces = pShaderBlock->pReflectionData->pReflection->GetNumInterfaceSlots();
- uint32_t CurInterfaceParameter = 0;
- if( NumInterfaces > 0 )
- {
- assert( ShaderDesc.ConstantBuffers > 0 );
-
- for( uint32_t i=0; i < ShaderDesc.ConstantBuffers; i++ )
- {
- ID3D11ShaderReflectionConstantBuffer* pCB = pShaderBlock->pReflectionData->pReflection->GetConstantBufferByIndex(i);
- VN( pCB );
- D3D11_SHADER_BUFFER_DESC CBDesc;
- VHD( pCB->GetDesc( &CBDesc ), "Internal loading error: cannot get CB desc." );
- if( CBDesc.Type != D3D11_CT_INTERFACE_POINTERS )
- {
- continue;
- }
-
- for( uint32_t iVar=0; iVar < CBDesc.Variables; iVar++ )
- {
- ID3D11ShaderReflectionVariable* pInterfaceVar = pCB->GetVariableByIndex( iVar );
- VN( pInterfaceVar );
- D3D11_SHADER_VARIABLE_DESC InterfaceDesc;
- VHD( pInterfaceVar->GetDesc(&InterfaceDesc), "Internal load error: cannot get IV desc.");
-
- LPCSTR pName;
- uint32_t bindPoint, size;
- SGlobalVariable *pVariable = nullptr;
- SInterface *pInterface = nullptr;
- uint32_t VariableElements;
-
- pName = InterfaceDesc.Name;
- bindPoint = InterfaceDesc.StartOffset;
- size = InterfaceDesc.Size;
-
- if( bindPoint == (uint32_t)-1 )
- {
- continue;
- }
-
- assert( InterfaceDesc.uFlags & D3D11_SVF_INTERFACE_POINTER );
- if( InterfaceDesc.uFlags & D3D11_SVF_INTERFACE_PARAMETER )
- {
- // This interface pointer is a parameter to the shader
- if( pShaderBlock->pReflectionData->InterfaceParameterCount == 0 )
- {
- // There may be no interface parameters in this shader if it was compiled but had no interfaced bound to it.
- // The shader cannot be set (correctly) in any pass.
- continue;
- }
- else
- {
- VBD( CurInterfaceParameter < pShaderBlock->pReflectionData->InterfaceParameterCount,
- "Internal loading error: interface count mismatch.");
- SShaderBlock::SInterfaceParameter* pInterfaceInfo;
- pInterfaceInfo = &pShaderBlock->pReflectionData->pInterfaceParameters[CurInterfaceParameter];
- ++CurInterfaceParameter;
- SGlobalVariable *pParent = m_pEffect->FindVariableByName(pInterfaceInfo->pName);
- VBD( pParent != nullptr, "Loading error: cannot find parent type." );
- if( pInterfaceInfo->Index == (uint32_t)-1 )
- {
- pVariable = pParent;
- VariableElements = pVariable->pType->Elements;
- }
- else
- {
- // We want a specific index of the variable (ex. "MyVar[2]")
- VBD( size == 1, "Loading error: interface array type mismatch." );
- pVariable = (SGlobalVariable*)pParent->GetElement( pInterfaceInfo->Index );
- VBD( pVariable->IsValid(), "Loading error: interface array index out of range." );
- VariableElements = 0;
- }
- }
- }
- else
- {
- // This interface pointer is a global interface used in the shader
- pVariable = m_pEffect->FindVariableByName(pName);
- VBD( pVariable != nullptr, "Loading error: cannot find interface variable." );
- VariableElements = pVariable->pType->Elements;
- }
- VBD( size <= std::max<uint32_t>(1, VariableElements), "Loading error: interface array size mismatch." );
- if( pVariable->pType->IsInterface() )
- {
- pInterface = pVariable->Data.pInterface;
- }
- else if( pVariable->pType->IsClassInstance() )
- {
- // For class instances, we create background interfaces which point to the class instance. This is done so
- // the shader can always expect SInterface dependencies, rather than a mix of SInterfaces and class instances
- VN( pInterface = PRIVATENEW SInterface[size] );
- if( VariableElements == 0 )
- {
- assert( size == 1 );
- pInterface[0].pClassInstance = (SClassInstanceGlobalVariable*)pVariable;
- m_BackgroundInterfaces.Add( &pInterface[0] );
- }
- else
- {
- // Fill each element of the SInstance array individually
- VBD( size == VariableElements, "Loading error: class instance array size mismatch." );
- for( uint32_t iElement=0; iElement < size; iElement++ )
- {
- SGlobalVariable *pElement = (SGlobalVariable*)pVariable->GetElement( iElement );
- VBD( pElement->IsValid(), "Internal loading error: class instance array index out of range." );
- pInterface[iElement].pClassInstance = (SClassInstanceGlobalVariable*)pElement;
- m_BackgroundInterfaces.Add( &pInterface[iElement] );
- }
- }
- }
- else
- {
- VHD( E_FAIL, "Loading error: invalid interface initializer variable type.");
- }
-
- //
- // Here's where the "optimized" part comes in; whenever there's
- // a resource dependency, see if it's located contiguous to
- // an existing resource dependency and merge them together
- // if possible
- //
- uint32_t rangeCount;
- pvRange = &vRanges[ER_Interfaces];
- rangeCount = pvRange->GetSize();
-
- VBD( rangeCount <= 1, "Internal loading error: invalid range count." );
-
- if ( rangeCount == 0 )
- {
- VN( pRange = pvRange->Add() );
- pRange->start = pRange->last = 0;
- }
- else
- {
- pRange = &( (*pvRange)[0] );
- }
-
- if( bindPoint < pRange->last )
- {
- // add interfaces into the range that already exists
- VBD( bindPoint + size < pRange->last, "Internal loading error: range overlap." );
- for( uint32_t j = 0; j < size; ++ j )
- {
- pRange->vResources[j + bindPoint] = pInterface + j;
- }
- }
- else
- {
- // add interfaces to the end of the range
-
- // add missing interface slots, if necessary
- while(pRange->last < bindPoint)
- {
- VHD( pRange->vResources.Add(&g_NullInterface), "Internal loading error: cannot add nullptr interface to range." );
- pRange->last++;
- }
-
- assert( bindPoint == pRange->last );
- for( size_t j=0; j < size; ++ j )
- {
- VHD( pRange->vResources.Add(pInterface + j), "Internal loading error: cannot at interface to range." );
- }
- pRange->last = bindPoint + size;
- }
- }
-
- // There is only one interface cbuffer
- break;
- }
- }
-
- //////////////////////////////////////////////////////////////////////////
- // Step 3: allocate room in pShaderBlock for all of the dependency
- // pointers and then hook them up
-
- pShaderBlock->SampDepCount = vRanges[ ER_Sampler ].GetSize();
- pShaderBlock->CBDepCount = vRanges[ ER_CBuffer ].GetSize();
- pShaderBlock->InterfaceDepCount = vRanges[ ER_Interfaces ].GetSize();
- pShaderBlock->ResourceDepCount = vRanges[ ER_Texture ].GetSize();
- pShaderBlock->UAVDepCount = vRanges[ ER_UnorderedAccessView ].GetSize();
- pShaderBlock->TBufferDepCount = vTBuffers.GetSize();
-
- VN( pShaderBlock->pSampDeps = PRIVATENEW SShaderSamplerDependency[pShaderBlock->SampDepCount] );
- VN( pShaderBlock->pCBDeps = PRIVATENEW SShaderCBDependency[pShaderBlock->CBDepCount] );
- VN( pShaderBlock->pInterfaceDeps = PRIVATENEW SInterfaceDependency[pShaderBlock->InterfaceDepCount] );
- VN( pShaderBlock->pResourceDeps = PRIVATENEW SShaderResourceDependency[pShaderBlock->ResourceDepCount] );
- VN( pShaderBlock->pUAVDeps = PRIVATENEW SUnorderedAccessViewDependency[pShaderBlock->UAVDepCount] );
- VN( pShaderBlock->ppTbufDeps = PRIVATENEW SConstantBuffer*[pShaderBlock->TBufferDepCount] );
-
- for (size_t i=0; i<pShaderBlock->CBDepCount; ++i)
- {
- SShaderCBDependency *pDep = &pShaderBlock->pCBDeps[i];
-
- pRange = &vRanges[ER_CBuffer][i];
-
- pDep->StartIndex = pRange->start;
- pDep->Count = pRange->last - pDep->StartIndex;
- pDep->ppFXPointers = PRIVATENEW SConstantBuffer*[ pDep->Count ];
- pDep->ppD3DObjects = PRIVATENEW ID3D11Buffer*[ pDep->Count ];
-
- assert(pDep->Count == pRange->vResources.GetSize());
- for (size_t j=0; j<pDep->Count; ++j)
- {
- pDep->ppFXPointers[j] = (SConstantBuffer *)pRange->vResources[j];
- pDep->ppD3DObjects[j] = nullptr;
- }
- }
-
- for (size_t i=0; i<pShaderBlock->SampDepCount; ++i)
- {
- SShaderSamplerDependency *pDep = &pShaderBlock->pSampDeps[i];
-
- pRange = &vRanges[ER_Sampler][i];
-
- pDep->StartIndex = pRange->start;
- pDep->Count = pRange->last - pDep->StartIndex;
- pDep->ppFXPointers = PRIVATENEW SSamplerBlock*[ pDep->Count ];
- pDep->ppD3DObjects = PRIVATENEW ID3D11SamplerState*[ pDep->Count ];
-
- assert(pDep->Count == pRange->vResources.GetSize());
- for (size_t j=0; j<pDep->Count; ++j)
- {
- pDep->ppFXPointers[j] = (SSamplerBlock *) pRange->vResources[j];
- pDep->ppD3DObjects[j] = nullptr;
- }
- }
-
- for (size_t i=0; i<pShaderBlock->InterfaceDepCount; ++i)
- {
- SInterfaceDependency *pDep = &pShaderBlock->pInterfaceDeps[i];
-
- pRange = &vRanges[ER_Interfaces][i];
-
- pDep->StartIndex = pRange->start;
- pDep->Count = pRange->last - pDep->StartIndex;
- pDep->ppFXPointers = PRIVATENEW SInterface*[ pDep->Count ];
- pDep->ppD3DObjects = PRIVATENEW ID3D11ClassInstance*[ pDep->Count ];
-
- assert(pDep->Count == pRange->vResources.GetSize());
- for (size_t j=0; j<pDep->Count; ++j)
- {
- pDep->ppFXPointers[j] = (SInterface *) pRange->vResources[j];
- pDep->ppD3DObjects[j] = nullptr;
- }
- }
-
- for (size_t i=0; i<pShaderBlock->ResourceDepCount; ++i)
- {
- SShaderResourceDependency *pDep = &pShaderBlock->pResourceDeps[i];
-
- pRange = &vRanges[ER_Texture][i];
-
- pDep->StartIndex = pRange->start;
- pDep->Count = pRange->last - pDep->StartIndex;
- pDep->ppFXPointers = PRIVATENEW SShaderResource*[ pDep->Count ];
- pDep->ppD3DObjects = PRIVATENEW ID3D11ShaderResourceView*[ pDep->Count ];
-
- assert(pDep->Count == pRange->vResources.GetSize());
- for (size_t j=0; j<pDep->Count; ++j)
- {
- pDep->ppFXPointers[j] = (SShaderResource *) pRange->vResources[j];
- pDep->ppD3DObjects[j] = nullptr;
- }
- }
-
- for (size_t i=0; i<pShaderBlock->UAVDepCount; ++i)
- {
- SUnorderedAccessViewDependency *pDep = &pShaderBlock->pUAVDeps[i];
-
- pRange = &vRanges[ER_UnorderedAccessView][i];
-
- pDep->StartIndex = pRange->start;
- pDep->Count = pRange->last - pDep->StartIndex;
- pDep->ppFXPointers = PRIVATENEW SUnorderedAccessView*[ pDep->Count ];
- pDep->ppD3DObjects = PRIVATENEW ID3D11UnorderedAccessView*[ pDep->Count ];
-
- assert(pDep->Count == pRange->vResources.GetSize());
- for (size_t j=0; j<pDep->Count; ++j)
- {
- pDep->ppFXPointers[j] = (SUnorderedAccessView *) pRange->vResources[j];
- pDep->ppD3DObjects[j] = nullptr;
- }
- }
-
- if (pShaderBlock->TBufferDepCount > 0)
- {
- memcpy(pShaderBlock->ppTbufDeps, &vTBuffers[0], pShaderBlock->TBufferDepCount * sizeof(SConstantBuffer*));
- }
-
-lExit:
- return hr;
-}
-
-// Create shader reflection interface and grab dependency info
-HRESULT CEffectLoader::BuildShaderBlock(SShaderBlock *pShaderBlock)
-{
- HRESULT hr = S_OK;
-
- // unused shader block? that's not right
- VBD( pShaderBlock->pVT != nullptr, "Internal loading error: nullptr shader vtable." );
-
- assert(pShaderBlock->pD3DObject == nullptr);
-
- if (nullptr == pShaderBlock->pReflectionData)
- {
- // File contains a shader variable without an assigned shader, or this is a null assignment.
- // Usually, this is called by one of these guys:
- // SetVertexShader( nullptr );
- // or
- // vertexshader g_VS = nullptr;
- return S_OK;
- }
-
- // Initialize the reflection interface
- VHD( D3DReflect( pShaderBlock->pReflectionData->pBytecode, pShaderBlock->pReflectionData->BytecodeLength, IID_ID3D11ShaderReflection, (void**)&pShaderBlock->pReflectionData->pReflection ),
- "Internal loading error: cannot create shader reflection object." );
-
- // Get dependencies
- VH( GrabShaderData( pShaderBlock ) );
-
- // Grab input signatures for VS
- if( EOT_VertexShader == pShaderBlock->GetShaderType() )
- {
- assert( pShaderBlock->pInputSignatureBlob == nullptr );
- VHD( D3DGetBlobPart( pShaderBlock->pReflectionData->pBytecode, pShaderBlock->pReflectionData->BytecodeLength,
- D3D_BLOB_INPUT_SIGNATURE_BLOB, 0,
- &pShaderBlock->pInputSignatureBlob ),
- "Internal loading error: cannot get input signature." );
- }
-
-lExit:
- return hr;
-}
-
-#undef PRIVATENEW
-
-
-//////////////////////////////////////////////////////////////////////////
-// Code to relocate data to private heaps (reflection & runtime effect)
-//
-// Important note about alignment: all reasonable chunks of data are
-// machine word aligned (that is, any piece of data moved as a whole is
-// aligned as a whole. This means that when computing m_ReflectionMemory
-// or m_EffectMemory, each addition is aligned. This also means
-// that, when later relocating that same memory, you must call MoveData
-// or MoveString on the same chunks that were aligned. This is
-// because: Align(a * b) != a * Align(b).
-//////////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////////
-// Reflection reallocation code
-//////////////////////////////////////////////////////////////////////////
-
-HRESULT CEffectLoader::CalculateAnnotationSize(uint32_t cAnnotations, SAnnotation *pAnnotations)
-{
- HRESULT hr = S_OK;
- uint32_t i;
-
- m_ReflectionMemory += AlignToPowerOf2(cAnnotations * sizeof(SAnnotation), c_DataAlignment);
- for (i=0; i<cAnnotations; i++)
- {
- if (pAnnotations[i].pType->BelongsInConstantBuffer())
- {
- m_ReflectionMemory += AlignToPowerOf2(pAnnotations[i].pType->TotalSize, c_DataAlignment);
- }
- else
- {
- VBD( pAnnotations[i].pType->IsObjectType(EOT_String), "Invalid pEffectBuffer: invalid annotation type." );
-
- uint32_t cElements = std::max<uint32_t>(1, pAnnotations[i].pType->Elements);
-
- m_ReflectionMemory += AlignToPowerOf2(cElements * sizeof(SString), c_DataAlignment);
-
- }
- }
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::ReallocateAnnotationData(uint32_t cAnnotations, SAnnotation **ppAnnotations)
-{
- HRESULT hr = S_OK;
- uint32_t i;
- SAnnotation *pAnnotations;
-
- VHD( m_pReflection->m_Heap.MoveData((void**) ppAnnotations, cAnnotations * sizeof(SAnnotation)),
- "Internal loading error: cannot move annotation data." );
- pAnnotations = *ppAnnotations;
-
- for (i=0; i<cAnnotations; i++)
- {
- SAnnotation *pAn = &pAnnotations[i];
- pAn->pEffect = m_pEffect;
-
- VHD( m_pReflection->m_Heap.MoveString(&pAn->pName), "Internal loading error: cannot move annotation name." );
-
- // Reallocate type later
- if (pAn->pType->BelongsInConstantBuffer())
- {
- VHD( m_pReflection->m_Heap.MoveData( &pAn->Data.pGeneric, pAn->pType->TotalSize ), "Internal loading error: cannot move annotation data." );
- }
- else if (pAnnotations[i].pType->IsObjectType(EOT_String))
- {
- uint32_t cElements = std::max<uint32_t>(1, pAn->pType->Elements);
-
- VHD( m_pReflection->m_Heap.MoveData((void**) &pAn->Data.pString, cElements * sizeof(SString)), "Internal loading error: cannot move annotation string." );
- for (size_t j = 0; j < cElements; ++ j)
- {
- VHD( m_pReflection->m_Heap.MoveString(&pAn->Data.pString[j].pString), "Internal loading error: cannot move annotation string element." );
- }
- }
- else
- {
- VHD( E_FAIL, "Invalid pEffectBuffer: invalid annotation type." );
- }
- }
-
-lExit:
- return hr;
-}
-
-HRESULT CEffectLoader::InitializeReflectionDataAndMoveStrings( uint32_t KnownSize )
-{
- HRESULT hr = S_OK;
- uint32_t cbStrings;
- CEffectHeap *pHeap = &m_pReflection->m_Heap;
-
- // Get byte counts
- cbStrings = m_pEffect->m_StringCount * sizeof( SString );
-
- if( KnownSize )
- {
- m_ReflectionMemory = KnownSize;
- }
- else
- {
- m_ReflectionMemory += AlignToPowerOf2(cbStrings, c_DataAlignment);
-
- for (size_t i=0; i<m_pEffect->m_CBCount; i++)
- {
- VH( CalculateAnnotationSize(m_pEffect->m_pCBs[i].AnnotationCount, m_pEffect->m_pCBs[i].pAnnotations) );
- }
-
- for (size_t i=0; i<m_pEffect->m_VariableCount; i++)
- {
- VH( CalculateAnnotationSize(m_pEffect->m_pVariables[i].AnnotationCount, m_pEffect->m_pVariables[i].pAnnotations) );
- }
-
- for (size_t i=0; i<m_pEffect->m_GroupCount; i++)
- {
- VH( CalculateAnnotationSize(m_pEffect->m_pGroups[i].AnnotationCount, m_pEffect->m_pGroups[i].pAnnotations) );
-
- for (size_t j=0; j<m_pEffect->m_pGroups[i].TechniqueCount; j++)
- {
- VH( CalculateAnnotationSize(m_pEffect->m_pGroups[i].pTechniques[j].AnnotationCount, m_pEffect->m_pGroups[i].pTechniques[j].pAnnotations) );
-
- for (size_t k=0; k<m_pEffect->m_pGroups[i].pTechniques[j].PassCount; k++)
- {
- VH( CalculateAnnotationSize(m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].AnnotationCount, m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].pAnnotations) );
- }
- }
- }
-
- // Calculate shader reflection data size
- for (size_t i=0; i<m_pEffect->m_ShaderBlockCount; i++)
- {
- if (nullptr != m_pEffect->m_pShaderBlocks[i].pReflectionData)
- {
- m_ReflectionMemory += AlignToPowerOf2(sizeof(SShaderBlock::SReflectionData), c_DataAlignment);
- m_ReflectionMemory += AlignToPowerOf2(m_pEffect->m_pShaderBlocks[i].pReflectionData->BytecodeLength, c_DataAlignment);
- // stream out decl is handled as a string, and thus its size is already factored because of GetStringAndAddToReflection
- }
- }
- }
-
- VHD( pHeap->ReserveMemory(m_ReflectionMemory), "Internal loading error: failed to reserve reflection memory." );
-
- // Strings are handled separately because we are moving them to reflection
- m_pOldStrings = m_pEffect->m_pStrings;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pStrings, cbStrings), "Internal loading error: cannot move string data." );
- for(size_t i=0; i<m_pEffect->m_StringCount; i++)
- {
- VHD( pHeap->MoveString( &m_pEffect->m_pStrings[i].pString), "Internal loading error: cannot move string pointer." );
- }
-
-lExit:
- return hr;
-}
-
-// Move all reflection data to private heap
-HRESULT CEffectLoader::ReallocateReflectionData( bool Cloning )
-{
- HRESULT hr = S_OK;
- CEffectHeap *pHeap = &m_pReflection->m_Heap;
-
- for(size_t i=0; i<m_pEffect->m_CBCount; i++)
- {
- VHD( pHeap->MoveString( &m_pEffect->m_pCBs[i].pName ), "Internal loading error: cannot move CB name." );
- VH( ReallocateAnnotationData(m_pEffect->m_pCBs[i].AnnotationCount, &m_pEffect->m_pCBs[i].pAnnotations) );
- }
-
- for(size_t i=0; i<m_pEffect->m_VariableCount; i++)
- {
- VHD( pHeap->MoveString( &m_pEffect->m_pVariables[i].pName ), "Internal loading error: cannot move variable name." );
- VHD( pHeap->MoveString( &m_pEffect->m_pVariables[i].pSemantic ), "Internal loading error: cannot move variable semantic." );
- VH( ReallocateAnnotationData(m_pEffect->m_pVariables[i].AnnotationCount, &m_pEffect->m_pVariables[i].pAnnotations) );
- }
-
- for(size_t i=0; i<m_pEffect->m_GroupCount; i++)
- {
- VHD( pHeap->MoveString( &m_pEffect->m_pGroups[i].pName ), "Internal loading error: cannot move group name." );
- VH( ReallocateAnnotationData(m_pEffect->m_pGroups[i].AnnotationCount, &m_pEffect->m_pGroups[i].pAnnotations) );
-
- for(size_t j=0; j<m_pEffect->m_pGroups[i].TechniqueCount; j++)
- {
- VHD( pHeap->MoveString( &m_pEffect->m_pGroups[i].pTechniques[j].pName ), "Internal loading error: cannot move technique name." );
- VH( ReallocateAnnotationData(m_pEffect->m_pGroups[i].pTechniques[j].AnnotationCount, &m_pEffect->m_pGroups[i].pTechniques[j].pAnnotations) );
-
- for(size_t k=0; k<m_pEffect->m_pGroups[i].pTechniques[j].PassCount; k++)
- {
- VHD( pHeap->MoveString( &m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].pName ), "Internal loading error: cannot move pass name." );
- VH( ReallocateAnnotationData(m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].AnnotationCount, &m_pEffect->m_pGroups[i].pTechniques[j].pPasses[k].pAnnotations) );
- }
- }
- }
-
- if( !Cloning )
- {
- // When not cloning, every member in m_pMemberInterfaces is from a global variable, so we can take pName and pSemantic
- // from the parent variable, which were updated above
- for (size_t i = 0; i < m_pEffect->m_pMemberInterfaces.GetSize(); ++ i)
- {
- SMember* pMember = m_pEffect->m_pMemberInterfaces[i];
- SGlobalVariable* pTopLevelEntity = (SGlobalVariable*)pMember->pTopLevelEntity;
- VH( FixupVariablePointer( &pTopLevelEntity ) );
- pMember->pName = pTopLevelEntity->pName;
- pMember->pSemantic = pTopLevelEntity->pSemantic;
- }
- }
-
- // Move shader bytecode
- for (size_t i=0; i<m_pEffect->m_ShaderBlockCount; i++)
- {
- if (nullptr != m_pEffect->m_pShaderBlocks[i].pReflectionData)
- {
- VHD( pHeap->MoveData((void**)&m_pEffect->m_pShaderBlocks[i].pReflectionData, sizeof(SShaderBlock::SReflectionData)),
- "Internal loading error: cannot move shader reflection block." );
- VHD( pHeap->MoveData((void**)&m_pEffect->m_pShaderBlocks[i].pReflectionData->pBytecode, m_pEffect->m_pShaderBlocks[i].pReflectionData->BytecodeLength),
- "Internal loading error: cannot move shader bytecode.");
- for( size_t iDecl=0; iDecl < D3D11_SO_STREAM_COUNT; ++iDecl )
- {
- VHD( pHeap->MoveString(&m_pEffect->m_pShaderBlocks[i].pReflectionData->pStreamOutDecls[iDecl]), "Internal loading error: cannot move SO decl." );
- }
- VH( pHeap->MoveInterfaceParameters(m_pEffect->m_pShaderBlocks[i].pReflectionData->InterfaceParameterCount, &m_pEffect->m_pShaderBlocks[i].pReflectionData->pInterfaceParameters ) );
- }
-
- }
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Runtime effect reallocation code
-//////////////////////////////////////////////////////////////////////////
-
-template<class T> HRESULT CEffectLoader::ReallocateBlockAssignments(T* &pBlocks, uint32_t cBlocks, T* pOldBlocks)
-{
- HRESULT hr = S_OK;
- CEffectHeap *pHeap = &m_pEffect->m_Heap;
-
- for(size_t i=0; i<cBlocks; i++)
- {
- T *pBlock = &pBlocks[i];
- VHD( pHeap->MoveData((void**) &pBlock->pAssignments, sizeof(SAssignment)*pBlock->AssignmentCount), "Internal loading error: cannot move assignment count." );
-
- for (size_t j=0; j<pBlock->AssignmentCount; j++)
- {
- SAssignment *pAssignment = &pBlock->pAssignments[j];
- uint32_t cbDeps;
-
- // When cloning, convert pointers back into offsets
- if( pOldBlocks )
- {
- T *pOldBlock = &pOldBlocks[i];
- pAssignment->Destination.Offset = (uint32_t)( (UINT_PTR)pAssignment->Destination.pGeneric - (UINT_PTR)pOldBlock ) ;
- }
-
- // Convert destination pointers from offset to real pointer
- pAssignment->Destination.pGeneric = (uint8_t*) pBlock + pAssignment->Destination.Offset;
-
- // Make sure the data pointer points into the backing store
- VBD( pAssignment->Destination.pGeneric >= &pBlock->BackingStore &&
- pAssignment->Destination.pGeneric < (uint8_t*) &pBlock->BackingStore + sizeof(pBlock->BackingStore),
- "Internal loading error: assignment destination out of range." );
-
- // Fixup dependencies
- cbDeps = pAssignment->DependencyCount * sizeof(SAssignment::SDependency);
- VHD( pHeap->MoveData((void**) &pAssignment->pDependencies, cbDeps), "Internal loading error: cannot move assignment dependencies." );
-
- SGlobalVariable *pOldVariable = nullptr;
- for(size_t iDep=0; iDep<pAssignment->DependencyCount; iDep++)
- {
- SAssignment::SDependency *pDep = &pAssignment->pDependencies[iDep];
- // We ignore all but the last variable because below, we only use the last dependency
- pOldVariable = pDep->pVariable;
- VH( FixupVariablePointer(&pDep->pVariable) );
- }
-
- // Fixup source pointers
- switch(pAssignment->LhsType)
- {
- case ELHS_VertexShaderBlock:
- case ELHS_PixelShaderBlock:
- case ELHS_GeometryShaderBlock:
- case ELHS_HullShaderBlock:
- case ELHS_DomainShaderBlock:
- case ELHS_ComputeShaderBlock:
- VH( FixupShaderPointer(&pAssignment->Source.pShader) );
- break;
-
- case ELHS_DepthStencilBlock:
- VH( FixupDSPointer((SDepthStencilBlock**)&pAssignment->Source.pBlock) );
- break;
- case ELHS_BlendBlock:
- VH( FixupABPointer((SBlendBlock**) &pAssignment->Source.pBlock) );
- break;
- case ELHS_RasterizerBlock:
- VH( FixupRSPointer((SRasterizerBlock**) &pAssignment->Source.pBlock) );
- break;
-
- case ELHS_Texture:
- VH( FixupShaderResourcePointer((SShaderResource**) &pAssignment->Source.pShaderResource) );
- break;
-
- default:
- // Non-object assignment (must have at least one dependency or it would have been pruned by now)
- assert( !pAssignment->IsObjectAssignment() && pAssignment->DependencyCount > 0 );
-
- // Numeric variables must be relocated before this function is called
-
- switch (pAssignment->AssignmentType)
- {
- case ERAT_NumericVariable:
- case ERAT_NumericVariableIndex:
- // the variable or variable array is always the last dependency in the chain
- SGlobalVariable *pVariable;
- pVariable = pAssignment->pDependencies[pAssignment->DependencyCount - 1].pVariable;
- assert( pVariable->pType->BelongsInConstantBuffer() && nullptr != pVariable->pCB );
-
- // When cloning, convert pointers back into offsets
- if( pOldBlocks )
- {
- VBD( pOldVariable != nullptr, "Internal loading error: pOldVariable is nullptr." );
- pAssignment->Source.Offset = pAssignment->Source.pNumeric - pOldVariable->pCB->pBackingStore;
- }
-
- // Convert from offset to pointer
- pAssignment->Source.pNumeric = pVariable->pCB->pBackingStore + pAssignment->Source.Offset;
- break;
-
- default:
- // Shouldn't be able to get here
- assert(0);
- VHD( E_FAIL, "Loading error: invalid assignment type." );
- }
- break;
-
- case ELHS_Invalid:
- VHD( E_FAIL, "Loading error: invalid assignment type." );
- }
-
- assert(m_pEffect->m_LocalTimer > 0);
- m_pEffect->EvaluateAssignment(pAssignment);
- }
- }
-
-lExit:
- return hr;
-}
-
-template<class T> uint32_t CEffectLoader::CalculateBlockAssignmentSize(T* &pBlocks, uint32_t cBlocks)
-{
- uint32_t dwSize = 0;
-
- for(size_t i=0; i<cBlocks; i++)
- {
- SBaseBlock *pBlock = &pBlocks[i];
- dwSize += AlignToPowerOf2(pBlock->AssignmentCount * sizeof(SAssignment), c_DataAlignment);
-
- for (size_t j=0; j<pBlock->AssignmentCount; j++)
- {
- SAssignment *pAssignment = &pBlock->pAssignments[j];
-
- dwSize += AlignToPowerOf2(pAssignment->DependencyCount * sizeof(SAssignment::SDependency), c_DataAlignment);
- }
- }
-
- return dwSize;
-}
-
-HRESULT CEffectLoader::ReallocateShaderBlocks()
-{
- HRESULT hr = S_OK;
- CEffectHeap *pHeap = &m_pEffect->m_Heap;
- const char* pError = "Internal loading error: cannot move shader data.";
-
- for (size_t i=0; i<m_pEffect->m_ShaderBlockCount; i++)
- {
- SShaderBlock *pShader = &m_pEffect->m_pShaderBlocks[i];
-
- // pShader->pReflection data and all of its members (bytecode, SO decl, etc.) are handled by ReallocateReflectionData()
- VHD( pHeap->MoveData((void**) &pShader->pCBDeps, pShader->CBDepCount * sizeof(SShaderCBDependency)), pError );
- VHD( pHeap->MoveData((void**) &pShader->pSampDeps, pShader->SampDepCount * sizeof(SShaderSamplerDependency)), pError );
- VHD( pHeap->MoveData((void**) &pShader->pInterfaceDeps, pShader->InterfaceDepCount * sizeof(SInterfaceDependency)), pError );
- VHD( pHeap->MoveData((void**) &pShader->pResourceDeps, pShader->ResourceDepCount * sizeof(SShaderResourceDependency)), pError );
- VHD( pHeap->MoveData((void**) &pShader->pUAVDeps, pShader->UAVDepCount * sizeof(SUnorderedAccessViewDependency)), pError );
- VHD( pHeap->MoveData((void**) &pShader->ppTbufDeps, pShader->TBufferDepCount * sizeof(SConstantBuffer*)), pError );
-
- for (size_t j=0; j<pShader->CBDepCount; j++)
- {
- SShaderCBDependency *pCBDeps = &pShader->pCBDeps[j];
- VHD( pHeap->MoveData((void**) &pCBDeps->ppD3DObjects, pCBDeps->Count * sizeof(ID3D11Buffer*)), pError );
- VHD( pHeap->MoveData((void**) &pCBDeps->ppFXPointers, pCBDeps->Count * sizeof(SConstantBuffer*)), pError );
-
- for (size_t k=0; k<pCBDeps->Count; k++)
- {
- VH( FixupCBPointer( &pCBDeps->ppFXPointers[k] ) );
- }
- }
-
- for (size_t j=0; j<pShader->SampDepCount; j++)
- {
- SShaderSamplerDependency *pSampDeps = &pShader->pSampDeps[j];
- VHD( pHeap->MoveData((void**) &pSampDeps->ppD3DObjects, pSampDeps->Count * sizeof(ID3D11SamplerState*)), pError );
- VHD( pHeap->MoveData((void**) &pSampDeps->ppFXPointers, pSampDeps->Count * sizeof(SSamplerBlock*)), pError );
-
- for (size_t k=0; k<pSampDeps->Count; k++)
- {
- VH( FixupSamplerPointer(&pSampDeps->ppFXPointers[k]) );
- }
- }
-
- for (size_t j=0; j<pShader->InterfaceDepCount; j++)
- {
- SInterfaceDependency *pInterfaceDeps = &pShader->pInterfaceDeps[j];
- VHD( pHeap->MoveData((void**) &pInterfaceDeps->ppD3DObjects, pInterfaceDeps->Count * sizeof(ID3D11ClassInstance*)), pError );
- VHD( pHeap->MoveData((void**) &pInterfaceDeps->ppFXPointers, pInterfaceDeps->Count * sizeof(SInterface*)), pError );
-
- for (size_t k=0; k<pInterfaceDeps->Count; k++)
- {
- VH( FixupInterfacePointer(&pInterfaceDeps->ppFXPointers[k], true) );
- }
- }
-
- for (size_t j=0; j<pShader->ResourceDepCount; j++)
- {
- SShaderResourceDependency *pResourceDeps = &pShader->pResourceDeps[j];
- VHD( pHeap->MoveData((void**) &pResourceDeps->ppD3DObjects, pResourceDeps->Count * sizeof(ID3D11ShaderResourceView*)), pError );
- VHD( pHeap->MoveData((void**) &pResourceDeps->ppFXPointers, pResourceDeps->Count * sizeof(SShaderResource*)), pError );
-
- for (size_t k=0; k<pResourceDeps->Count; k++)
- {
- VH( FixupShaderResourcePointer(&pResourceDeps->ppFXPointers[k]) );
- }
- }
-
- for (size_t j=0; j<pShader->UAVDepCount; j++)
- {
- SUnorderedAccessViewDependency *pUAVDeps = &pShader->pUAVDeps[j];
- VHD( pHeap->MoveData((void**) &pUAVDeps->ppD3DObjects, pUAVDeps->Count * sizeof(ID3D11UnorderedAccessView*)), pError );
- VHD( pHeap->MoveData((void**) &pUAVDeps->ppFXPointers, pUAVDeps->Count * sizeof(SUnorderedAccessView*)), pError );
-
- for (size_t k=0; k<pUAVDeps->Count; k++)
- {
- VH( FixupUnorderedAccessViewPointer(&pUAVDeps->ppFXPointers[k]) );
- }
- }
-
- for (size_t j=0; j<pShader->TBufferDepCount; j++)
- {
- VH( FixupCBPointer( &pShader->ppTbufDeps[j] ) );
- }
- }
-
-lExit:
- return hr;
-}
-
-
-uint32_t CEffectLoader::CalculateShaderBlockSize()
-{
- uint32_t dwSize = 0;
-
- for (size_t i=0; i<m_pEffect->m_ShaderBlockCount; i++)
- {
- SShaderBlock *pShader = &m_pEffect->m_pShaderBlocks[i];
-
- dwSize += AlignToPowerOf2(pShader->CBDepCount * sizeof(SShaderCBDependency), c_DataAlignment);
- dwSize += AlignToPowerOf2(pShader->SampDepCount * sizeof(SShaderSamplerDependency), c_DataAlignment);
- dwSize += AlignToPowerOf2(pShader->InterfaceDepCount * sizeof(SInterfaceDependency), c_DataAlignment);
- dwSize += AlignToPowerOf2(pShader->ResourceDepCount * sizeof(SShaderResourceDependency), c_DataAlignment);
- dwSize += AlignToPowerOf2(pShader->UAVDepCount * sizeof(SUnorderedAccessViewDependency), c_DataAlignment);
- dwSize += AlignToPowerOf2(pShader->TBufferDepCount * sizeof(SConstantBuffer*), c_DataAlignment);
-
- for (size_t j=0; j<pShader->CBDepCount; j++)
- {
- SShaderCBDependency *pCBDeps = &pShader->pCBDeps[j];
- dwSize += AlignToPowerOf2(pCBDeps->Count * sizeof(ID3D11Buffer*), c_DataAlignment);
- dwSize += AlignToPowerOf2(pCBDeps->Count * sizeof(SConstantBuffer*), c_DataAlignment);
- }
-
- for (size_t j=0; j<pShader->SampDepCount; j++)
- {
- SShaderSamplerDependency *pSampDeps = &pShader->pSampDeps[j];
- dwSize += AlignToPowerOf2(pSampDeps->Count * sizeof(ID3D11SamplerState*), c_DataAlignment);
- dwSize += AlignToPowerOf2(pSampDeps->Count * sizeof(SSamplerBlock*), c_DataAlignment);
- }
-
- for (size_t j=0; j<pShader->InterfaceDepCount; j++)
- {
- SInterfaceDependency *pInterfaceDeps = &pShader->pInterfaceDeps[j];
- dwSize += AlignToPowerOf2(pInterfaceDeps->Count * sizeof(ID3D11ClassInstance*), c_DataAlignment);
- dwSize += AlignToPowerOf2(pInterfaceDeps->Count * sizeof(SInterface*), c_DataAlignment);
- }
-
- for (size_t j=0; j<pShader->ResourceDepCount; j++)
- {
- SShaderResourceDependency *pResourceDeps = &pShader->pResourceDeps[j];
- dwSize += AlignToPowerOf2(pResourceDeps->Count * sizeof(ID3D11ShaderResourceView*), c_DataAlignment);
- dwSize += AlignToPowerOf2(pResourceDeps->Count * sizeof(SShaderResource*), c_DataAlignment);
- }
-
- for (size_t j=0; j<pShader->UAVDepCount; j++)
- {
- SUnorderedAccessViewDependency *pUAVDeps = &pShader->pUAVDeps[j];
- dwSize += AlignToPowerOf2(pUAVDeps->Count * sizeof(ID3D11UnorderedAccessView*), c_DataAlignment);
- dwSize += AlignToPowerOf2(pUAVDeps->Count * sizeof(SUnorderedAccessView*), c_DataAlignment);
- }
- }
-
- return dwSize;
-}
-
-// Move all (non-reflection) effect data to private heap
-#pragma warning(push)
-#pragma warning(disable: 4616 6239 )
-HRESULT CEffectLoader::ReallocateEffectData( bool Cloning )
-{
- HRESULT hr = S_OK;
- CEffectHeap *pHeap = &m_pEffect->m_Heap;
- uint32_t cbCBs = sizeof(SConstantBuffer) * m_pEffect->m_CBCount;
- uint32_t cbVariables = sizeof(SGlobalVariable) * m_pEffect->m_VariableCount;
- uint32_t cbGroups = sizeof(STechnique) * m_pEffect->m_GroupCount;
- uint32_t cbShaders = sizeof(SShaderBlock) * m_pEffect->m_ShaderBlockCount;
- uint32_t cbDS = sizeof(SDepthStencilBlock) * m_pEffect->m_DepthStencilBlockCount;
- uint32_t cbAB = sizeof(SBlendBlock) * m_pEffect->m_BlendBlockCount;
- uint32_t cbRS = sizeof(SRasterizerBlock) * m_pEffect->m_RasterizerBlockCount;
- uint32_t cbSamplers = sizeof(SSamplerBlock) * m_pEffect->m_SamplerBlockCount;
- uint32_t cbMemberDatas = sizeof(SMemberDataPointer) * m_pEffect->m_MemberDataCount;
- uint32_t cbInterfaces = sizeof(SInterface) * m_pEffect->m_InterfaceCount;
- uint32_t cbBackgroundInterfaces = sizeof(SInterface) * m_BackgroundInterfaces.GetSize();
- uint32_t cbShaderResources = sizeof(SShaderResource) * m_pEffect->m_ShaderResourceCount;
- uint32_t cbUnorderedAccessViews = sizeof(SUnorderedAccessView) * m_pEffect->m_UnorderedAccessViewCount;
- uint32_t cbRenderTargetViews = sizeof(SRenderTargetView) * m_pEffect->m_RenderTargetViewCount;
- uint32_t cbDepthStencilViews = sizeof(SDepthStencilView) * m_pEffect->m_DepthStencilViewCount;
- uint32_t cbAnonymousShaders = sizeof(SAnonymousShader) * m_pEffect->m_AnonymousShaderCount;
-
- // Calculate memory needed
- m_EffectMemory += AlignToPowerOf2(cbCBs, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbVariables, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbGroups, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbShaders, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbMemberDatas, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbInterfaces + cbBackgroundInterfaces, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbShaderResources, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbUnorderedAccessViews, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbRenderTargetViews, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbDepthStencilViews, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbDS, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbAB, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbRS, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbSamplers, c_DataAlignment);
- m_EffectMemory += AlignToPowerOf2(cbAnonymousShaders, c_DataAlignment);
-
- m_EffectMemory += CalculateShaderBlockSize();
-
- for (size_t i=0; i<m_pEffect->m_CBCount; i++)
- {
- SConstantBuffer *pCB = &m_pEffect->m_pCBs[i];
-
- m_EffectMemory += AlignToPowerOf2(pCB->Size, c_DataAlignment);
- }
-
- for (size_t i=0; i<m_pEffect->m_GroupCount; i++)
- {
- SGroup *pGroup = &m_pEffect->m_pGroups[i];
-
- m_EffectMemory += AlignToPowerOf2(pGroup->TechniqueCount * sizeof(STechnique), c_DataAlignment);
-
- for (size_t j=0; j<pGroup->TechniqueCount; j++)
- {
- STechnique *pTech = &pGroup->pTechniques[j];
-
- m_EffectMemory += AlignToPowerOf2(pTech->PassCount * sizeof(SPassBlock), c_DataAlignment);
- m_EffectMemory += CalculateBlockAssignmentSize(pTech->pPasses, pTech->PassCount);
- }
- };
-
- m_EffectMemory += CalculateBlockAssignmentSize(m_pEffect->m_pBlendBlocks, m_pEffect->m_BlendBlockCount);
- m_EffectMemory += CalculateBlockAssignmentSize(m_pEffect->m_pDepthStencilBlocks, m_pEffect->m_DepthStencilBlockCount);
- m_EffectMemory += CalculateBlockAssignmentSize(m_pEffect->m_pRasterizerBlocks, m_pEffect->m_RasterizerBlockCount);
- m_EffectMemory += CalculateBlockAssignmentSize(m_pEffect->m_pSamplerBlocks, m_pEffect->m_SamplerBlockCount);
-
- // Reserve memory
- VHD( pHeap->ReserveMemory(m_EffectMemory), "Internal loading error: cannot reserve effect memory." );
-
- // Move DataMemberPointer blocks
- m_pOldMemberDataBlocks = m_pEffect->m_pMemberDataBlocks;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pMemberDataBlocks, cbMemberDatas), "Internal loading error: cannot move member data blocks." );
-
- // Move CBs
- m_pOldCBs = m_pEffect->m_pCBs;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pCBs, cbCBs), "Internal loading error: cannot move CB count." );
- for (size_t i=0; i<m_pEffect->m_CBCount; i++)
- {
- SConstantBuffer *pCB = &m_pEffect->m_pCBs[i];
-
- VHD( pHeap->MoveData((void**) &pCB->pBackingStore, pCB->Size), "Internal loading error: cannot move CB backing store." );
-
- if( !Cloning )
- {
- // When creating the effect, MemberDataOffsetPlus4 is used, not pMemberData
- if( pCB->MemberDataOffsetPlus4 )
- {
- pCB->pMemberData = (SMemberDataPointer*)( (uint8_t*)m_pEffect->m_pMemberDataBlocks + ( pCB->MemberDataOffsetPlus4 - 4 ) );
- }
- }
- else if (pCB->pMemberData)
- {
- // When cloning an effect, pMemberData points to valid data in the original effect
- VH( FixupMemberDataPointer( &pCB->pMemberData ) );
- }
- }
-
- // Move numeric variables; move all variable types
- m_pOldVars = m_pEffect->m_pVariables;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pVariables, cbVariables), "Internal loading error: cannot move variable count." );
- for (size_t i=0; i<m_pEffect->m_VariableCount; i++)
- {
- SGlobalVariable *pVar = &m_pEffect->m_pVariables[i];
- pVar->pEffect = m_pEffect;
-
- if( Cloning && pVar->pType->BelongsInConstantBuffer())
- {
- // Convert pointer back to offset
- // pVar->pCB refers to the old CB
- pVar->Data.Offset = (UINT_PTR)pVar->Data.pGeneric - (UINT_PTR)pVar->pCB->pBackingStore;
- }
-
- if (pVar->pCB)
- {
- VH( FixupCBPointer( &pVar->pCB ) );
- }
-
- if( !Cloning )
- {
- // When creating the effect, MemberDataOffsetPlus4 is used, not pMemberData
- if( pVar->MemberDataOffsetPlus4 )
- {
- pVar->pMemberData = (SMemberDataPointer*)( (uint8_t*)m_pEffect->m_pMemberDataBlocks + ( pVar->MemberDataOffsetPlus4 - 4 ) );
- }
- }
- else if (pVar->pMemberData)
- {
- // When cloning an effect, pMemberData points to valid data in the original effect
- VH( FixupMemberDataPointer( &pVar->pMemberData ) );
- }
-
- if (pVar->pType->BelongsInConstantBuffer())
- {
- // Convert from offsets to pointers
- pVar->Data.pGeneric = pVar->pCB->pBackingStore + pVar->Data.Offset;
- }
- }
-
- // Fixup each CB's array of child variable pointers
- for (size_t i=0; i<m_pEffect->m_CBCount; i++)
- {
- SConstantBuffer *pCB = &m_pEffect->m_pCBs[i];
- pCB->pEffect = m_pEffect;
-
- if (pCB->pVariables != nullptr)
- {
- VH( FixupVariablePointer(&pCB->pVariables) );
- }
- }
-
- // Move shaders
- m_pOldShaders = m_pEffect->m_pShaderBlocks;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pShaderBlocks, cbShaders), "Internal loading error: cannot move shader count." );
-
- // Move interfaces, combining global interfaces and those that were created during shader initialization
- m_pOldInterfaces = m_pEffect->m_pInterfaces;
- m_OldInterfaceCount = m_pEffect->m_InterfaceCount;
- VHD( pHeap->MoveEmptyDataBlock((void**) &m_pEffect->m_pInterfaces, cbInterfaces + cbBackgroundInterfaces), "Internal loading error: cannot move shader." );
- memcpy( m_pEffect->m_pInterfaces, m_pOldInterfaces, cbInterfaces );
- for( size_t i=0; i < m_BackgroundInterfaces.GetSize(); i++ )
- {
- assert( m_BackgroundInterfaces[i] != nullptr );
- uint8_t* pDst = (uint8_t*)m_pEffect->m_pInterfaces + ( m_pEffect->m_InterfaceCount * sizeof(SInterface) );
- memcpy( pDst, m_BackgroundInterfaces[i], sizeof(SInterface) );
- m_pEffect->m_InterfaceCount++;
- }
-
- m_pOldShaderResources = m_pEffect->m_pShaderResources;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pShaderResources, cbShaderResources), "Internal loading error: cannot move SRVs." );
-
- m_pOldUnorderedAccessViews = m_pEffect->m_pUnorderedAccessViews;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pUnorderedAccessViews, cbUnorderedAccessViews), "Internal loading error: cannot move UAVS." );
-
- m_pOldRenderTargetViews = m_pEffect->m_pRenderTargetViews;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pRenderTargetViews, cbRenderTargetViews), "Internal loading error: cannot move RTVs." );
-
- m_pOldDepthStencilViews = m_pEffect->m_pDepthStencilViews;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pDepthStencilViews, cbDepthStencilViews), "Internal loading error: cannot move DSVs." );
-
- m_pOldDS = m_pEffect->m_pDepthStencilBlocks;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pDepthStencilBlocks, cbDS), "Internal loading error: cannot move depth-stencil state blocks." );
- VH( ReallocateBlockAssignments(m_pEffect->m_pDepthStencilBlocks, m_pEffect->m_DepthStencilBlockCount, Cloning ? m_pOldDS : nullptr) );
-
- m_pOldAB = m_pEffect->m_pBlendBlocks;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pBlendBlocks, cbAB), "Internal loading error: cannot move blend state blocks." );
- VH( ReallocateBlockAssignments(m_pEffect->m_pBlendBlocks, m_pEffect->m_BlendBlockCount, Cloning ? m_pOldAB : nullptr) );
-
- m_pOldRS = m_pEffect->m_pRasterizerBlocks;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pRasterizerBlocks, cbRS), "Internal loading error: cannot move rasterizer state blocks." );
- VH( ReallocateBlockAssignments(m_pEffect->m_pRasterizerBlocks, m_pEffect->m_RasterizerBlockCount, Cloning ? m_pOldRS : nullptr) );
-
- m_pOldSamplers = m_pEffect->m_pSamplerBlocks;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pSamplerBlocks, cbSamplers), "Internal loading error: cannot move samplers." );
- VH( ReallocateBlockAssignments(m_pEffect->m_pSamplerBlocks, m_pEffect->m_SamplerBlockCount, Cloning ? m_pOldSamplers : nullptr) );
-
- // Fixup sampler backing stores
- for (size_t i=0; i<m_pEffect->m_SamplerBlockCount; ++i)
- {
- VH( FixupShaderResourcePointer(&m_pEffect->m_pSamplerBlocks[i].BackingStore.pTexture) );
- }
-
- // Fixup each interface's class instance variable pointer
- for (size_t i=0; i<m_pEffect->m_InterfaceCount; i++)
- {
- SInterface *pInterface = &m_pEffect->m_pInterfaces[i];
-
- if (pInterface->pClassInstance != nullptr)
- {
- VH( FixupVariablePointer( (SGlobalVariable**)&pInterface->pClassInstance ) );
- }
- }
-
- // Fixup pointers for non-numeric variables
- for (size_t i=0; i<m_pEffect->m_VariableCount; i++)
- {
- SGlobalVariable *pVar = &m_pEffect->m_pVariables[i];
-
- if (pVar->pType->IsShader())
- {
- VH( FixupShaderPointer(&pVar->Data.pShader) );
- }
- else if (pVar->pType->IsShaderResource())
- {
- VH( FixupShaderResourcePointer(&pVar->Data.pShaderResource) );
- }
- else if (pVar->pType->IsUnorderedAccessView())
- {
- VH( FixupUnorderedAccessViewPointer(&pVar->Data.pUnorderedAccessView) );
- }
- else if (pVar->pType->IsInterface())
- {
- VH( FixupInterfacePointer(&pVar->Data.pInterface, false) );
- }
- else if (pVar->pType->IsObjectType(EOT_String))
- {
- if( !m_pEffect->IsOptimized() )
- {
- VH( FixupStringPointer(&pVar->Data.pString) );
- }
- }
- else if (pVar->pType->IsStateBlockObject())
- {
- switch(pVar->pType->ObjectType)
- {
- case EOT_DepthStencil:
- VH( FixupDSPointer((SDepthStencilBlock**) &pVar->Data.pBlock) );
- break;
- case EOT_Blend:
- VH( FixupABPointer((SBlendBlock**) &pVar->Data.pBlock) );
- break;
- case EOT_Rasterizer:
- VH( FixupRSPointer((SRasterizerBlock**) &pVar->Data.pBlock) );
- break;
- case EOT_Sampler:
- VB(pVar->pType->IsSampler());
- VH( FixupSamplerPointer((SSamplerBlock**) &pVar->Data.pBlock) );
- break;
- default:
- VH( E_FAIL );
- }
- }
- else if (pVar->pType->VarType == EVT_Struct || pVar->pType->VarType == EVT_Numeric)
- {
- if( pVar->pType->IsClassInstance() )
- {
- // do nothing
- }
- else
- {
- // do nothing
- }
- }
- else if (pVar->pType->IsRenderTargetView())
- {
- VH( FixupRenderTargetViewPointer(&pVar->Data.pRenderTargetView) );
- }
- else if (pVar->pType->IsDepthStencilView())
- {
- VH( FixupDepthStencilViewPointer(&pVar->Data.pDepthStencilView) );
- }
- else
- {
- VHD( E_FAIL, "Internal loading error: Invalid variable type." );
- }
- }
-
- // Fixup created members
- for (size_t i = 0; i < m_pEffect->m_pMemberInterfaces.GetSize(); ++ i)
- {
- SMember* pMember = m_pEffect->m_pMemberInterfaces[i];
- SGlobalVariable** ppTopLevelEntity = (SGlobalVariable**)&pMember->pTopLevelEntity;
- VN( *ppTopLevelEntity );
-
- // This might be set to false later, for supporting textures inside classes
- const bool bGlobalMemberDataBlock = true;
-
- if( Cloning )
- {
- if( pMember->pType->BelongsInConstantBuffer() )
- {
- assert( pMember->Data.pGeneric == nullptr || (*ppTopLevelEntity)->pEffect->m_Heap.IsInHeap(pMember->Data.pGeneric) );
- pMember->Data.Offset = (uint32_t)( (uint8_t*)pMember->Data.pGeneric - (uint8_t*)(*ppTopLevelEntity)->pCB->pBackingStore );
- }
- if( bGlobalMemberDataBlock && pMember->pMemberData )
- {
- pMember->MemberDataOffsetPlus4 = (uint32_t)( (uint8_t*)pMember->pMemberData - (uint8_t*)(*ppTopLevelEntity)->pEffect->m_pMemberDataBlocks ) + 4;
- }
- }
-
- VH( FixupVariablePointer( ppTopLevelEntity ) );
-
- if (pMember->pType->BelongsInConstantBuffer())
- {
- // Convert from offsets to pointers
- pMember->Data.pGeneric = (*ppTopLevelEntity)->pCB->pBackingStore + pMember->Data.Offset;
- }
- if( bGlobalMemberDataBlock && pMember->MemberDataOffsetPlus4 )
- {
- pMember->pMemberData = (SMemberDataPointer*)( (uint8_t*)m_pEffect->m_pMemberDataBlocks + ( pMember->MemberDataOffsetPlus4 - 4 ) );
- }
- }
-
- // Fixup shader data
- VH( ReallocateShaderBlocks() );
-
- // Move groups, techniques, and passes
- m_pOldGroups = m_pEffect->m_pGroups;
- VHD( pHeap->MoveData((void**) &m_pEffect->m_pGroups, cbGroups), "Internal loading error: cannot move groups." );
- for (size_t i=0; i<m_pEffect->m_GroupCount; i++)
- {
- SGroup *pGroup = &m_pEffect->m_pGroups[i];
- uint32_t cbTechniques;
-
- cbTechniques = pGroup->TechniqueCount * sizeof(STechnique);
- VHD( pHeap->MoveData((void**) &pGroup->pTechniques, cbTechniques), "Internal loading error: cannot move techniques." );
-
- for (size_t j=0; j<pGroup->TechniqueCount; j++)
- {
- STechnique *pTech = &pGroup->pTechniques[j];
- uint32_t cbPass;
-
- cbPass = pTech->PassCount * sizeof(SPassBlock);
- SPassBlock* pOldPasses = Cloning ? pTech->pPasses : nullptr;
- VHD( pHeap->MoveData((void**) &pTech->pPasses, cbPass), "Internal loading error: cannot move passes." );
-
- for (size_t iPass = 0; iPass < pTech->PassCount; ++ iPass)
- {
- pTech->pPasses[iPass].pEffect = m_pEffect;
-
- // Fixup backing store pointers in passes
- VH( FixupABPointer((SBlendBlock**) &pTech->pPasses[iPass].BackingStore.pBlendBlock) );
- VH( FixupDSPointer((SDepthStencilBlock**) &pTech->pPasses[iPass].BackingStore.pDepthStencilBlock) );
- VH( FixupRSPointer((SRasterizerBlock**) &pTech->pPasses[iPass].BackingStore.pRasterizerBlock) );
- VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pVertexShaderBlock) );
- VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pPixelShaderBlock) );
- VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pGeometryShaderBlock) );
- VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pHullShaderBlock) );
- VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pDomainShaderBlock) );
- VH( FixupShaderPointer((SShaderBlock**) &pTech->pPasses[iPass].BackingStore.pComputeShaderBlock) );
- VH( FixupDepthStencilViewPointer( &pTech->pPasses[iPass].BackingStore.pDepthStencilView) );
- for (size_t iRT = 0; iRT < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; iRT++)
- {
- VH( FixupRenderTargetViewPointer( &pTech->pPasses[iPass].BackingStore.pRenderTargetViews[iRT] ) );
- }
- }
-
- VH( ReallocateBlockAssignments( pTech->pPasses, pTech->PassCount, pOldPasses ) );
- }
- }
- VH( FixupGroupPointer( &m_pEffect->m_pNullGroup ) );
-
- // Move anonymous shader variables
- VHD( pHeap->MoveData((void **) &m_pEffect->m_pAnonymousShaders, cbAnonymousShaders), "Internal loading error: cannot move anonymous shaders." );
- for (size_t i=0; i<m_pEffect->m_AnonymousShaderCount; ++i)
- {
- SAnonymousShader *pAnonymousShader = m_pEffect->m_pAnonymousShaders + i;
- VH( FixupShaderPointer((SShaderBlock**) &pAnonymousShader->pShaderBlock) );
- }
-
- VBD( pHeap->GetSize() == m_EffectMemory, "Loading error: effect size mismatch." );
-
-lExit:
- return hr;
-}
-#pragma warning(pop)
-
-}
diff --git a/lib/win32/Effects11/EffectLoad.h b/lib/win32/Effects11/EffectLoad.h
deleted file mode 100644
index c125f8cff8..0000000000
--- a/lib/win32/Effects11/EffectLoad.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectLoad.h
-//
-// Direct3D 11 Effects header for the FX file loader
-// A CEffectLoader is created at load time to facilitate loading
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-namespace D3DX11Effects
-{
-
-// Ranges are used for dependency checking during load
-
-enum ERanges
-{
- ER_CBuffer = 0,
- ER_Texture, // Includes TBuffers
- ER_Sampler,
- ER_UnorderedAccessView,
- ER_Interfaces,
- ER_Count // This should be the size of the enum
-};
-
-struct SRange
-{
- uint32_t start;
- uint32_t last;
- CEffectVector<void *> vResources; // should be (last - start) in length, resource type depends on the range type
-
- SRange() noexcept :
- start(0),
- last(0)
- {
- }
-};
-
-// Used during load to validate assignments
-D3D_SHADER_VARIABLE_TYPE GetSimpleParameterTypeFromObjectType(EObjectType ObjectType);
-
-
-// A class to facilitate loading an Effect. This class is a friend of CEffect.
-class CEffectLoader
-{
- friend HRESULT CEffect::CloneEffect(_In_ uint32_t Flags, _Outptr_ ID3DX11Effect** ppClonedEffect );
-
-protected:
- // Load-time allocations that eventually get moved happen out of the TempHeap. This heap will grow as needed
- CDataBlockStore m_BulkHeap;
-
- uint8_t *m_pData;
- SBinaryHeader5 *m_pHeader;
- DWORD m_Version;
-
- CEffect *m_pEffect;
- CEffectReflection *m_pReflection;
-
- D3DX11Core::CMemoryStream m_msStructured;
- D3DX11Core::CMemoryStream m_msUnstructured;
-
- // used to avoid repeated hash buffer allocations in LoadTypeAndAddToPool
- CEffectVector<uint8_t> m_HashBuffer;
-
- uint32_t m_dwBufferSize; // Size of data buffer in bytes
-
- // List of SInterface blocks created to back class instances bound to shaders
- CEffectVector<SInterface*> m_BackgroundInterfaces;
-
- // Pointers to pre-reallocation data
- SGlobalVariable *m_pOldVars;
- SShaderBlock *m_pOldShaders;
- SDepthStencilBlock *m_pOldDS;
- SBlendBlock *m_pOldAB;
- SRasterizerBlock *m_pOldRS;
- SConstantBuffer *m_pOldCBs;
- SSamplerBlock *m_pOldSamplers;
- uint32_t m_OldInterfaceCount;
- SInterface *m_pOldInterfaces;
- SShaderResource *m_pOldShaderResources;
- SUnorderedAccessView *m_pOldUnorderedAccessViews;
- SRenderTargetView *m_pOldRenderTargetViews;
- SDepthStencilView *m_pOldDepthStencilViews;
- SString *m_pOldStrings;
- SMemberDataPointer *m_pOldMemberDataBlocks;
- CEffectVectorOwner<SMember> *m_pvOldMemberInterfaces;
- SGroup *m_pOldGroups;
-
- uint32_t m_EffectMemory; // Effect private heap
- uint32_t m_ReflectionMemory; // Reflection private heap
-
- // Loader helpers
- HRESULT LoadCBs();
- HRESULT LoadNumericVariable(_In_ SConstantBuffer *pParentCB);
- HRESULT LoadObjectVariables();
- HRESULT LoadInterfaceVariables();
-
- HRESULT LoadTypeAndAddToPool(_Outptr_ SType **ppType, _In_ uint32_t dwOffset);
- HRESULT LoadStringAndAddToPool(_Outptr_result_maybenull_z_ char **ppString, _In_ uint32_t dwOffset);
- HRESULT LoadAssignments( _In_ uint32_t Assignments, _Out_writes_(Assignments) SAssignment **pAssignments,
- _In_ uint8_t *pBackingStore, _Out_opt_ uint32_t *pRTVAssignments, _Out_opt_ uint32_t *pFinalAssignments );
- HRESULT LoadGroups();
- HRESULT LoadTechnique( STechnique* pTech );
- HRESULT LoadAnnotations(uint32_t *pcAnnotations, SAnnotation **ppAnnotations);
-
- HRESULT ExecuteConstantAssignment(_In_ const SBinaryConstant *pConstant, _Out_writes_bytes_(4) void *pLHS, _In_ D3D_SHADER_VARIABLE_TYPE lhsType);
- uint32_t UnpackData(uint8_t *pDestData, uint8_t *pSrcData, uint32_t PackedDataSize, SType *pType, uint32_t *pBytesRead);
-
- // Build shader blocks
- HRESULT ConvertRangesToBindings(SShaderBlock *pShaderBlock, CEffectVector<SRange> *pvRanges );
- HRESULT GrabShaderData(SShaderBlock *pShaderBlock);
- HRESULT BuildShaderBlock(SShaderBlock *pShaderBlock);
-
- // Memory compactors
- HRESULT InitializeReflectionDataAndMoveStrings( uint32_t KnownSize = 0 );
- HRESULT ReallocateReflectionData( bool Cloning = false );
- HRESULT ReallocateEffectData( bool Cloning = false );
- HRESULT ReallocateShaderBlocks();
- template<class T> HRESULT ReallocateBlockAssignments(T* &pBlocks, uint32_t cBlocks, T* pOldBlocks = nullptr);
- HRESULT ReallocateAnnotationData(uint32_t cAnnotations, SAnnotation **ppAnnotations);
-
- HRESULT CalculateAnnotationSize(uint32_t cAnnotations, SAnnotation *pAnnotations);
- uint32_t CalculateShaderBlockSize();
- template<class T> uint32_t CalculateBlockAssignmentSize(T* &pBlocks, uint32_t cBlocks);
-
- HRESULT FixupCBPointer(_Inout_ SConstantBuffer **ppCB);
- HRESULT FixupShaderPointer(_Inout_ SShaderBlock **ppShaderBlock);
- HRESULT FixupDSPointer(_Inout_ SDepthStencilBlock **ppDSBlock);
- HRESULT FixupABPointer(_Inout_ SBlendBlock **ppABBlock);
- HRESULT FixupRSPointer(_Inout_ SRasterizerBlock **ppRSBlock);
- HRESULT FixupInterfacePointer(_Inout_ SInterface **ppInterface, _In_ bool CheckBackgroundInterfaces);
- HRESULT FixupShaderResourcePointer(_Inout_ SShaderResource **ppResource);
- HRESULT FixupUnorderedAccessViewPointer(_Inout_ SUnorderedAccessView **ppResource);
- HRESULT FixupRenderTargetViewPointer(_Inout_ SRenderTargetView **ppRenderTargetView);
- HRESULT FixupDepthStencilViewPointer(_Inout_ SDepthStencilView **ppDepthStencilView);
- HRESULT FixupSamplerPointer(_Inout_ SSamplerBlock **ppSampler);
- HRESULT FixupVariablePointer(_Inout_ SGlobalVariable **ppVar);
- HRESULT FixupStringPointer(_Inout_ SString **ppString);
- HRESULT FixupMemberDataPointer(_Inout_ SMemberDataPointer **ppMemberData);
- HRESULT FixupGroupPointer(_Inout_ SGroup **ppGroup);
-
- // Methods to retrieve data from the unstructured block
- // (these do not make copies; they simply return pointers into the block)
- HRESULT GetStringAndAddToReflection(_In_ uint32_t offset, _Outptr_result_maybenull_z_ char **ppPointer); // Returns a string from the file string block, updates m_EffectMemory
- HRESULT GetUnstructuredDataBlock(_In_ uint32_t offset, _Out_ uint32_t *pdwSize, _Outptr_result_buffer_(*pdwSize) void **ppData);
- // This function makes a copy of the array of SInterfaceParameters, but not a copy of the strings
- HRESULT GetInterfaceParametersAndAddToReflection( _In_ uint32_t InterfaceCount, _In_ uint32_t offset, _Outptr_result_buffer_all_maybenull_(InterfaceCount) SShaderBlock::SInterfaceParameter **ppInterfaces );
-
-public:
- CEffectLoader() noexcept;
-
- HRESULT LoadEffect(_In_ CEffect *pEffect, _In_reads_bytes_(cbEffectBuffer) const void *pEffectBuffer, _In_ uint32_t cbEffectBuffer);
-};
-
-}
diff --git a/lib/win32/Effects11/EffectNonRuntime.cpp b/lib/win32/Effects11/EffectNonRuntime.cpp
deleted file mode 100644
index e6908c2d49..0000000000
--- a/lib/win32/Effects11/EffectNonRuntime.cpp
+++ /dev/null
@@ -1,2988 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectNonRuntime.cpp
-//
-// D3DX11 Effect low-frequency utility functions
-// These functions are not intended to be called regularly. They
-// are typically called when creating, cloning, or optimizing an
-// Effect, or reflecting a variable.
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#include "pchfx.h"
-#include "SOParser.h"
-
-namespace D3DX11Effects
-{
-
-extern SUnorderedAccessView g_NullUnorderedAccessView;
-
-SBaseBlock::SBaseBlock() noexcept :
- BlockType(EBT_Invalid),
- IsUserManaged(false),
- AssignmentCount(0),
- pAssignments(nullptr)
-{
-}
-
-SPassBlock::SPassBlock() noexcept :
- BackingStore{},
- pName(nullptr),
- AnnotationCount(0),
- pAnnotations(nullptr),
- pEffect(nullptr),
- InitiallyValid(true),
- HasDependencies(false)
-{
-}
-
-STechnique::STechnique() noexcept :
- pName(nullptr),
- PassCount(0),
- pPasses(nullptr),
- AnnotationCount(0),
- pAnnotations(nullptr),
- InitiallyValid( true ),
- HasDependencies( false )
-{
-}
-
-SGroup::SGroup() noexcept :
- pName(nullptr),
- TechniqueCount(0),
- pTechniques(nullptr),
- AnnotationCount(0),
- pAnnotations(nullptr),
- InitiallyValid( true ),
- HasDependencies( false )
-{
-}
-
-SDepthStencilBlock::SDepthStencilBlock() noexcept :
- pDSObject(nullptr),
- BackingStore{},
- IsValid(true)
-{
- BackingStore.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
- BackingStore.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
- BackingStore.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
- BackingStore.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
- BackingStore.DepthEnable = true;
- BackingStore.DepthFunc = D3D11_COMPARISON_LESS;
- BackingStore.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
- BackingStore.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
- BackingStore.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
- BackingStore.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
- BackingStore.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
- BackingStore.StencilEnable = false;
- BackingStore.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
- BackingStore.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
-}
-
-SBlendBlock::SBlendBlock() noexcept :
- pBlendObject(nullptr),
- BackingStore{},
- IsValid(true)
-{
- BackingStore.AlphaToCoverageEnable = false;
- BackingStore.IndependentBlendEnable = true;
- for( size_t i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++ )
- {
- BackingStore.RenderTarget[i].SrcBlend = D3D11_BLEND_ONE;
- BackingStore.RenderTarget[i].DestBlend = D3D11_BLEND_ZERO;
- BackingStore.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
- BackingStore.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE;
- BackingStore.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO;
- BackingStore.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;
- memset(&BackingStore.RenderTarget[i].RenderTargetWriteMask, 0x0F, sizeof(BackingStore.RenderTarget[i].RenderTargetWriteMask));
- }
-}
-
-SRasterizerBlock::SRasterizerBlock() noexcept :
- pRasterizerObject(nullptr),
- BackingStore{},
- IsValid(true)
-{
- BackingStore.AntialiasedLineEnable = false;
- BackingStore.CullMode = D3D11_CULL_BACK;
- BackingStore.DepthBias = D3D11_DEFAULT_DEPTH_BIAS;
- BackingStore.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP;
- BackingStore.FillMode = D3D11_FILL_SOLID;
- BackingStore.FrontCounterClockwise = false;
- BackingStore.MultisampleEnable = false;
- BackingStore.ScissorEnable = false;
- BackingStore.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
- BackingStore.DepthClipEnable = true;
-}
-
-SSamplerBlock::SSamplerBlock() noexcept :
- pD3DObject(nullptr),
- BackingStore{}
-{
- BackingStore.SamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
- BackingStore.SamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
- BackingStore.SamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
- BackingStore.SamplerDesc.BorderColor[3] = D3D11_DEFAULT_BORDER_COLOR_COMPONENT;
- BackingStore.SamplerDesc.BorderColor[2] = D3D11_DEFAULT_BORDER_COLOR_COMPONENT;
- BackingStore.SamplerDesc.BorderColor[1] = D3D11_DEFAULT_BORDER_COLOR_COMPONENT;
- BackingStore.SamplerDesc.BorderColor[0] = D3D11_DEFAULT_BORDER_COLOR_COMPONENT;
- BackingStore.SamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
- BackingStore.SamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
- BackingStore.SamplerDesc.MaxAnisotropy = (UINT32) D3D11_DEFAULT_MAX_ANISOTROPY;
- BackingStore.SamplerDesc.MipLODBias = D3D11_DEFAULT_MIP_LOD_BIAS;
- BackingStore.SamplerDesc.MinLOD = -FLT_MAX;
- BackingStore.SamplerDesc.MaxLOD = FLT_MAX;
-}
-
-SShaderBlock::SShaderBlock(SD3DShaderVTable *pVirtualTable) noexcept :
- IsValid(true),
- pVT(pVirtualTable),
- pReflectionData(nullptr),
- pD3DObject(nullptr),
- CBDepCount(0),
- pCBDeps(nullptr),
- SampDepCount(0),
- pSampDeps(nullptr),
- InterfaceDepCount(0),
- pInterfaceDeps(nullptr),
- ResourceDepCount(0),
- pResourceDeps(nullptr),
- UAVDepCount(0),
- pUAVDeps(nullptr),
- TBufferDepCount(0),
- ppTbufDeps(nullptr),
- pInputSignatureBlob(nullptr)
-{
-}
-
-HRESULT SShaderBlock::OnDeviceBind()
-{
- HRESULT hr = S_OK;
- uint32_t i, j;
-
- // Update all CB deps
- for (i=0; i<CBDepCount; i++)
- {
- assert(pCBDeps[i].Count);
-
- for (j=0; j<pCBDeps[i].Count; j++)
- {
- pCBDeps[i].ppD3DObjects[j] = pCBDeps[i].ppFXPointers[j]->pD3DObject;
-
- if ( !pCBDeps[i].ppD3DObjects[j] )
- VH( E_FAIL );
- }
- }
-
- // Update all sampler deps
- for (i=0; i<SampDepCount; i++)
- {
- assert(pSampDeps[i].Count);
-
- for (j=0; j<pSampDeps[i].Count; j++)
- {
- pSampDeps[i].ppD3DObjects[j] = pSampDeps[i].ppFXPointers[j]->pD3DObject;
-
- if ( !pSampDeps[i].ppD3DObjects[j] )
- VH( E_FAIL );
- }
- }
-
- // Texture deps will be set automatically on use since they are initially marked dirty.
-
-lExit:
- return hr;
-}
-
-extern SD3DShaderVTable g_vtVS;
-extern SD3DShaderVTable g_vtGS;
-extern SD3DShaderVTable g_vtPS;
-extern SD3DShaderVTable g_vtHS;
-extern SD3DShaderVTable g_vtDS;
-extern SD3DShaderVTable g_vtCS;
-
-EObjectType SShaderBlock::GetShaderType()
-{
- if (&g_vtVS == pVT)
- return EOT_VertexShader;
- else if (&g_vtGS == pVT)
- return EOT_GeometryShader;
- else if (&g_vtPS == pVT)
- return EOT_PixelShader;
- else if (&g_vtHS == pVT)
- return EOT_HullShader5;
- else if (&g_vtDS == pVT)
- return EOT_DomainShader5;
- else if (&g_vtCS == pVT)
- return EOT_ComputeShader5;
-
- return EOT_Invalid;
-}
-
-#define _SET_BIT(bytes, x) (bytes[x / 8] |= (1 << (x % 8)))
-
-HRESULT SShaderBlock::ComputeStateBlockMask(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask)
-{
- HRESULT hr = S_OK;
- uint32_t i, j;
- uint8_t *pSamplerMask = nullptr, *pShaderResourceMask = nullptr, *pConstantBufferMask = nullptr, *pUnorderedAccessViewMask = nullptr, *pInterfaceMask = nullptr;
-
- switch (GetShaderType())
- {
- case EOT_VertexShader:
- case EOT_VertexShader5:
- pStateBlockMask->VS = 1;
- pSamplerMask = pStateBlockMask->VSSamplers;
- pShaderResourceMask = pStateBlockMask->VSShaderResources;
- pConstantBufferMask = pStateBlockMask->VSConstantBuffers;
- pInterfaceMask = pStateBlockMask->VSInterfaces;
- pUnorderedAccessViewMask = nullptr;
- break;
-
- case EOT_GeometryShader:
- case EOT_GeometryShader5:
- pStateBlockMask->GS = 1;
- pSamplerMask = pStateBlockMask->GSSamplers;
- pShaderResourceMask = pStateBlockMask->GSShaderResources;
- pConstantBufferMask = pStateBlockMask->GSConstantBuffers;
- pInterfaceMask = pStateBlockMask->GSInterfaces;
- pUnorderedAccessViewMask = nullptr;
- break;
-
- case EOT_PixelShader:
- case EOT_PixelShader5:
- pStateBlockMask->PS = 1;
- pSamplerMask = pStateBlockMask->PSSamplers;
- pShaderResourceMask = pStateBlockMask->PSShaderResources;
- pConstantBufferMask = pStateBlockMask->PSConstantBuffers;
- pInterfaceMask = pStateBlockMask->PSInterfaces;
- pUnorderedAccessViewMask = &pStateBlockMask->PSUnorderedAccessViews;
- break;
-
- case EOT_HullShader5:
- pStateBlockMask->HS = 1;
- pSamplerMask = pStateBlockMask->HSSamplers;
- pShaderResourceMask = pStateBlockMask->HSShaderResources;
- pConstantBufferMask = pStateBlockMask->HSConstantBuffers;
- pInterfaceMask = pStateBlockMask->HSInterfaces;
- pUnorderedAccessViewMask = nullptr;
- break;
-
- case EOT_DomainShader5:
- pStateBlockMask->DS = 1;
- pSamplerMask = pStateBlockMask->DSSamplers;
- pShaderResourceMask = pStateBlockMask->DSShaderResources;
- pConstantBufferMask = pStateBlockMask->DSConstantBuffers;
- pInterfaceMask = pStateBlockMask->DSInterfaces;
- pUnorderedAccessViewMask = nullptr;
- break;
-
- case EOT_ComputeShader5:
- pStateBlockMask->CS = 1;
- pSamplerMask = pStateBlockMask->CSSamplers;
- pShaderResourceMask = pStateBlockMask->CSShaderResources;
- pConstantBufferMask = pStateBlockMask->CSConstantBuffers;
- pInterfaceMask = pStateBlockMask->CSInterfaces;
- pUnorderedAccessViewMask = &pStateBlockMask->CSUnorderedAccessViews;
- break;
-
- default:
- assert(0);
- VH(E_FAIL);
- }
-
- for (i = 0; i < SampDepCount; ++ i)
- {
- for (j = 0; j < pSampDeps[i].Count; ++ j)
- {
- _SET_BIT(pSamplerMask, (pSampDeps[i].StartIndex + j));
- }
- }
-
- for (i = 0; i < InterfaceDepCount; ++ i)
- {
- for (j = 0; j < pInterfaceDeps[i].Count; ++ j)
- {
- _SET_BIT(pInterfaceMask, (pInterfaceDeps[i].StartIndex + j));
- }
- }
-
- for (i = 0; i < ResourceDepCount; ++ i)
- {
- for (j = 0; j < pResourceDeps[i].Count; ++ j)
- {
- _SET_BIT(pShaderResourceMask, (pResourceDeps[i].StartIndex + j));
- }
- }
-
- for (i = 0; i < CBDepCount; ++ i)
- {
- for (j = 0; j < pCBDeps[i].Count; ++ j)
- {
- _SET_BIT(pConstantBufferMask, (pCBDeps[i].StartIndex + j));
- }
- }
-
- for (i = 0; i < UAVDepCount; ++ i)
- {
- assert( pUnorderedAccessViewMask != 0 );
- _Analysis_assume_( pUnorderedAccessViewMask != 0 );
- for (j = 0; j < pUAVDeps[i].Count; ++ j)
- {
- if( pUAVDeps[i].ppFXPointers[j] != &g_NullUnorderedAccessView )
- _SET_BIT(pUnorderedAccessViewMask, (pUAVDeps[i].StartIndex + j));
- }
- }
-
-lExit:
- return hr;
-}
-
-#undef _SET_BIT
-
-HRESULT SShaderBlock::GetShaderDesc(_Out_ D3DX11_EFFECT_SHADER_DESC *pDesc, _In_ bool IsInline)
-{
- HRESULT hr = S_OK;
-
- ZeroMemory(pDesc, sizeof(*pDesc));
-
- pDesc->pInputSignature = pInputSignatureBlob ? (const uint8_t*)pInputSignatureBlob->GetBufferPointer() : nullptr;
- pDesc->IsInline = IsInline;
-
- if (nullptr != pReflectionData)
- {
- // initialize these only if present; otherwise leave them nullptr or 0
- pDesc->pBytecode = pReflectionData->pBytecode;
- pDesc->BytecodeLength = pReflectionData->BytecodeLength;
- for( size_t iDecl=0; iDecl < D3D11_SO_STREAM_COUNT; ++iDecl )
- {
- pDesc->SODecls[iDecl] = pReflectionData->pStreamOutDecls[iDecl];
- }
- pDesc->RasterizedStream = pReflectionData->RasterizedStream;
-
- // get # of input & output signature entries
- assert( pReflectionData->pReflection != 0 );
- _Analysis_assume_( pReflectionData->pReflection != 0 );
-
- D3D11_SHADER_DESC ShaderDesc;
- hr = pReflectionData->pReflection->GetDesc( &ShaderDesc );
- if ( SUCCEEDED(hr) )
- {
- pDesc->NumInputSignatureEntries = ShaderDesc.InputParameters;
- pDesc->NumOutputSignatureEntries = ShaderDesc.OutputParameters;
- pDesc->NumPatchConstantSignatureEntries = ShaderDesc.PatchConstantParameters;
- }
- }
-
- return hr;
-}
-
-HRESULT SShaderBlock::GetVertexShader(_Outptr_ ID3D11VertexShader **ppVS)
-{
- if (EOT_VertexShader == GetShaderType() ||
- EOT_VertexShader5 == GetShaderType())
- {
- assert( pD3DObject != 0 );
- _Analysis_assume_( pD3DObject != 0 );
- *ppVS = static_cast<ID3D11VertexShader *>( pD3DObject );
- SAFE_ADDREF(*ppVS);
- return S_OK;
- }
- else
- {
- *ppVS = nullptr;
- DPF(0, "ID3DX11EffectShaderVariable::GetVertexShader: This shader variable is not a vertex shader");
- return D3DERR_INVALIDCALL;
- }
-}
-
-HRESULT SShaderBlock::GetGeometryShader(_Outptr_ ID3D11GeometryShader **ppGS)
-{
- if (EOT_GeometryShader == GetShaderType() ||
- EOT_GeometryShaderSO == GetShaderType() ||
- EOT_GeometryShader5 == GetShaderType())
- {
- assert( pD3DObject != 0 );
- _Analysis_assume_( pD3DObject != 0 );
- *ppGS = static_cast<ID3D11GeometryShader *>( pD3DObject );
- SAFE_ADDREF(*ppGS);
- return S_OK;
- }
- else
- {
- *ppGS = nullptr;
- DPF(0, "ID3DX11EffectShaderVariable::GetGeometryShader: This shader variable is not a geometry shader");
- return D3DERR_INVALIDCALL;
- }
-}
-
-HRESULT SShaderBlock::GetPixelShader(_Outptr_ ID3D11PixelShader **ppPS)
-{
- if (EOT_PixelShader == GetShaderType() ||
- EOT_PixelShader5 == GetShaderType())
- {
- assert( pD3DObject != 0 );
- _Analysis_assume_( pD3DObject != 0 );
- *ppPS = static_cast<ID3D11PixelShader *>( pD3DObject );
- SAFE_ADDREF(*ppPS);
- return S_OK;
- }
- else
- {
- *ppPS = nullptr;
- DPF(0, "ID3DX11EffectShaderVariable::GetPixelShader: This shader variable is not a pixel shader");
- return D3DERR_INVALIDCALL;
- }
-}
-
-HRESULT SShaderBlock::GetHullShader(_Outptr_ ID3D11HullShader **ppHS)
-{
- if (EOT_HullShader5 == GetShaderType())
- {
- assert( pD3DObject != 0 );
- _Analysis_assume_( pD3DObject != 0 );
- *ppHS = static_cast<ID3D11HullShader *>( pD3DObject );
- SAFE_ADDREF(*ppHS);
- return S_OK;
- }
- else
- {
- *ppHS = nullptr;
- DPF(0, "ID3DX11EffectShaderVariable::GetHullShader: This shader variable is not a hull shader");
- return D3DERR_INVALIDCALL;
- }
-}
-
-HRESULT SShaderBlock::GetDomainShader(_Outptr_ ID3D11DomainShader **ppDS)
-{
- if (EOT_DomainShader5 == GetShaderType())
- {
- assert( pD3DObject != 0 );
- _Analysis_assume_( pD3DObject != 0 );
- *ppDS = static_cast<ID3D11DomainShader *>( pD3DObject );
- SAFE_ADDREF(*ppDS);
- return S_OK;
- }
- else
- {
- *ppDS = nullptr;
- DPF(0, "ID3DX11EffectShaderVariable::GetDomainShader: This shader variable is not a domain shader");
- return D3DERR_INVALIDCALL;
- }
-}
-
-HRESULT SShaderBlock::GetComputeShader(_Outptr_ ID3D11ComputeShader **ppCS)
-{
- if (EOT_ComputeShader5 == GetShaderType())
- {
- assert( pD3DObject != 0 );
- _Analysis_assume_( pD3DObject != 0 );
- *ppCS = static_cast<ID3D11ComputeShader *>( pD3DObject );
- SAFE_ADDREF(*ppCS);
- return S_OK;
- }
- else
- {
- *ppCS = nullptr;
- DPF(0, "ID3DX11EffectShaderVariable::GetComputeShader: This shader variable is not a compute shader");
- return D3DERR_INVALIDCALL;
- }
-}
-
-_Use_decl_annotations_
-HRESULT SShaderBlock::GetSignatureElementDesc(ESigType SigType, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
-{
- HRESULT hr = S_OK;
- LPCSTR pFuncName = nullptr;
- switch( SigType )
- {
- case ST_Input:
- pFuncName = "ID3DX11EffectShaderVariable::GetInputSignatureElementDesc";
- break;
- case ST_Output:
- pFuncName = "ID3DX11EffectShaderVariable::GetOutputSignatureElementDesc";
- break;
- case ST_PatchConstant:
- pFuncName = "ID3DX11EffectShaderVariable::GetPatchConstantSignatureElementDesc";
- break;
- default:
- assert( false );
- return E_FAIL;
- };
-
- if (nullptr != pReflectionData)
- {
- // get # of signature entries
- assert( pReflectionData->pReflection != 0 );
- _Analysis_assume_( pReflectionData->pReflection != 0 );
-
- D3D11_SHADER_DESC ShaderDesc;
- VH( pReflectionData->pReflection->GetDesc( &ShaderDesc ) );
-
- D3D11_SIGNATURE_PARAMETER_DESC ParamDesc ={};
- if( pReflectionData->IsNullGS )
- {
- switch( SigType )
- {
- case ST_Input:
- // The input signature for a null-GS is the output signature of the previous VS
- SigType = ST_Output;
- break;
- case ST_PatchConstant:
- // GeometryShaders cannot have patch constant signatures
- return E_INVALIDARG;
- };
- }
-
- switch( SigType )
- {
- case ST_Input:
- if( Element >= ShaderDesc.InputParameters )
- {
- DPF( 0, "%s: Invalid Element index (%u) specified", pFuncName, Element );
- VH( E_INVALIDARG );
- }
- VH( pReflectionData->pReflection->GetInputParameterDesc( Element, &ParamDesc ) );
- break;
- case ST_Output:
- if( Element >= ShaderDesc.OutputParameters )
- {
- DPF( 0, "%s: Invalid Element index (%u) specified", pFuncName, Element );
- VH( E_INVALIDARG );
- }
- VH( pReflectionData->pReflection->GetOutputParameterDesc( Element, &ParamDesc ) );
- break;
- case ST_PatchConstant:
- if( Element >= ShaderDesc.PatchConstantParameters )
- {
- DPF( 0, "%s: Invalid Element index (%u) specified", pFuncName, Element );
- VH( E_INVALIDARG );
- }
- VH( pReflectionData->pReflection->GetPatchConstantParameterDesc( Element, &ParamDesc ) );
- break;
- };
-
- pDesc->SemanticName = ParamDesc.SemanticName;
- pDesc->SystemValueType = ParamDesc.SystemValueType;
-
- // Pixel shaders need to be special-cased as they don't technically output SVs
- if( pDesc->SystemValueType == D3D_NAME_UNDEFINED && GetShaderType() == EOT_PixelShader && pDesc->SemanticName != 0 )
- {
- if( _stricmp(pDesc->SemanticName, "SV_TARGET") == 0 )
- {
- pDesc->SystemValueType = D3D_NAME_TARGET;
- }
- else if( _stricmp(pDesc->SemanticName, "SV_DEPTH") == 0 )
- {
- pDesc->SystemValueType = D3D_NAME_DEPTH;
- }
- else if( _stricmp(pDesc->SemanticName, "SV_COVERAGE") == 0 )
- {
- pDesc->SystemValueType = D3D_NAME_COVERAGE;
- }
- }
-
- pDesc->SemanticIndex = ParamDesc.SemanticIndex;
- pDesc->Register = ParamDesc.Register;
- pDesc->Mask = ParamDesc.Mask;
- pDesc->ComponentType = ParamDesc.ComponentType;
- pDesc->ReadWriteMask = ParamDesc.ReadWriteMask;
- }
- else
- {
- DPF(0, "%s: Cannot get signatures; shader bytecode is not present", pFuncName);
- VH( D3DERR_INVALIDCALL );
- }
-
-lExit:
- return hr;
-}
-
-void * GetBlockByIndex(EVarType VarType, EObjectType ObjectType, void *pBaseBlock, uint32_t Index)
-{
- switch( VarType )
- {
- case EVT_Interface:
- return (SInterface *)pBaseBlock + Index;
- case EVT_Object:
- switch (ObjectType)
- {
- case EOT_Blend:
- return (SBlendBlock *)pBaseBlock + Index;
- case EOT_DepthStencil:
- return (SDepthStencilBlock *)pBaseBlock + Index;
- case EOT_Rasterizer:
- return (SRasterizerBlock *)pBaseBlock + Index;
- case EOT_PixelShader:
- case EOT_PixelShader5:
- case EOT_GeometryShader:
- case EOT_GeometryShaderSO:
- case EOT_GeometryShader5:
- case EOT_VertexShader:
- case EOT_VertexShader5:
- case EOT_HullShader5:
- case EOT_DomainShader5:
- case EOT_ComputeShader5:
- return (SShaderBlock *)pBaseBlock + Index;
- case EOT_String:
- return (SString *)pBaseBlock + Index;
- case EOT_Sampler:
- return (SSamplerBlock *)pBaseBlock + Index;
- case EOT_Buffer:
- case EOT_Texture:
- case EOT_Texture1D:
- case EOT_Texture1DArray:
- case EOT_Texture2D:
- case EOT_Texture2DArray:
- case EOT_Texture2DMS:
- case EOT_Texture2DMSArray:
- case EOT_Texture3D:
- case EOT_TextureCube:
- case EOT_TextureCubeArray:
- case EOT_ByteAddressBuffer:
- case EOT_StructuredBuffer:
- return (SShaderResource *)pBaseBlock + Index;
- case EOT_DepthStencilView:
- return (SDepthStencilView *)pBaseBlock + Index;
- case EOT_RenderTargetView:
- return (SRenderTargetView *)pBaseBlock + Index;
- case EOT_RWTexture1D:
- case EOT_RWTexture1DArray:
- case EOT_RWTexture2D:
- case EOT_RWTexture2DArray:
- case EOT_RWTexture3D:
- case EOT_RWBuffer:
- case EOT_RWByteAddressBuffer:
- case EOT_RWStructuredBuffer:
- case EOT_RWStructuredBufferAlloc:
- case EOT_RWStructuredBufferConsume:
- case EOT_AppendStructuredBuffer:
- case EOT_ConsumeStructuredBuffer:
- return (SUnorderedAccessView *)pBaseBlock + Index;
- default:
- assert(0);
- return nullptr;
- }
- default:
- assert(0);
- return nullptr;
- }
-}
-
-//--------------------------------------------------------------------------------------
-// CEffect
-//--------------------------------------------------------------------------------------
-
-CEffect::CEffect( uint32_t Flags ) noexcept :
- m_RefCount(1),
- m_Flags(Flags),
- m_pReflection(nullptr),
- m_VariableCount(0),
- m_pVariables(nullptr),
- m_AnonymousShaderCount(0),
- m_pAnonymousShaders(nullptr),
- m_TechniqueCount(0),
- m_GroupCount(0),
- m_pGroups(nullptr),
- m_pNullGroup(nullptr),
- m_ShaderBlockCount(0),
- m_pShaderBlocks(nullptr),
- m_DepthStencilBlockCount(0),
- m_pDepthStencilBlocks(nullptr),
- m_BlendBlockCount(0),
- m_pBlendBlocks(nullptr),
- m_RasterizerBlockCount(0),
- m_pRasterizerBlocks(nullptr),
- m_SamplerBlockCount(0),
- m_pSamplerBlocks(nullptr),
- m_MemberDataCount(0),
- m_pMemberDataBlocks(nullptr),
- m_InterfaceCount(0),
- m_pInterfaces(nullptr),
- m_CBCount(0),
- m_pCBs(nullptr),
- m_StringCount(0),
- m_pStrings(nullptr),
- m_ShaderResourceCount(0),
- m_pShaderResources(nullptr),
- m_UnorderedAccessViewCount(0),
- m_pUnorderedAccessViews(nullptr),
- m_RenderTargetViewCount(0),
- m_pRenderTargetViews(nullptr),
- m_DepthStencilViewCount(0),
- m_pDepthStencilViews(nullptr),
- m_LocalTimer(1),
- m_FXLIndex(0),
- m_pDevice(nullptr),
- m_pContext(nullptr),
- m_pClassLinkage(nullptr),
- m_pTypePool(nullptr),
- m_pStringPool(nullptr),
- m_pPooledHeap(nullptr),
- m_pOptimizedTypeHeap(nullptr)
-{
-}
-
-void CEffect::ReleaseShaderRefection()
-{
- for( size_t i = 0; i < m_ShaderBlockCount; ++ i )
- {
- SAFE_RELEASE( m_pShaderBlocks[i].pInputSignatureBlob );
- if( m_pShaderBlocks[i].pReflectionData )
- {
- SAFE_RELEASE( m_pShaderBlocks[i].pReflectionData->pReflection );
- }
- }
-}
-
-CEffect::~CEffect()
-{
- ID3D11InfoQueue *pInfoQueue = nullptr;
-
- // Mute debug spew
- if (m_pDevice)
- {
- HRESULT hr = m_pDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void**) &pInfoQueue);
- if ( FAILED(hr) )
- pInfoQueue = nullptr;
- }
-
- if (pInfoQueue)
- {
- D3D11_INFO_QUEUE_FILTER filter = {};
- D3D11_MESSAGE_CATEGORY messageCategory = D3D11_MESSAGE_CATEGORY_STATE_SETTING;
-
- filter.DenyList.NumCategories = 1;
- filter.DenyList.pCategoryList = &messageCategory;
- pInfoQueue->PushStorageFilter(&filter);
- }
-
- if( nullptr != m_pDevice )
- {
- // if m_pDevice == nullptr, then we failed LoadEffect(), which means ReleaseShaderReflection was already called.
-
- // Release the shader reflection info, as it was not created on the private heap
- // This must be called before we delete m_pReflection
- ReleaseShaderRefection();
- }
-
- SAFE_DELETE( m_pReflection );
- SAFE_DELETE( m_pTypePool );
- SAFE_DELETE( m_pStringPool );
- SAFE_DELETE( m_pPooledHeap );
- SAFE_DELETE( m_pOptimizedTypeHeap );
-
- // this code assumes the effect has been loaded & relocated,
- // so check for that before freeing the resources
-
- if (nullptr != m_pDevice)
- {
- // Keep the following in line with AddRefAllForCloning
-
- assert(nullptr == m_pRasterizerBlocks || m_Heap.IsInHeap(m_pRasterizerBlocks));
- for (size_t i = 0; i < m_RasterizerBlockCount; ++ i)
- {
- SAFE_RELEASE(m_pRasterizerBlocks[i].pRasterizerObject);
- }
-
- assert(nullptr == m_pBlendBlocks || m_Heap.IsInHeap(m_pBlendBlocks));
- for (size_t i = 0; i < m_BlendBlockCount; ++ i)
- {
- SAFE_RELEASE(m_pBlendBlocks[i].pBlendObject);
- }
-
- assert(nullptr == m_pDepthStencilBlocks || m_Heap.IsInHeap(m_pDepthStencilBlocks));
- for (size_t i = 0; i < m_DepthStencilBlockCount; ++ i)
- {
- SAFE_RELEASE(m_pDepthStencilBlocks[i].pDSObject);
- }
-
- assert(nullptr == m_pSamplerBlocks || m_Heap.IsInHeap(m_pSamplerBlocks));
- for (size_t i = 0; i < m_SamplerBlockCount; ++ i)
- {
- SAFE_RELEASE(m_pSamplerBlocks[i].pD3DObject);
- }
-
- assert(nullptr == m_pShaderResources || m_Heap.IsInHeap(m_pShaderResources));
- for (size_t i = 0; i < m_ShaderResourceCount; ++ i)
- {
- SAFE_RELEASE(m_pShaderResources[i].pShaderResource);
- }
-
- assert(nullptr == m_pUnorderedAccessViews || m_Heap.IsInHeap(m_pUnorderedAccessViews));
- for (size_t i = 0; i < m_UnorderedAccessViewCount; ++ i)
- {
- SAFE_RELEASE(m_pUnorderedAccessViews[i].pUnorderedAccessView);
- }
-
- assert(nullptr == m_pRenderTargetViews || m_Heap.IsInHeap(m_pRenderTargetViews));
- for (size_t i = 0; i < m_RenderTargetViewCount; ++ i)
- {
- SAFE_RELEASE(m_pRenderTargetViews[i].pRenderTargetView);
- }
-
- assert(nullptr == m_pDepthStencilViews || m_Heap.IsInHeap(m_pDepthStencilViews));
- for (size_t i = 0; i < m_DepthStencilViewCount; ++ i)
- {
- SAFE_RELEASE(m_pDepthStencilViews[i].pDepthStencilView);
- }
-
- assert(nullptr == m_pMemberDataBlocks || m_Heap.IsInHeap(m_pMemberDataBlocks));
- for (size_t i = 0; i < m_MemberDataCount; ++ i)
- {
- switch( m_pMemberDataBlocks[i].Type )
- {
- case MDT_ClassInstance:
- SAFE_RELEASE(m_pMemberDataBlocks[i].Data.pD3DClassInstance);
- break;
- case MDT_BlendState:
- SAFE_RELEASE(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedBlendState);
- break;
- case MDT_DepthStencilState:
- SAFE_RELEASE(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedDepthStencilState);
- break;
- case MDT_RasterizerState:
- SAFE_RELEASE(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedRasterizerState);
- break;
- case MDT_SamplerState:
- SAFE_RELEASE(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedSamplerState);
- break;
- case MDT_Buffer:
- SAFE_RELEASE(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedConstantBuffer);
- break;
- case MDT_ShaderResourceView:
- SAFE_RELEASE(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedTextureBuffer);
- break;
- default:
- assert( false );
- }
- }
-
- assert(nullptr == m_pCBs || m_Heap.IsInHeap(m_pCBs));
- for (size_t i = 0; i < m_CBCount; ++ i)
- {
- SAFE_RELEASE(m_pCBs[i].TBuffer.pShaderResource);
- SAFE_RELEASE(m_pCBs[i].pD3DObject);
- }
-
- assert(nullptr == m_pShaderBlocks || m_Heap.IsInHeap(m_pShaderBlocks));
- _Analysis_assume_( m_ShaderBlockCount == 0 || m_pShaderBlocks != 0 );
- for (size_t i = 0; i < m_ShaderBlockCount; ++ i)
- {
- SAFE_RELEASE(m_pShaderBlocks[i].pD3DObject);
- }
-
- SAFE_RELEASE( m_pDevice );
- }
- SAFE_RELEASE( m_pClassLinkage );
- assert( m_pContext == nullptr );
-
- // Restore debug spew
- if (pInfoQueue)
- {
- pInfoQueue->PopStorageFilter();
- SAFE_RELEASE(pInfoQueue);
- }
-}
-
-// AddRef all D3D object when cloning
-void CEffect::AddRefAllForCloning( _In_ CEffect* pEffectSource )
-{
-#ifdef NDEBUG
- UNREFERENCED_PARAMETER(pEffectSource);
-#endif
- // Keep the following in line with ~CEffect
-
- assert( m_pDevice != nullptr );
-
- for( size_t i = 0; i < m_ShaderBlockCount; ++ i )
- {
- SAFE_ADDREF( m_pShaderBlocks[i].pInputSignatureBlob );
- if( m_pShaderBlocks[i].pReflectionData )
- {
- SAFE_ADDREF( m_pShaderBlocks[i].pReflectionData->pReflection );
- }
- }
-
- assert(nullptr == m_pRasterizerBlocks || pEffectSource->m_Heap.IsInHeap(m_pRasterizerBlocks));
- for ( size_t i = 0; i < m_RasterizerBlockCount; ++ i)
- {
- SAFE_ADDREF(m_pRasterizerBlocks[i].pRasterizerObject);
- }
-
- assert(nullptr == m_pBlendBlocks || pEffectSource->m_Heap.IsInHeap(m_pBlendBlocks));
- for ( size_t i = 0; i < m_BlendBlockCount; ++ i)
- {
- SAFE_ADDREF(m_pBlendBlocks[i].pBlendObject);
- }
-
- assert(nullptr == m_pDepthStencilBlocks || pEffectSource->m_Heap.IsInHeap(m_pDepthStencilBlocks));
- for ( size_t i = 0; i < m_DepthStencilBlockCount; ++ i)
- {
- SAFE_ADDREF(m_pDepthStencilBlocks[i].pDSObject);
- }
-
- assert(nullptr == m_pSamplerBlocks || pEffectSource->m_Heap.IsInHeap(m_pSamplerBlocks));
- for ( size_t i = 0; i < m_SamplerBlockCount; ++ i)
- {
- SAFE_ADDREF(m_pSamplerBlocks[i].pD3DObject);
- }
-
- assert(nullptr == m_pShaderResources || pEffectSource->m_Heap.IsInHeap(m_pShaderResources));
- for ( size_t i = 0; i < m_ShaderResourceCount; ++ i)
- {
- SAFE_ADDREF(m_pShaderResources[i].pShaderResource);
- }
-
- assert(nullptr == m_pUnorderedAccessViews || pEffectSource->m_Heap.IsInHeap(m_pUnorderedAccessViews));
- for ( size_t i = 0; i < m_UnorderedAccessViewCount; ++ i)
- {
- SAFE_ADDREF(m_pUnorderedAccessViews[i].pUnorderedAccessView);
- }
-
- assert(nullptr == m_pRenderTargetViews || pEffectSource->m_Heap.IsInHeap(m_pRenderTargetViews));
- for ( size_t i = 0; i < m_RenderTargetViewCount; ++ i)
- {
- SAFE_ADDREF(m_pRenderTargetViews[i].pRenderTargetView);
- }
-
- assert(nullptr == m_pDepthStencilViews || pEffectSource->m_Heap.IsInHeap(m_pDepthStencilViews));
- for ( size_t i = 0; i < m_DepthStencilViewCount; ++ i)
- {
- SAFE_ADDREF(m_pDepthStencilViews[i].pDepthStencilView);
- }
-
- assert(nullptr == m_pMemberDataBlocks || pEffectSource->m_Heap.IsInHeap(m_pMemberDataBlocks));
- for ( size_t i = 0; i < m_MemberDataCount; ++ i)
- {
- switch( m_pMemberDataBlocks[i].Type )
- {
- case MDT_ClassInstance:
- SAFE_ADDREF(m_pMemberDataBlocks[i].Data.pD3DClassInstance);
- break;
- case MDT_BlendState:
- SAFE_ADDREF(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedBlendState);
- break;
- case MDT_DepthStencilState:
- SAFE_ADDREF(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedDepthStencilState);
- break;
- case MDT_RasterizerState:
- SAFE_ADDREF(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedRasterizerState);
- break;
- case MDT_SamplerState:
- SAFE_ADDREF(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedSamplerState);
- break;
- case MDT_Buffer:
- SAFE_ADDREF(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedConstantBuffer);
- break;
- case MDT_ShaderResourceView:
- SAFE_ADDREF(m_pMemberDataBlocks[i].Data.pD3DEffectsManagedTextureBuffer);
- break;
- default:
- assert( false );
- }
- }
-
- // There's no need to AddRef CBs, since they are recreated
- if (m_pCBs)
- {
- assert(pEffectSource->m_Heap.IsInHeap(m_pCBs));
- for (size_t i = 0; i < m_CBCount; ++i)
- {
- SAFE_ADDREF(m_pCBs[i].TBuffer.pShaderResource);
- SAFE_ADDREF(m_pCBs[i].pD3DObject);
- }
- }
-
- assert(nullptr == m_pShaderBlocks || pEffectSource->m_Heap.IsInHeap(m_pShaderBlocks));
- for ( size_t i = 0; i < m_ShaderBlockCount; ++ i)
- {
- SAFE_ADDREF(m_pShaderBlocks[i].pD3DObject);
- }
-
- SAFE_ADDREF( m_pDevice );
-
- SAFE_ADDREF( m_pClassLinkage );
- assert( m_pContext == nullptr );
-}
-
-_Use_decl_annotations_
-HRESULT CEffect::QueryInterface(REFIID iid, LPVOID *ppv)
-{
- HRESULT hr = S_OK;
-
- if(nullptr == ppv)
- {
- DPF(0, "ID3DX11Effect::QueryInterface: nullptr parameter");
- hr = E_INVALIDARG;
- goto EXIT;
- }
-
- *ppv = nullptr;
- if(IsEqualIID(iid, IID_IUnknown))
- {
- *ppv = (IUnknown *) this;
- }
- else if(IsEqualIID(iid, IID_ID3DX11Effect))
- {
- *ppv = (ID3DX11Effect *) this;
- }
- else
- {
- return E_NOINTERFACE;
- }
-
- AddRef();
-
-EXIT:
- return hr;
-}
-
-ULONG CEffect::AddRef()
-{
- return ++ m_RefCount;
-}
-
-ULONG CEffect::Release()
-{
- if (-- m_RefCount > 0)
- {
- return m_RefCount;
- }
- else
- {
- delete this;
- }
-
- return 0;
-}
-
-// In all shaders, replace pOldBufferBlock with pNewBuffer, if pOldBufferBlock is a dependency
-_Use_decl_annotations_
-void CEffect::ReplaceCBReference(SConstantBuffer *pOldBufferBlock, ID3D11Buffer *pNewBuffer)
-{
- for (size_t iShaderBlock=0; iShaderBlock<m_ShaderBlockCount; iShaderBlock++)
- {
- for (size_t iCBDep = 0; iCBDep < m_pShaderBlocks[iShaderBlock].CBDepCount; iCBDep++)
- {
- for (size_t iCB = 0; iCB < m_pShaderBlocks[iShaderBlock].pCBDeps[iCBDep].Count; iCB++)
- {
- if (m_pShaderBlocks[iShaderBlock].pCBDeps[iCBDep].ppFXPointers[iCB] == pOldBufferBlock)
- m_pShaderBlocks[iShaderBlock].pCBDeps[iCBDep].ppD3DObjects[iCB] = pNewBuffer;
- }
- }
- }
-}
-
-// In all shaders, replace pOldSamplerBlock with pNewSampler, if pOldSamplerBlock is a dependency
-_Use_decl_annotations_
-void CEffect::ReplaceSamplerReference(SSamplerBlock *pOldSamplerBlock, ID3D11SamplerState *pNewSampler)
-{
- for (size_t iShaderBlock=0; iShaderBlock<m_ShaderBlockCount; iShaderBlock++)
- {
- for (size_t iSamplerDep = 0; iSamplerDep < m_pShaderBlocks[iShaderBlock].SampDepCount; iSamplerDep++)
- {
- for (size_t iSampler = 0; iSampler < m_pShaderBlocks[iShaderBlock].pSampDeps[iSamplerDep].Count; iSampler++)
- {
- if (m_pShaderBlocks[iShaderBlock].pSampDeps[iSamplerDep].ppFXPointers[iSampler] == pOldSamplerBlock)
- m_pShaderBlocks[iShaderBlock].pSampDeps[iSamplerDep].ppD3DObjects[iSampler] = pNewSampler;
- }
- }
- }
-}
-
-// Call BindToDevice after the effect has been fully loaded.
-// BindToDevice will release all D3D11 objects and create new ones on the new device
-_Use_decl_annotations_
-HRESULT CEffect::BindToDevice(ID3D11Device *pDevice, LPCSTR srcName)
-{
- HRESULT hr = S_OK;
-
- // Set new device
- if (pDevice == nullptr)
- {
- DPF(0, "ID3DX11Effect: pDevice must point to a valid D3D11 device");
- return D3DERR_INVALIDCALL;
- }
-
- if (m_pDevice != nullptr)
- {
- DPF(0, "ID3DX11Effect: Internal error, rebinding effects to a new device is not supported");
- return D3DERR_INVALIDCALL;
- }
-
- bool featureLevelGE11 = ( pDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_0 );
-
- pDevice->AddRef();
- SAFE_RELEASE(m_pDevice);
- m_pDevice = pDevice;
- VH( m_pDevice->CreateClassLinkage( &m_pClassLinkage ) );
- SetDebugObjectName(m_pClassLinkage,srcName);
-
- // Create all constant buffers
- SConstantBuffer *pCB = m_pCBs;
- SConstantBuffer *pCBLast = m_pCBs + m_CBCount;
- for(; pCB != pCBLast; pCB++)
- {
- SAFE_RELEASE(pCB->pD3DObject);
- SAFE_RELEASE(pCB->TBuffer.pShaderResource);
-
- // This is a CBuffer
- if (pCB->Size > 0)
- {
- if (pCB->IsTBuffer)
- {
- D3D11_BUFFER_DESC bufDesc;
- // size is always register aligned
- bufDesc.ByteWidth = pCB->Size;
- bufDesc.Usage = D3D11_USAGE_DEFAULT;
- bufDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
- bufDesc.CPUAccessFlags = 0;
- bufDesc.MiscFlags = 0;
-
- VH( pDevice->CreateBuffer( &bufDesc, nullptr, &pCB->pD3DObject) );
- SetDebugObjectName(pCB->pD3DObject, srcName );
-
- D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
- viewDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT;
- viewDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
- viewDesc.Buffer.ElementOffset = 0;
- viewDesc.Buffer.ElementWidth = pCB->Size / SType::c_RegisterSize;
-
- VH( pDevice->CreateShaderResourceView( pCB->pD3DObject, &viewDesc, &pCB->TBuffer.pShaderResource) );
- SetDebugObjectName(pCB->TBuffer.pShaderResource, srcName );
- }
- else
- {
- D3D11_BUFFER_DESC bufDesc;
- // size is always register aligned
- bufDesc.ByteWidth = pCB->Size;
- bufDesc.Usage = D3D11_USAGE_DEFAULT;
- bufDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
- bufDesc.CPUAccessFlags = 0;
- bufDesc.MiscFlags = 0;
-
- VH( pDevice->CreateBuffer( &bufDesc, nullptr, &pCB->pD3DObject) );
- SetDebugObjectName( pCB->pD3DObject, srcName );
- pCB->TBuffer.pShaderResource = nullptr;
- }
-
- pCB->IsDirty = true;
- }
- else
- {
- pCB->IsDirty = false;
- }
- }
-
- // Create all RasterizerStates
- SRasterizerBlock *pRB = m_pRasterizerBlocks;
- SRasterizerBlock *pRBLast = m_pRasterizerBlocks + m_RasterizerBlockCount;
- for(; pRB != pRBLast; pRB++)
- {
- SAFE_RELEASE(pRB->pRasterizerObject);
- if( SUCCEEDED( m_pDevice->CreateRasterizerState( &pRB->BackingStore, &pRB->pRasterizerObject) ) )
- {
- pRB->IsValid = true;
- SetDebugObjectName( pRB->pRasterizerObject, srcName );
- }
- else
- pRB->IsValid = false;
- }
-
- // Create all DepthStencils
- SDepthStencilBlock *pDS = m_pDepthStencilBlocks;
- SDepthStencilBlock *pDSLast = m_pDepthStencilBlocks + m_DepthStencilBlockCount;
- for(; pDS != pDSLast; pDS++)
- {
- SAFE_RELEASE(pDS->pDSObject);
- if( SUCCEEDED( m_pDevice->CreateDepthStencilState( &pDS->BackingStore, &pDS->pDSObject) ) )
- {
- pDS->IsValid = true;
- SetDebugObjectName( pDS->pDSObject, srcName );
- }
- else
- pDS->IsValid = false;
- }
-
- // Create all BlendStates
- SBlendBlock *pBlend = m_pBlendBlocks;
- SBlendBlock *pBlendLast = m_pBlendBlocks + m_BlendBlockCount;
- for(; pBlend != pBlendLast; pBlend++)
- {
- SAFE_RELEASE(pBlend->pBlendObject);
- if( SUCCEEDED( m_pDevice->CreateBlendState( &pBlend->BackingStore, &pBlend->pBlendObject ) ) )
- {
- pBlend->IsValid = true;
- SetDebugObjectName( pBlend->pBlendObject, srcName );
- }
- else
- pBlend->IsValid = false;
- }
-
- // Create all Samplers
- SSamplerBlock *pSampler = m_pSamplerBlocks;
- SSamplerBlock *pSamplerLast = m_pSamplerBlocks + m_SamplerBlockCount;
- for(; pSampler != pSamplerLast; pSampler++)
- {
- SAFE_RELEASE(pSampler->pD3DObject);
-
- VH( m_pDevice->CreateSamplerState( &pSampler->BackingStore.SamplerDesc, &pSampler->pD3DObject) );
- SetDebugObjectName( pSampler->pD3DObject, srcName );
- }
-
- // Create all shaders
- ID3D11ClassLinkage* neededClassLinkage = featureLevelGE11 ? m_pClassLinkage : nullptr;
- SShaderBlock *pShader = m_pShaderBlocks;
- SShaderBlock *pShaderLast = m_pShaderBlocks + m_ShaderBlockCount;
- for(; pShader != pShaderLast; pShader++)
- {
- SAFE_RELEASE(pShader->pD3DObject);
-
- if (nullptr == pShader->pReflectionData)
- {
- // nullptr shader. It's one of these:
- // PixelShader ps;
- // or
- // SetPixelShader( nullptr );
- continue;
- }
-
- if (pShader->pReflectionData->pStreamOutDecls[0] || pShader->pReflectionData->pStreamOutDecls[1] ||
- pShader->pReflectionData->pStreamOutDecls[2] || pShader->pReflectionData->pStreamOutDecls[3] )
- {
- // This is a geometry shader, process it's data
- CSOParser soParser;
- VH( soParser.Parse(pShader->pReflectionData->pStreamOutDecls) );
- uint32_t strides[4];
- soParser.GetStrides( strides );
- hr = m_pDevice->CreateGeometryShaderWithStreamOutput(pShader->pReflectionData->pBytecode,
- pShader->pReflectionData->BytecodeLength,
- soParser.GetDeclArray(),
- soParser.GetDeclCount(),
- strides,
- featureLevelGE11 ? 4 : 1,
- pShader->pReflectionData->RasterizedStream,
- neededClassLinkage,
- reinterpret_cast<ID3D11GeometryShader**>(&pShader->pD3DObject) );
- if (FAILED(hr))
- {
- DPF(1, "ID3DX11Effect::Load - failed to create GeometryShader with StreamOutput decl: \"%s\"", soParser.GetErrorString() );
- pShader->IsValid = false;
- hr = S_OK;
- }
- else
- {
- SetDebugObjectName( pShader->pD3DObject, srcName );
- }
- }
- else
- {
- // This is a regular shader
- if( pShader->pReflectionData->RasterizedStream == D3D11_SO_NO_RASTERIZED_STREAM )
- pShader->IsValid = false;
- else
- {
- if( FAILED( (m_pDevice->*(pShader->pVT->pCreateShader))( (uint32_t *) pShader->pReflectionData->pBytecode, pShader->pReflectionData->BytecodeLength, neededClassLinkage, &pShader->pD3DObject) ) )
- {
- DPF(1, "ID3DX11Effect::Load - failed to create shader" );
- pShader->IsValid = false;
- }
- else
- {
- SetDebugObjectName( pShader->pD3DObject, srcName );
- }
- }
- }
-
- // Update all dependency pointers
- VH( pShader->OnDeviceBind() );
- }
-
- // Initialize the member data pointers for all variables
- uint32_t CurMemberData = 0;
- for (uint32_t i = 0; i < m_VariableCount; ++ i)
- {
- if( m_pVariables[i].pMemberData )
- {
- if( m_pVariables[i].pType->IsClassInstance() )
- {
- for (uint32_t j = 0; j < std::max<size_t>(m_pVariables[i].pType->Elements,1); ++j)
- {
- assert( CurMemberData < m_MemberDataCount );
- ID3D11ClassInstance** ppCI = &(m_pVariables[i].pMemberData + j)->Data.pD3DClassInstance;
- (m_pVariables[i].pMemberData + j)->Type = MDT_ClassInstance;
- (m_pVariables[i].pMemberData + j)->Data.pD3DClassInstance = nullptr;
- if( m_pVariables[i].pType->TotalSize > 0 )
- {
- // ignore failures in GetClassInstance;
- m_pClassLinkage->GetClassInstance( m_pVariables[i].pName, j, ppCI );
- }
- else
- {
- // The HLSL compiler optimizes out zero-sized classes, so we have to create class instances from scratch
- if( FAILED( m_pClassLinkage->CreateClassInstance( m_pVariables[i].pType->pTypeName, 0, 0, 0, 0, ppCI ) ) )
- {
- DPF(0, "ID3DX11Effect: Out of memory while trying to create new class instance interface");
- }
- else
- {
- SetDebugObjectName( *ppCI, srcName );
- }
- }
- CurMemberData++;
- }
- }
- else if( m_pVariables[i].pType->IsStateBlockObject() )
- {
- for (size_t j = 0; j < std::max<size_t>(m_pVariables[i].pType->Elements,1); ++j)
- {
- switch( m_pVariables[i].pType->ObjectType )
- {
- case EOT_Blend:
- (m_pVariables[i].pMemberData + j)->Type = MDT_BlendState;
- (m_pVariables[i].pMemberData + j)->Data.pD3DEffectsManagedBlendState = nullptr;
- break;
- case EOT_Rasterizer:
- (m_pVariables[i].pMemberData + j)->Type = MDT_RasterizerState;
- (m_pVariables[i].pMemberData + j)->Data.pD3DEffectsManagedRasterizerState = nullptr;
- break;
- case EOT_DepthStencil:
- (m_pVariables[i].pMemberData + j)->Type = MDT_DepthStencilState;
- (m_pVariables[i].pMemberData + j)->Data.pD3DEffectsManagedDepthStencilState = nullptr;
- break;
- case EOT_Sampler:
- (m_pVariables[i].pMemberData + j)->Type = MDT_SamplerState;
- (m_pVariables[i].pMemberData + j)->Data.pD3DEffectsManagedSamplerState = nullptr;
- break;
- default:
- VB( false );
- }
- CurMemberData++;
- }
- }
- else
- {
- VB( false );
- }
- }
- }
- for(pCB = m_pCBs; pCB != pCBLast; pCB++)
- {
- (pCB->pMemberData + 0)->Type = MDT_Buffer;
- (pCB->pMemberData + 0)->Data.pD3DEffectsManagedConstantBuffer = nullptr;
- CurMemberData++;
- (pCB->pMemberData + 1)->Type = MDT_ShaderResourceView;
- (pCB->pMemberData + 1)->Data.pD3DEffectsManagedTextureBuffer = nullptr;
- CurMemberData++;
- }
-
-
- // Determine which techniques and passes are known to be invalid
- for( size_t iGroup=0; iGroup < m_GroupCount; iGroup++ )
- {
- SGroup* pGroup = &m_pGroups[iGroup];
- pGroup->InitiallyValid = true;
-
- for( size_t iTech=0; iTech < pGroup->TechniqueCount; iTech++ )
- {
- STechnique* pTechnique = &pGroup->pTechniques[iTech];
- pTechnique->InitiallyValid = true;
-
- for( size_t iPass = 0; iPass < pTechnique->PassCount; iPass++ )
- {
- SPassBlock* pPass = &pTechnique->pPasses[iPass];
- pPass->InitiallyValid = true;
-
- if( pPass->BackingStore.pBlendBlock != nullptr && !pPass->BackingStore.pBlendBlock->IsValid )
- pPass->InitiallyValid = false;
- if( pPass->BackingStore.pDepthStencilBlock != nullptr && !pPass->BackingStore.pDepthStencilBlock->IsValid )
- pPass->InitiallyValid = false;
- if( pPass->BackingStore.pRasterizerBlock != nullptr && !pPass->BackingStore.pRasterizerBlock->IsValid )
- pPass->InitiallyValid = false;
- if( pPass->BackingStore.pVertexShaderBlock != nullptr && !pPass->BackingStore.pVertexShaderBlock->IsValid )
- pPass->InitiallyValid = false;
- if( pPass->BackingStore.pPixelShaderBlock != nullptr && !pPass->BackingStore.pPixelShaderBlock->IsValid )
- pPass->InitiallyValid = false;
- if( pPass->BackingStore.pGeometryShaderBlock != nullptr && !pPass->BackingStore.pGeometryShaderBlock->IsValid )
- pPass->InitiallyValid = false;
- if( pPass->BackingStore.pHullShaderBlock != nullptr && !pPass->BackingStore.pHullShaderBlock->IsValid )
- pPass->InitiallyValid = false;
- if( pPass->BackingStore.pDomainShaderBlock != nullptr && !pPass->BackingStore.pDomainShaderBlock->IsValid )
- pPass->InitiallyValid = false;
- if( pPass->BackingStore.pComputeShaderBlock != nullptr && !pPass->BackingStore.pComputeShaderBlock->IsValid )
- pPass->InitiallyValid = false;
-
- pTechnique->InitiallyValid &= pPass->InitiallyValid;
- }
- pGroup->InitiallyValid &= pTechnique->InitiallyValid;
- }
- }
-
-lExit:
- return hr;
-}
-
-// FindVariableByName, plus an understanding of literal indices
-// This code handles A[i].
-// It does not handle anything else, like A.B, A[B[i]], A[B]
-SVariable * CEffect::FindVariableByNameWithParsing(_In_z_ LPCSTR pName)
-{
- SGlobalVariable *pVariable;
- const uint32_t MAX_PARSABLE_NAME_LENGTH = 256;
- char pScratchString[MAX_PARSABLE_NAME_LENGTH];
-
- const char* pSource = pName;
- char* pDest = pScratchString;
- char* pEnd = pScratchString + MAX_PARSABLE_NAME_LENGTH;
-
- pVariable = nullptr;
-
- while( *pSource != 0 )
- {
- if( pDest == pEnd )
- {
- pVariable = FindLocalVariableByName(pName);
- if( pVariable == nullptr )
- {
- DPF( 0, "Name %s is too long to parse", pName );
- }
- return pVariable;
- }
-
- if( *pSource == '[' )
- {
- // parse previous variable name
- *pDest = 0;
- assert( pVariable == nullptr );
- pVariable = FindLocalVariableByName(pScratchString);
- if( pVariable == nullptr )
- {
- return nullptr;
- }
- pDest = pScratchString;
- }
- else if( *pSource == ']' )
- {
- // parse integer
- *pDest = 0;
- uint32_t index = atoi(pScratchString);
- assert( pVariable != 0 );
- _Analysis_assume_( pVariable != 0 );
- pVariable = (SGlobalVariable*)pVariable->GetElement(index);
- if( pVariable && !pVariable->IsValid() )
- {
- pVariable = nullptr;
- }
- return pVariable;
- }
- else
- {
- // add character
- *pDest = *pSource;
- pDest++;
- }
- pSource++;
- }
-
- if( pDest != pScratchString )
- {
- // parse the variable name (there was no [i])
- *pDest = 0;
- assert( pVariable == nullptr );
- pVariable = FindLocalVariableByName(pScratchString);
- }
-
- return pVariable;
-}
-
-SGlobalVariable * CEffect::FindVariableByName(_In_z_ LPCSTR pName)
-{
- SGlobalVariable *pVariable;
-
- pVariable = FindLocalVariableByName(pName);
-
- return pVariable;
-}
-
-SGlobalVariable * CEffect::FindLocalVariableByName(_In_z_ LPCSTR pName)
-{
- SGlobalVariable *pVariable, *pVariableEnd;
-
- pVariableEnd = m_pVariables + m_VariableCount;
- for (pVariable = m_pVariables; pVariable != pVariableEnd; pVariable++)
- {
- if (strcmp( pVariable->pName, pName) == 0)
- {
- return pVariable;
- }
- }
-
- return nullptr;
-}
-
-
-//
-// Checks to see if two types are equivalent (either at runtime
-// or during the type-pooling load process)
-//
-// Major assumption: if both types are structures, then their
-// member types & names should already have been added to the pool,
-// in which case their member type & name pointers should be equal.
-//
-// This is true because complex data types (structures) have all
-// sub-types translated before the containing type is translated,
-// which means that simple sub-types (numeric types) have already
-// been pooled.
-//
-bool SType::IsEqual(SType *pOtherType) const
-{
- if (VarType != pOtherType->VarType || Elements != pOtherType->Elements
- || strcmp(pTypeName, pOtherType->pTypeName) != 0)
- {
- return false;
- }
-
- switch (VarType)
- {
- case EVT_Struct:
- {
- if (StructType.Members != pOtherType->StructType.Members)
- {
- return false;
- }
- assert(StructType.pMembers != nullptr && pOtherType->StructType.pMembers != nullptr);
-
- uint32_t i;
- for (i = 0; i < StructType.Members; ++ i)
- {
- // names for types must exist (not true for semantics)
- assert(StructType.pMembers[i].pName != nullptr && pOtherType->StructType.pMembers[i].pName != nullptr);
-
- if (StructType.pMembers[i].pType != pOtherType->StructType.pMembers[i].pType ||
- StructType.pMembers[i].Data.Offset != pOtherType->StructType.pMembers[i].Data.Offset ||
- StructType.pMembers[i].pName != pOtherType->StructType.pMembers[i].pName ||
- StructType.pMembers[i].pSemantic != pOtherType->StructType.pMembers[i].pSemantic)
- {
- return false;
- }
- }
- }
- break;
-
- case EVT_Object:
- {
- if (ObjectType != pOtherType->ObjectType)
- {
- return false;
- }
- }
- break;
-
- case EVT_Numeric:
- {
- if (NumericType.Rows != pOtherType->NumericType.Rows ||
- NumericType.Columns != pOtherType->NumericType.Columns ||
- NumericType.ScalarType != pOtherType->NumericType.ScalarType ||
- NumericType.NumericLayout != pOtherType->NumericType.NumericLayout ||
- NumericType.IsColumnMajor != pOtherType->NumericType.IsColumnMajor ||
- NumericType.IsPackedArray != pOtherType->NumericType.IsPackedArray)
- {
- return false;
- }
- }
- break;
-
- case EVT_Interface:
- {
- // VarType and pTypeName handled above
- }
- break;
-
- default:
- {
- assert(0);
- return false;
- }
- break;
- }
-
- assert(TotalSize == pOtherType->TotalSize && Stride == pOtherType->Stride && PackedSize == pOtherType->PackedSize);
-
- return true;
-}
-
-uint32_t SType::GetTotalUnpackedSize(_In_ bool IsSingleElement) const
-{
- if (VarType == EVT_Object)
- {
- return 0;
- }
- else if (VarType == EVT_Interface)
- {
- return 0;
- }
- else if (Elements > 0 && IsSingleElement)
- {
- assert( ( TotalSize == 0 && Stride == 0 ) ||
- ( (TotalSize > (Stride * (Elements - 1))) && (TotalSize <= (Stride * Elements)) ) );
- return TotalSize - Stride * (Elements - 1);
- }
- else
- {
- return TotalSize;
- }
-}
-
-uint32_t SType::GetTotalPackedSize(_In_ bool IsSingleElement) const
-{
- if (Elements > 0 && IsSingleElement)
- {
- assert(PackedSize % Elements == 0);
- return PackedSize / Elements;
- }
- else
- {
- return PackedSize;
- }
-}
-
-SConstantBuffer *CEffect::FindCB(_In_z_ LPCSTR pName)
-{
- uint32_t i;
-
- for (i=0; i<m_CBCount; i++)
- {
- if (!strcmp(m_pCBs[i].pName, pName))
- {
- return &m_pCBs[i];
- }
- }
-
- return nullptr;
-}
-
-bool CEffect::IsOptimized()
-{
- if ((m_Flags & D3DX11_EFFECT_OPTIMIZED) != 0)
- {
- assert(nullptr == m_pReflection);
- return true;
- }
- else
- {
- assert(nullptr != m_pReflection);
- return false;
- }
-}
-
-// Replace *ppType with the corresponding value in pMappingTable
-// pMappingTable table describes how to map old type pointers to new type pointers
-static HRESULT RemapType(_Inout_ SType **ppType, _Inout_ CPointerMappingTable *pMappingTable)
-{
- HRESULT hr = S_OK;
-
- SPointerMapping ptrMapping;
- CPointerMappingTable::CIterator iter;
- ptrMapping.pOld = *ppType;
- VH( pMappingTable->FindValueWithHash(ptrMapping, ptrMapping.Hash(), &iter) );
- *ppType = (SType *) iter.GetData().pNew;
-
-lExit:
- return hr;
-}
-
-// Replace *ppString with the corresponding value in pMappingTable
-// pMappingTable table describes how to map old string pointers to new string pointers
-static HRESULT RemapString(_In_ char **ppString, _Inout_ CPointerMappingTable *pMappingTable)
-{
- HRESULT hr = S_OK;
-
- SPointerMapping ptrMapping;
- CPointerMappingTable::CIterator iter;
- ptrMapping.pOld = *ppString;
- VH( pMappingTable->FindValueWithHash(ptrMapping, ptrMapping.Hash(), &iter) );
- *ppString = (char *) iter.GetData().pNew;
-
-lExit:
- return hr;
-}
-
-// Used in cloning, copy m_pMemberInterfaces from pEffectSource to this
-HRESULT CEffect::CopyMemberInterfaces( _In_ CEffect* pEffectSource )
-{
- HRESULT hr = S_OK;
-
- uint32_t Members = pEffectSource->m_pMemberInterfaces.GetSize();
- m_pMemberInterfaces.AddRange(Members);
- uint32_t i=0; // after a failure, this holds the failing index
- for(; i < Members; i++ )
- {
- SMember* pOldMember = pEffectSource->m_pMemberInterfaces[i];
- if( pOldMember == nullptr )
- {
- // During Optimization, m_pMemberInterfaces[i] was set to nullptr because it was an annotation
- m_pMemberInterfaces[i] = nullptr;
- continue;
- }
-
- SMember *pNewMember;
- assert( pOldMember->pTopLevelEntity != nullptr );
-
- if (nullptr == (pNewMember = CreateNewMember((SType*)pOldMember->pType, false)))
- {
- DPF(0, "ID3DX11Effect: Out of memory while trying to create new member variable interface");
- VN( pNewMember );
- }
-
- pNewMember->pType = pOldMember->pType;
- pNewMember->pName = pOldMember->pName;
- pNewMember->pSemantic = pOldMember->pSemantic;
- pNewMember->Data.pGeneric = pOldMember->Data.pGeneric;
- pNewMember->IsSingleElement = pOldMember->IsSingleElement;
- pNewMember->pTopLevelEntity = pOldMember->pTopLevelEntity;
- pNewMember->pMemberData = pOldMember->pMemberData;
-
- m_pMemberInterfaces[i] = pNewMember;
- }
-
-lExit:
- if( FAILED(hr) )
- {
- assert( i < Members );
- ZeroMemory( &m_pMemberInterfaces[i], sizeof(SMember) * ( Members - i ) );
- }
- return hr;
-}
-
-// Used in cloning, copy the string pool from pEffectSource to this and build mappingTable
-// for use in RemapString
-_Use_decl_annotations_
-HRESULT CEffect::CopyStringPool( CEffect* pEffectSource, CPointerMappingTable& mappingTable )
-{
- HRESULT hr = S_OK;
- assert( m_pPooledHeap != 0 );
- _Analysis_assume_( m_pPooledHeap != 0 );
- VN( m_pStringPool = new CEffect::CStringHashTable );
- m_pStringPool->SetPrivateHeap(m_pPooledHeap);
- VH( m_pStringPool->AutoGrow() );
-
- CStringHashTable::CIterator stringIter;
-
- // move strings over, build mapping table
- for (pEffectSource->m_pStringPool->GetFirstEntry(&stringIter); !pEffectSource->m_pStringPool->PastEnd(&stringIter); pEffectSource->m_pStringPool->GetNextEntry(&stringIter))
- {
- SPointerMapping ptrMapping;
- char *pString;
-
- const char* pOldString = stringIter.GetData();
- ptrMapping.pOld = (void*)pOldString;
- uint32_t len = (uint32_t)strlen(pOldString);
- uint32_t hash = ptrMapping.Hash();
- VN( pString = new(*m_pPooledHeap) char[len + 1] );
- ptrMapping.pNew = (void*)pString;
- memcpy(ptrMapping.pNew, ptrMapping.pOld, len + 1);
- VH( m_pStringPool->AddValueWithHash(pString, hash) );
-
- VH( mappingTable.AddValueWithHash(ptrMapping, hash) );
- }
-
- // Uncomment to print string mapping
- /*
- CPointerMappingTable::CIterator mapIter;
- for (mappingTable.GetFirstEntry(&mapIter); !mappingTable.PastEnd(&mapIter); mappingTable.GetNextEntry(&mapIter))
- {
- SPointerMapping ptrMapping = mapIter.GetData();
- DPF(0, "string: 0x%x : 0x%x %s", (UINT_PTR)ptrMapping.pOld, (UINT_PTR)ptrMapping.pNew, (char*)ptrMapping.pNew );
- }*/
-
-lExit:
- return hr;
-}
-
-// Used in cloning, copy the unoptimized type pool from pEffectSource to this and build mappingTableTypes
-// for use in RemapType. mappingTableStrings is the mapping table previously filled when copying strings.
-_Use_decl_annotations_
-HRESULT CEffect::CopyTypePool( CEffect* pEffectSource, CPointerMappingTable& mappingTableTypes, CPointerMappingTable& mappingTableStrings )
-{
- HRESULT hr = S_OK;
- assert( m_pPooledHeap != 0 );
- _Analysis_assume_( m_pPooledHeap != 0 );
- VN( m_pTypePool = new CEffect::CTypeHashTable );
- m_pTypePool->SetPrivateHeap(m_pPooledHeap);
- VH( m_pTypePool->AutoGrow() );
-
- CTypeHashTable::CIterator typeIter;
- CPointerMappingTable::CIterator mapIter;
-
- // first pass: move types over, build mapping table
- for (pEffectSource->m_pTypePool->GetFirstEntry(&typeIter); !pEffectSource->m_pTypePool->PastEnd(&typeIter); pEffectSource->m_pTypePool->GetNextEntry(&typeIter))
- {
- SPointerMapping ptrMapping;
- SType *pType;
-
- ptrMapping.pOld = typeIter.GetData();
- uint32_t hash = ptrMapping.Hash();
- VN( (ptrMapping.pNew) = new(*m_pPooledHeap) SType );
- memcpy(ptrMapping.pNew, ptrMapping.pOld, sizeof(SType));
-
- pType = (SType *) ptrMapping.pNew;
-
- // if this is a struct, move its members to the newly allocated space
- if (EVT_Struct == pType->VarType)
- {
- SVariable* pOldMembers = pType->StructType.pMembers;
- VN( pType->StructType.pMembers = new(*m_pPooledHeap) SVariable[pType->StructType.Members] );
- memcpy(pType->StructType.pMembers, pOldMembers, pType->StructType.Members * sizeof(SVariable));
- }
-
- VH( m_pTypePool->AddValueWithHash(pType, hash) );
- VH( mappingTableTypes.AddValueWithHash(ptrMapping, hash) );
- }
-
- // second pass: fixup structure member & name pointers
- for (mappingTableTypes.GetFirstEntry(&mapIter); !mappingTableTypes.PastEnd(&mapIter); mappingTableTypes.GetNextEntry(&mapIter))
- {
- SPointerMapping ptrMapping = mapIter.GetData();
-
- // Uncomment to print type mapping
- //DPF(0, "type: 0x%x : 0x%x", (UINT_PTR)ptrMapping.pOld, (UINT_PTR)ptrMapping.pNew );
-
- SType *pType = (SType *) ptrMapping.pNew;
-
- if( pType->pTypeName )
- {
- VH( RemapString(&pType->pTypeName, &mappingTableStrings) );
- }
-
- // if this is a struct, fix up its members' pointers
- if (EVT_Struct == pType->VarType)
- {
- for (uint32_t i = 0; i < pType->StructType.Members; ++ i)
- {
- VH( RemapType((SType**)&pType->StructType.pMembers[i].pType, &mappingTableTypes) );
- if( pType->StructType.pMembers[i].pName )
- {
- VH( RemapString(&pType->StructType.pMembers[i].pName, &mappingTableStrings) );
- }
- if( pType->StructType.pMembers[i].pSemantic )
- {
- VH( RemapString(&pType->StructType.pMembers[i].pSemantic, &mappingTableStrings) );
- }
- }
- }
- }
-
-lExit:
- return hr;
-}
-
-// Used in cloning, copy the unoptimized type pool from pEffectSource to this and build mappingTableTypes
-// for use in RemapType. mappingTableStrings is the mapping table previously filled when copying strings.
-_Use_decl_annotations_
-HRESULT CEffect::CopyOptimizedTypePool( CEffect* pEffectSource, CPointerMappingTable& mappingTableTypes )
-{
- HRESULT hr = S_OK;
- CEffectHeap* pOptimizedTypeHeap = nullptr;
-
- assert( pEffectSource->m_pOptimizedTypeHeap != 0 );
- _Analysis_assume_( pEffectSource->m_pOptimizedTypeHeap != 0 );
- assert( m_pTypePool == 0 );
- assert( m_pStringPool == 0 );
- assert( m_pPooledHeap == 0 );
-
- VN( pOptimizedTypeHeap = new CEffectHeap );
- VH( pOptimizedTypeHeap->ReserveMemory( pEffectSource->m_pOptimizedTypeHeap->GetSize() ) );
- CPointerMappingTable::CIterator mapIter;
-
- // first pass: move types over, build mapping table
- uint8_t* pReadTypes = pEffectSource->m_pOptimizedTypeHeap->GetDataStart();
- while( pEffectSource->m_pOptimizedTypeHeap->IsInHeap( pReadTypes ) )
- {
- SPointerMapping ptrMapping;
- SType *pType;
- uint32_t moveSize;
-
- ptrMapping.pOld = ptrMapping.pNew = pReadTypes;
- moveSize = sizeof(SType);
- VH( pOptimizedTypeHeap->MoveData(&ptrMapping.pNew, moveSize) );
- pReadTypes += moveSize;
-
- pType = (SType *) ptrMapping.pNew;
-
- // if this is a struct, move its members to the newly allocated space
- if (EVT_Struct == pType->VarType)
- {
- moveSize = pType->StructType.Members * sizeof(SVariable);
- VH( pOptimizedTypeHeap->MoveData((void **)&pType->StructType.pMembers, moveSize) );
- pReadTypes += moveSize;
- }
-
- VH( mappingTableTypes.AddValueWithHash(ptrMapping, ptrMapping.Hash()) );
- }
-
- // second pass: fixup structure member & name pointers
- for (mappingTableTypes.GetFirstEntry(&mapIter); !mappingTableTypes.PastEnd(&mapIter); mappingTableTypes.GetNextEntry(&mapIter))
- {
- SPointerMapping ptrMapping = mapIter.GetData();
-
- // Uncomment to print type mapping
- //DPF(0, "type: 0x%x : 0x%x", (UINT_PTR)ptrMapping.pOld, (UINT_PTR)ptrMapping.pNew );
-
- SType *pType = (SType *) ptrMapping.pNew;
-
- // if this is a struct, fix up its members' pointers
- if (EVT_Struct == pType->VarType)
- {
- for (uint32_t i = 0; i < pType->StructType.Members; ++ i)
- {
- VH( RemapType((SType**)&pType->StructType.pMembers[i].pType, &mappingTableTypes) );
- }
- }
- }
-
-lExit:
- return hr;
-}
-
-// Used in cloning, create new ID3D11ConstantBuffers for each non-single CB
-HRESULT CEffect::RecreateCBs()
-{
- HRESULT hr = S_OK;
- uint32_t i; // after a failure, this holds the failing index
-
- for (i = 0; i < m_CBCount; ++ i)
- {
- SConstantBuffer* pCB = &m_pCBs[i];
-
- pCB->IsNonUpdatable = pCB->IsUserManaged || pCB->ClonedSingle();
-
- if( pCB->Size > 0 && !pCB->ClonedSingle() )
- {
- ID3D11Buffer** ppOriginalBuffer;
- ID3D11ShaderResourceView** ppOriginalTBufferView;
-
- if( pCB->IsUserManaged )
- {
- ppOriginalBuffer = &pCB->pMemberData[0].Data.pD3DEffectsManagedConstantBuffer;
- ppOriginalTBufferView = &pCB->pMemberData[1].Data.pD3DEffectsManagedTextureBuffer;
- }
- else
- {
- ppOriginalBuffer = &pCB->pD3DObject;
- ppOriginalTBufferView = &pCB->TBuffer.pShaderResource;
- }
-
- VN( *ppOriginalBuffer );
- D3D11_BUFFER_DESC bufDesc;
- (*ppOriginalBuffer)->GetDesc( &bufDesc );
- ID3D11Buffer* pNewBuffer = nullptr;
- VH( m_pDevice->CreateBuffer( &bufDesc, nullptr, &pNewBuffer ) );
- SetDebugObjectName( pNewBuffer, "D3DX11Effect" );
- (*ppOriginalBuffer)->Release();
- (*ppOriginalBuffer) = pNewBuffer;
- pNewBuffer = nullptr;
-
- if( pCB->IsTBuffer )
- {
- VN( *ppOriginalTBufferView );
- D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
- (*ppOriginalTBufferView)->GetDesc( &viewDesc );
- ID3D11ShaderResourceView* pNewView = nullptr;
- VH( m_pDevice->CreateShaderResourceView( (*ppOriginalBuffer), &viewDesc, &pNewView) );
- SetDebugObjectName( pNewView, "D3DX11Effect" );
- (*ppOriginalTBufferView)->Release();
- (*ppOriginalTBufferView) = pNewView;
- pNewView = nullptr;
- }
- else
- {
- assert( *ppOriginalTBufferView == nullptr );
- ReplaceCBReference( pCB, (*ppOriginalBuffer) );
- }
-
- pCB->IsDirty = true;
- }
- }
-
-lExit:
- return hr;
-}
-
-// Move Name and Semantic strings using mappingTableStrings
-_Use_decl_annotations_
-HRESULT CEffect::FixupMemberInterface( SMember* pMember, CEffect* pEffectSource, CPointerMappingTable& mappingTableStrings )
-{
- HRESULT hr = S_OK;
-
- if( pMember->pName )
- {
- if( pEffectSource->m_pReflection && pEffectSource->m_pReflection->m_Heap.IsInHeap(pMember->pName) )
- {
- pMember->pName = (char*)((UINT_PTR)pMember->pName - (UINT_PTR)pEffectSource->m_pReflection->m_Heap.GetDataStart() + (UINT_PTR)m_pReflection->m_Heap.GetDataStart());
- }
- else
- {
- VH( RemapString(&pMember->pName, &mappingTableStrings) );
- }
- }
- if( pMember->pSemantic )
- {
- if( pEffectSource->m_pReflection && pEffectSource->m_pReflection->m_Heap.IsInHeap(pMember->pSemantic) )
- {
- pMember->pSemantic = (char*)((UINT_PTR)pMember->pSemantic - (UINT_PTR)pEffectSource->m_pReflection->m_Heap.GetDataStart() + (UINT_PTR)m_pReflection->m_Heap.GetDataStart());
- }
- else
- {
- VH( RemapString(&pMember->pSemantic, &mappingTableStrings) );
- }
- }
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Public API to create a copy of this effect
-HRESULT CEffect::CloneEffect(_In_ uint32_t Flags, _Outptr_ ID3DX11Effect** ppClonedEffect )
-{
- HRESULT hr = S_OK;
- CPointerMappingTable mappingTableTypes;
- CPointerMappingTable mappingTableStrings;
-
- CEffectLoader loader;
- CEffect* pNewEffect = nullptr;
- CDataBlockStore* pTempHeap = nullptr;
-
-
- VN( pNewEffect = new CEffect( m_Flags ) );
- if( Flags & D3DX11_EFFECT_CLONE_FORCE_NONSINGLE )
- {
- // The effect is cloned as if there was no original, so don't mark it as cloned
- pNewEffect->m_Flags &= ~(uint32_t)D3DX11_EFFECT_CLONE;
- }
- else
- {
- pNewEffect->m_Flags |= D3DX11_EFFECT_CLONE;
- }
-
- pNewEffect->m_VariableCount = m_VariableCount;
- pNewEffect->m_pVariables = m_pVariables;
- pNewEffect->m_AnonymousShaderCount = m_AnonymousShaderCount;
- pNewEffect->m_pAnonymousShaders = m_pAnonymousShaders;
- pNewEffect->m_TechniqueCount = m_TechniqueCount;
- pNewEffect->m_GroupCount = m_GroupCount;
- pNewEffect->m_pGroups = m_pGroups;
- pNewEffect->m_pNullGroup = m_pNullGroup;
- pNewEffect->m_ShaderBlockCount = m_ShaderBlockCount;
- pNewEffect->m_pShaderBlocks = m_pShaderBlocks;
- pNewEffect->m_DepthStencilBlockCount = m_DepthStencilBlockCount;
- pNewEffect->m_pDepthStencilBlocks = m_pDepthStencilBlocks;
- pNewEffect->m_BlendBlockCount = m_BlendBlockCount;
- pNewEffect->m_pBlendBlocks = m_pBlendBlocks;
- pNewEffect->m_RasterizerBlockCount = m_RasterizerBlockCount;
- pNewEffect->m_pRasterizerBlocks = m_pRasterizerBlocks;
- pNewEffect->m_SamplerBlockCount = m_SamplerBlockCount;
- pNewEffect->m_pSamplerBlocks = m_pSamplerBlocks;
- pNewEffect->m_MemberDataCount = m_MemberDataCount;
- pNewEffect->m_pMemberDataBlocks = m_pMemberDataBlocks;
- pNewEffect->m_InterfaceCount = m_InterfaceCount;
- pNewEffect->m_pInterfaces = m_pInterfaces;
- pNewEffect->m_CBCount = m_CBCount;
- pNewEffect->m_pCBs = m_pCBs;
- pNewEffect->m_StringCount = m_StringCount;
- pNewEffect->m_pStrings = m_pStrings;
- pNewEffect->m_ShaderResourceCount = m_ShaderResourceCount;
- pNewEffect->m_pShaderResources = m_pShaderResources;
- pNewEffect->m_UnorderedAccessViewCount = m_UnorderedAccessViewCount;
- pNewEffect->m_pUnorderedAccessViews = m_pUnorderedAccessViews;
- pNewEffect->m_RenderTargetViewCount = m_RenderTargetViewCount;
- pNewEffect->m_pRenderTargetViews = m_pRenderTargetViews;
- pNewEffect->m_DepthStencilViewCount = m_DepthStencilViewCount;
- pNewEffect->m_pDepthStencilViews = m_pDepthStencilViews;
- pNewEffect->m_LocalTimer = m_LocalTimer;
- pNewEffect->m_FXLIndex = m_FXLIndex;
- pNewEffect->m_pDevice = m_pDevice;
- pNewEffect->m_pClassLinkage = m_pClassLinkage;
-
- pNewEffect->AddRefAllForCloning( this );
-
-
- // m_pMemberInterfaces is a vector of cbuffer members that were created when the user called GetMemberBy* or GetElement
- // or during Effect loading when an interface is initialized to a global class variable elment.
- VH( pNewEffect->CopyMemberInterfaces( this ) );
-
- loader.m_pvOldMemberInterfaces = &m_pMemberInterfaces;
- loader.m_pEffect = pNewEffect;
- loader.m_EffectMemory = loader.m_ReflectionMemory = 0;
-
-
- // Move data from current effect to new effect
- if( !IsOptimized() )
- {
- VN( pNewEffect->m_pReflection = new CEffectReflection() );
- loader.m_pReflection = pNewEffect->m_pReflection;
-
- // make sure strings are moved before ReallocateEffectData
- VH( loader.InitializeReflectionDataAndMoveStrings( m_pReflection->m_Heap.GetSize() ) );
- }
- VH( loader.ReallocateEffectData( true ) );
- if( !IsOptimized() )
- {
- VH( loader.ReallocateReflectionData( true ) );
- }
-
-
- // Data structures for remapping type pointers and string pointers
- VN( pTempHeap = new CDataBlockStore );
- pTempHeap->EnableAlignment();
- mappingTableTypes.SetPrivateHeap(pTempHeap);
- mappingTableStrings.SetPrivateHeap(pTempHeap);
- VH( mappingTableTypes.AutoGrow() );
- VH( mappingTableStrings.AutoGrow() );
-
- if( !IsOptimized() )
- {
- // Let's re-create the type pool and string pool
- VN( pNewEffect->m_pPooledHeap = new CDataBlockStore );
- pNewEffect->m_pPooledHeap->EnableAlignment();
-
- VH( pNewEffect->CopyStringPool( this, mappingTableStrings ) );
- VH( pNewEffect->CopyTypePool( this, mappingTableTypes, mappingTableStrings ) );
- }
- else
- {
- // There's no string pool after optimizing. Let's re-create the type pool
- VH( pNewEffect->CopyOptimizedTypePool( this, mappingTableTypes ) );
- }
-
- // fixup this effect's variable's types
- VH( pNewEffect->OptimizeTypes(&mappingTableTypes, true) );
- VH( pNewEffect->RecreateCBs() );
-
-
- for (uint32_t i = 0; i < pNewEffect->m_pMemberInterfaces.GetSize(); ++ i)
- {
- SMember* pMember = pNewEffect->m_pMemberInterfaces[i];
- VH( pNewEffect->FixupMemberInterface( pMember, this, mappingTableStrings ) );
- }
-
-
-lExit:
- SAFE_DELETE( pTempHeap );
- if( FAILED( hr ) )
- {
- SAFE_DELETE( pNewEffect );
- }
- *ppClonedEffect = pNewEffect;
- return hr;
-}
-
-// Move all type pointers using pMappingTable.
-// This is called after creating the optimized type pool or during cloning.
-HRESULT CEffect::OptimizeTypes(_Inout_ CPointerMappingTable *pMappingTable, _In_ bool Cloning)
-{
- HRESULT hr = S_OK;
-
- // find all child types, point them to the new location
- for (size_t i = 0; i < m_VariableCount; ++ i)
- {
- VH( RemapType((SType**)&m_pVariables[i].pType, pMappingTable) );
- }
-
- uint32_t Members = m_pMemberInterfaces.GetSize();
- for( size_t i=0; i < Members; i++ )
- {
- if( m_pMemberInterfaces[i] != nullptr )
- {
- VH( RemapType((SType**)&m_pMemberInterfaces[i]->pType, pMappingTable) );
- }
- }
-
- // when cloning, there may be annotations
- if( Cloning )
- {
- for (size_t iVar = 0; iVar < m_VariableCount; ++ iVar)
- {
- for(size_t i = 0; i < m_pVariables[iVar].AnnotationCount; ++ i )
- {
- VH( RemapType((SType**)&m_pVariables[iVar].pAnnotations[i].pType, pMappingTable) );
- }
- }
- for (size_t iCB = 0; iCB < m_CBCount; ++ iCB)
- {
- for(size_t i = 0; i < m_pCBs[iCB].AnnotationCount; ++ i )
- {
- VH( RemapType((SType**)&m_pCBs[iCB].pAnnotations[i].pType, pMappingTable) );
- }
- }
- for (size_t iGroup = 0; iGroup < m_GroupCount; ++ iGroup)
- {
- for(size_t i = 0; i < m_pGroups[iGroup].AnnotationCount; ++ i )
- {
- VH( RemapType((SType**)&m_pGroups[iGroup].pAnnotations[i].pType, pMappingTable) );
- }
- for(size_t iTech = 0; iTech < m_pGroups[iGroup].TechniqueCount; ++ iTech )
- {
- for(size_t i = 0; i < m_pGroups[iGroup].pTechniques[iTech].AnnotationCount; ++ i )
- {
- VH( RemapType((SType**)&m_pGroups[iGroup].pTechniques[iTech].pAnnotations[i].pType, pMappingTable) );
- }
- for(size_t iPass = 0; iPass < m_pGroups[iGroup].pTechniques[iTech].PassCount; ++ iPass )
- {
- for(size_t i = 0; i < m_pGroups[iGroup].pTechniques[iTech].pPasses[iPass].AnnotationCount; ++ i )
- {
- VH( RemapType((SType**)&m_pGroups[iGroup].pTechniques[iTech].pPasses[iPass].pAnnotations[i].pType, pMappingTable) );
- }
- }
- }
- }
- }
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Public API to shed this effect of its reflection data
-
-HRESULT CEffect::Optimize()
-{
- HRESULT hr = S_OK;
- CEffectHeap *pOptimizedTypeHeap = nullptr;
-
- if (IsOptimized())
- {
- DPF(0, "ID3DX11Effect::Optimize: Effect has already been Optimize()'ed");
- return S_OK;
- }
-
- // Delete annotations, names, semantics, and string data on variables
-
- for (size_t i = 0; i < m_VariableCount; ++ i)
- {
- m_pVariables[i].AnnotationCount = 0;
- m_pVariables[i].pAnnotations = nullptr;
- m_pVariables[i].pName = nullptr;
- m_pVariables[i].pSemantic = nullptr;
-
- // 2) Point string variables to nullptr
- if (m_pVariables[i].pType->IsObjectType(EOT_String))
- {
- assert(nullptr != m_pVariables[i].Data.pString);
- m_pVariables[i].Data.pString = nullptr;
- }
- }
-
- // Delete annotations and names on CBs
-
- for (size_t i = 0; i < m_CBCount; ++ i)
- {
- m_pCBs[i].AnnotationCount = 0;
- m_pCBs[i].pAnnotations = nullptr;
- m_pCBs[i].pName = nullptr;
- m_pCBs[i].IsEffectOptimized = true;
- }
-
- // Delete annotations and names on techniques and passes
-
- for (size_t i = 0; i < m_GroupCount; ++ i)
- {
- m_pGroups[i].AnnotationCount = 0;
- m_pGroups[i].pAnnotations = nullptr;
- m_pGroups[i].pName = nullptr;
-
- for (size_t j = 0; j < m_pGroups[i].TechniqueCount; ++ j)
- {
- m_pGroups[i].pTechniques[j].AnnotationCount = 0;
- m_pGroups[i].pTechniques[j].pAnnotations = nullptr;
- m_pGroups[i].pTechniques[j].pName = nullptr;
-
- for (size_t k = 0; k < m_pGroups[i].pTechniques[j].PassCount; ++ k)
- {
- m_pGroups[i].pTechniques[j].pPasses[k].AnnotationCount = 0;
- m_pGroups[i].pTechniques[j].pPasses[k].pAnnotations = nullptr;
- m_pGroups[i].pTechniques[j].pPasses[k].pName = nullptr;
- }
- }
- };
-
- // 2) Remove shader bytecode & stream out decls
- // (all are contained within pReflectionData)
-
- for (size_t i = 0; i < m_ShaderBlockCount; ++ i)
- {
- if( m_pShaderBlocks[i].pReflectionData )
- {
- // pReflection was not created with PRIVATENEW
- SAFE_RELEASE( m_pShaderBlocks[i].pReflectionData->pReflection );
-
- m_pShaderBlocks[i].pReflectionData = nullptr;
- }
- }
-
- uint32_t Members = m_pMemberInterfaces.GetSize();
- for( size_t i=0; i < Members; i++ )
- {
- assert( m_pMemberInterfaces[i] != nullptr );
- if( IsReflectionData(m_pMemberInterfaces[i]->pTopLevelEntity) )
- {
- assert( IsReflectionData(m_pMemberInterfaces[i]->Data.pGeneric) );
-
- // This is checked when cloning (so we don't clone Optimized-out member variables)
- m_pMemberInterfaces[i] = nullptr;
- }
- else
- {
- m_pMemberInterfaces[i]->pName = nullptr;
- m_pMemberInterfaces[i]->pSemantic = nullptr;
- }
- }
-
-
-
- // get rid of the name/type hash tables and string data,
- // then reallocate the type data and fix up this effect
- CPointerMappingTable mappingTable;
- CTypeHashTable::CIterator typeIter;
- CPointerMappingTable::CIterator mapIter;
- CCheckedDword chkSpaceNeeded = 0;
- uint32_t spaceNeeded;
-
- // first pass: compute needed space
- for (m_pTypePool->GetFirstEntry(&typeIter); !m_pTypePool->PastEnd(&typeIter); m_pTypePool->GetNextEntry(&typeIter))
- {
- SType *pType = typeIter.GetData();
-
- chkSpaceNeeded += AlignToPowerOf2(sizeof(SType), c_DataAlignment);
-
- // if this is a struct, allocate room for its members
- if (EVT_Struct == pType->VarType)
- {
- chkSpaceNeeded += AlignToPowerOf2(pType->StructType.Members * sizeof(SVariable), c_DataAlignment);
- }
- }
-
- VH( chkSpaceNeeded.GetValue(&spaceNeeded) );
-
- assert(nullptr == m_pOptimizedTypeHeap);
- VN( pOptimizedTypeHeap = new CEffectHeap );
- VH( pOptimizedTypeHeap->ReserveMemory(spaceNeeded));
-
- // use the private heap that we're about to destroy as scratch space for the mapping table
- mappingTable.SetPrivateHeap(m_pPooledHeap);
- VH( mappingTable.AutoGrow() );
-
- // second pass: move types over, build mapping table
- for (m_pTypePool->GetFirstEntry(&typeIter); !m_pTypePool->PastEnd(&typeIter); m_pTypePool->GetNextEntry(&typeIter))
- {
- SPointerMapping ptrMapping;
- SType *pType;
-
- ptrMapping.pOld = ptrMapping.pNew = typeIter.GetData();
- VH( pOptimizedTypeHeap->MoveData(&ptrMapping.pNew, sizeof(SType)) );
-
- pType = (SType *) ptrMapping.pNew;
-
- // if this is a struct, move its members to the newly allocated space
- if (EVT_Struct == pType->VarType)
- {
- VH( pOptimizedTypeHeap->MoveData((void **)&pType->StructType.pMembers, pType->StructType.Members * sizeof(SVariable)) );
- }
-
- VH( mappingTable.AddValueWithHash(ptrMapping, ptrMapping.Hash()) );
- }
-
- // third pass: fixup structure member & name pointers
- for (mappingTable.GetFirstEntry(&mapIter); !mappingTable.PastEnd(&mapIter); mappingTable.GetNextEntry(&mapIter))
- {
- SPointerMapping ptrMapping = mapIter.GetData();
- SType *pType = (SType *) ptrMapping.pNew;
-
- pType->pTypeName = nullptr;
-
- // if this is a struct, fix up its members' pointers
- if (EVT_Struct == pType->VarType)
- {
- for (size_t i = 0; i < pType->StructType.Members; ++ i)
- {
- VH( RemapType((SType**)&pType->StructType.pMembers[i].pType, &mappingTable) );
- pType->StructType.pMembers[i].pName = nullptr;
- pType->StructType.pMembers[i].pSemantic = nullptr;
- }
- }
- }
-
- // fixup this effect's variable's types
- VH( OptimizeTypes(&mappingTable) );
-
- m_pOptimizedTypeHeap = pOptimizedTypeHeap;
- pOptimizedTypeHeap = nullptr;
-
-#ifdef D3DX11_FX_PRINT_HASH_STATS
- DPF(0, "Compiler string pool hash table statistics:");
- m_pTypePool->PrintHashTableStats();
- DPF(0, "Compiler type pool hash table statistics:");
- m_pStringPool->PrintHashTableStats();
-#endif // D3DX11_FX_PRINT_HASH_STATS
-
- SAFE_DELETE(m_pTypePool);
- SAFE_DELETE(m_pStringPool);
- SAFE_DELETE(m_pPooledHeap);
-
- DPF(0, "ID3DX11Effect::Optimize: %u bytes of reflection data freed.", m_pReflection->m_Heap.GetSize());
- SAFE_DELETE(m_pReflection);
- m_Flags |= D3DX11_EFFECT_OPTIMIZED;
-
-lExit:
- SAFE_DELETE(pOptimizedTypeHeap);
- return hr;
-}
-
-SMember * CreateNewMember(_In_ SType *pType, _In_ bool IsAnnotation)
-{
- switch (pType->VarType)
- {
- case EVT_Struct:
- if (IsAnnotation)
- {
- assert(sizeof(SNumericAnnotationMember) == sizeof(SMember));
- return (SMember*) new SNumericAnnotationMember;
- }
- else if (pType->StructType.ImplementsInterface)
- {
- assert(sizeof(SClassInstanceGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SClassInstanceGlobalVariableMember;
- }
- else
- {
- assert(sizeof(SNumericGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SNumericGlobalVariableMember;
- }
- break;
- case EVT_Interface:
- assert(sizeof(SInterfaceGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SInterfaceGlobalVariableMember;
- break;
- case EVT_Object:
- switch (pType->ObjectType)
- {
- case EOT_String:
- if (IsAnnotation)
- {
- assert(sizeof(SStringAnnotationMember) == sizeof(SMember));
- return (SMember*) new SStringAnnotationMember;
- }
- else
- {
- assert(sizeof(SStringGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SStringGlobalVariableMember;
- }
-
- break;
- case EOT_Texture:
- case EOT_Texture1D:
- case EOT_Texture1DArray:
- case EOT_Texture2D:
- case EOT_Texture2DArray:
- case EOT_Texture2DMS:
- case EOT_Texture2DMSArray:
- case EOT_Texture3D:
- case EOT_TextureCube:
- case EOT_TextureCubeArray:
- case EOT_Buffer:
- case EOT_ByteAddressBuffer:
- case EOT_StructuredBuffer:
- assert(!IsAnnotation);
- assert(sizeof(SShaderResourceGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SShaderResourceGlobalVariableMember;
- break;
- case EOT_RWTexture1D:
- case EOT_RWTexture1DArray:
- case EOT_RWTexture2D:
- case EOT_RWTexture2DArray:
- case EOT_RWTexture3D:
- case EOT_RWBuffer:
- case EOT_RWByteAddressBuffer:
- case EOT_RWStructuredBuffer:
- case EOT_RWStructuredBufferAlloc:
- case EOT_RWStructuredBufferConsume:
- case EOT_AppendStructuredBuffer:
- case EOT_ConsumeStructuredBuffer:
- assert(!IsAnnotation);
- assert(sizeof(SUnorderedAccessViewGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SUnorderedAccessViewGlobalVariableMember;
- break;
- case EOT_VertexShader:
- case EOT_VertexShader5:
- case EOT_GeometryShader:
- case EOT_GeometryShaderSO:
- case EOT_GeometryShader5:
- case EOT_PixelShader:
- case EOT_PixelShader5:
- case EOT_HullShader5:
- case EOT_DomainShader5:
- case EOT_ComputeShader5:
- assert(!IsAnnotation);
- assert(sizeof(SShaderGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SShaderGlobalVariableMember;
- break;
- case EOT_Blend:
- assert(!IsAnnotation);
- assert(sizeof(SBlendGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SBlendGlobalVariableMember;
- break;
- case EOT_Rasterizer:
- assert(!IsAnnotation);
- assert(sizeof(SRasterizerGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SRasterizerGlobalVariableMember;
- break;
- case EOT_DepthStencil:
- assert(!IsAnnotation);
- assert(sizeof(SDepthStencilGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SDepthStencilGlobalVariableMember;
- break;
- case EOT_Sampler:
- assert(!IsAnnotation);
- assert(sizeof(SSamplerGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SSamplerGlobalVariableMember;
- break;
- case EOT_DepthStencilView:
- assert(!IsAnnotation);
- assert(sizeof(SDepthStencilViewGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SDepthStencilViewGlobalVariableMember;
- break;
- case EOT_RenderTargetView:
- assert(!IsAnnotation);
- assert(sizeof(SRenderTargetViewGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SRenderTargetViewGlobalVariableMember;
- break;
- default:
- assert(0);
- DPF( 0, "Internal error: invalid object type." );
- return nullptr;
- break;
- }
- break;
- case EVT_Numeric:
- switch (pType->NumericType.NumericLayout)
- {
- case ENL_Matrix:
- if (IsAnnotation)
- {
- assert(sizeof(SMatrixAnnotationMember) == sizeof(SMember));
- return (SMember*) new SMatrixAnnotationMember;
- }
- else
- {
- assert(sizeof(SMatrixGlobalVariableMember) == sizeof(SMember));
- assert(sizeof(SMatrix4x4ColumnMajorGlobalVariableMember) == sizeof(SMember));
- assert(sizeof(SMatrix4x4RowMajorGlobalVariableMember) == sizeof(SMember));
-
- if (pType->NumericType.Rows == 4 && pType->NumericType.Columns == 4)
- {
- if (pType->NumericType.IsColumnMajor)
- {
- return (SMember*) new SMatrix4x4ColumnMajorGlobalVariableMember;
- }
- else
- {
- return (SMember*) new SMatrix4x4RowMajorGlobalVariableMember;
- }
- }
- else
- {
- return (SMember*) new SMatrixGlobalVariableMember;
- }
- }
- break;
- case ENL_Vector:
- switch (pType->NumericType.ScalarType)
- {
- case EST_Float:
- if (IsAnnotation)
- {
- assert(sizeof(SFloatVectorAnnotationMember) == sizeof(SMember));
- return (SMember*) new SFloatVectorAnnotationMember;
- }
- else
- {
- assert(sizeof(SFloatVectorGlobalVariableMember) == sizeof(SMember));
- assert(sizeof(SFloatVector4GlobalVariableMember) == sizeof(SMember));
-
- if (pType->NumericType.Columns == 4)
- {
- return (SMember*) new SFloatVector4GlobalVariableMember;
- }
- else
- {
- return (SMember*) new SFloatVectorGlobalVariableMember;
- }
- }
- break;
- case EST_Bool:
- if (IsAnnotation)
- {
- assert(sizeof(SBoolVectorAnnotationMember) == sizeof(SMember));
- return (SMember*) new SBoolVectorAnnotationMember;
- }
- else
- {
- assert(sizeof(SBoolVectorGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SBoolVectorGlobalVariableMember;
- }
- break;
- case EST_UInt:
- case EST_Int:
- if (IsAnnotation)
- {
- assert(sizeof(SIntVectorAnnotationMember) == sizeof(SMember));
- return (SMember*) new SIntVectorAnnotationMember;
- }
- else
- {
- assert(sizeof(SIntVectorGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SIntVectorGlobalVariableMember;
- }
- break;
- default:
- assert(0);
- DPF( 0, "Internal loading error: invalid vector type." );
- break;
- }
- break;
- case ENL_Scalar:
- switch (pType->NumericType.ScalarType)
- {
- case EST_Float:
- if (IsAnnotation)
- {
- assert(sizeof(SFloatScalarAnnotationMember) == sizeof(SMember));
- return (SMember*) new SFloatScalarAnnotationMember;
- }
- else
- {
- assert(sizeof(SFloatScalarGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SFloatScalarGlobalVariableMember;
- }
- break;
- case EST_UInt:
- case EST_Int:
- if (IsAnnotation)
- {
- assert(sizeof(SIntScalarAnnotationMember) == sizeof(SMember));
- return (SMember*) new SIntScalarAnnotationMember;
- }
- else
- {
- assert(sizeof(SIntScalarGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SIntScalarGlobalVariableMember;
- }
- break;
- case EST_Bool:
- if (IsAnnotation)
- {
- assert(sizeof(SBoolScalarAnnotationMember) == sizeof(SMember));
- return (SMember*) new SBoolScalarAnnotationMember;
- }
- else
- {
- assert(sizeof(SBoolScalarGlobalVariableMember) == sizeof(SMember));
- return (SMember*) new SBoolScalarGlobalVariableMember;
- }
- break;
- default:
- DPF( 0, "Internal loading error: invalid scalar type." );
- assert(0);
- break;
- }
- break;
- default:
- assert(0);
- DPF( 0, "Internal loading error: invalid numeric type." );
- break;
- }
- break;
- default:
- assert(0);
- DPF( 0, "Internal loading error: invalid variable type." );
- break;
- }
- return nullptr;
-}
-
-// Global variables are created in place because storage for them was allocated during LoadEffect
-HRESULT PlacementNewVariable(_In_ void *pVar, _In_ SType *pType, _In_ bool IsAnnotation)
-{
- switch (pType->VarType)
- {
- case EVT_Struct:
- if (IsAnnotation)
- {
- assert(sizeof(SNumericAnnotation) == sizeof(SAnnotation));
- new(pVar) SNumericAnnotation();
- }
- else if (pType->StructType.ImplementsInterface)
- {
- assert(sizeof(SClassInstanceGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SClassInstanceGlobalVariable;
- }
- else
- {
- assert(sizeof(SNumericGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SNumericGlobalVariable;
- }
- break;
- case EVT_Interface:
- assert(sizeof(SInterfaceGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SInterfaceGlobalVariable;
- break;
- case EVT_Object:
- switch (pType->ObjectType)
- {
- case EOT_String:
- if (IsAnnotation)
- {
- assert(sizeof(SStringAnnotation) == sizeof(SAnnotation));
- new(pVar) SStringAnnotation;
- }
- else
- {
- assert(sizeof(SStringGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SStringGlobalVariable;
- }
-
- break;
- case EOT_Texture:
- case EOT_Texture1D:
- case EOT_Texture1DArray:
- case EOT_Texture2D:
- case EOT_Texture2DArray:
- case EOT_Texture2DMS:
- case EOT_Texture2DMSArray:
- case EOT_Texture3D:
- case EOT_TextureCube:
- case EOT_TextureCubeArray:
- case EOT_Buffer:
- case EOT_ByteAddressBuffer:
- case EOT_StructuredBuffer:
- assert(!IsAnnotation);
- assert(sizeof(SShaderResourceGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SShaderResourceGlobalVariable;
- break;
- case EOT_RWTexture1D:
- case EOT_RWTexture1DArray:
- case EOT_RWTexture2D:
- case EOT_RWTexture2DArray:
- case EOT_RWTexture3D:
- case EOT_RWBuffer:
- case EOT_RWByteAddressBuffer:
- case EOT_RWStructuredBuffer:
- case EOT_RWStructuredBufferAlloc:
- case EOT_RWStructuredBufferConsume:
- case EOT_AppendStructuredBuffer:
- case EOT_ConsumeStructuredBuffer:
- assert(!IsAnnotation);
- assert(sizeof(SUnorderedAccessViewGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SUnorderedAccessViewGlobalVariable;
- break;
- case EOT_VertexShader:
- case EOT_VertexShader5:
- case EOT_GeometryShader:
- case EOT_GeometryShaderSO:
- case EOT_GeometryShader5:
- case EOT_PixelShader:
- case EOT_PixelShader5:
- case EOT_HullShader5:
- case EOT_DomainShader5:
- case EOT_ComputeShader5:
- assert(!IsAnnotation);
- assert(sizeof(SShaderGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SShaderGlobalVariable;
- break;
- case EOT_Blend:
- assert(!IsAnnotation);
- assert(sizeof(SBlendGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SBlendGlobalVariable;
- break;
- case EOT_Rasterizer:
- assert(!IsAnnotation);
- assert(sizeof(SRasterizerGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SRasterizerGlobalVariable;
- break;
- case EOT_DepthStencil:
- assert(!IsAnnotation);
- assert(sizeof(SDepthStencilGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SDepthStencilGlobalVariable;
- break;
- case EOT_Sampler:
- assert(!IsAnnotation);
- assert(sizeof(SSamplerGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SSamplerGlobalVariable;
- break;
- case EOT_RenderTargetView:
- assert(!IsAnnotation);
- assert(sizeof(SRenderTargetViewGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SRenderTargetViewGlobalVariable;
- break;
- case EOT_DepthStencilView:
- assert(!IsAnnotation);
- assert(sizeof(SDepthStencilViewGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SDepthStencilViewGlobalVariable;
- break;
- default:
- assert(0);
- DPF( 0, "Internal loading error: invalid object type." );
- return E_FAIL;
- break;
- }
- break;
- case EVT_Numeric:
- switch (pType->NumericType.NumericLayout)
- {
- case ENL_Matrix:
- if (IsAnnotation)
- {
- assert(sizeof(SMatrixAnnotation) == sizeof(SAnnotation));
- new(pVar) SMatrixAnnotation;
- }
- else
- {
- assert(sizeof(SMatrixGlobalVariable) == sizeof(SGlobalVariable));
- assert(sizeof(SMatrix4x4ColumnMajorGlobalVariable) == sizeof(SGlobalVariable));
- assert(sizeof(SMatrix4x4RowMajorGlobalVariable) == sizeof(SGlobalVariable));
-
- if (pType->NumericType.Rows == 4 && pType->NumericType.Columns == 4)
- {
- if (pType->NumericType.IsColumnMajor)
- {
- new(pVar) SMatrix4x4ColumnMajorGlobalVariable;
- }
- else
- {
- new(pVar) SMatrix4x4RowMajorGlobalVariable;
- }
- }
- else
- {
- new(pVar) SMatrixGlobalVariable;
- }
- }
- break;
- case ENL_Vector:
- switch (pType->NumericType.ScalarType)
- {
- case EST_Float:
- if (IsAnnotation)
- {
- assert(sizeof(SFloatVectorAnnotation) == sizeof(SAnnotation));
- new(pVar) SFloatVectorAnnotation;
- }
- else
- {
- assert(sizeof(SFloatVectorGlobalVariable) == sizeof(SGlobalVariable));
- assert(sizeof(SFloatVector4GlobalVariable) == sizeof(SGlobalVariable));
-
- if (pType->NumericType.Columns == 4)
- {
- new(pVar) SFloatVector4GlobalVariable;
- }
- else
- {
- new(pVar) SFloatVectorGlobalVariable;
- }
- }
- break;
- case EST_Bool:
- if (IsAnnotation)
- {
- assert(sizeof(SBoolVectorAnnotation) == sizeof(SAnnotation));
- new(pVar) SBoolVectorAnnotation;
- }
- else
- {
- assert(sizeof(SBoolVectorGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SBoolVectorGlobalVariable;
- }
- break;
- case EST_UInt:
- case EST_Int:
- if (IsAnnotation)
- {
- assert(sizeof(SIntVectorAnnotation) == sizeof(SAnnotation));
- new(pVar) SIntVectorAnnotation;
- }
- else
- {
- assert(sizeof(SIntVectorGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SIntVectorGlobalVariable;
- }
- break;
- }
- break;
- case ENL_Scalar:
- switch (pType->NumericType.ScalarType)
- {
- case EST_Float:
- if (IsAnnotation)
- {
- assert(sizeof(SFloatScalarAnnotation) == sizeof(SAnnotation));
- new(pVar) SFloatScalarAnnotation;
- }
- else
- {
- assert(sizeof(SFloatScalarGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SFloatScalarGlobalVariable;
- }
- break;
- case EST_UInt:
- case EST_Int:
- if (IsAnnotation)
- {
- assert(sizeof(SIntScalarAnnotation) == sizeof(SAnnotation));
- new(pVar) SIntScalarAnnotation;
- }
- else
- {
- assert(sizeof(SIntScalarGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SIntScalarGlobalVariable;
- }
- break;
- case EST_Bool:
- if (IsAnnotation)
- {
- assert(sizeof(SBoolScalarAnnotation) == sizeof(SAnnotation));
- new(pVar) SBoolScalarAnnotation;
- }
- else
- {
- assert(sizeof(SBoolScalarGlobalVariable) == sizeof(SGlobalVariable));
- new(pVar) SBoolScalarGlobalVariable;
- }
- break;
- default:
- assert(0);
- DPF( 0, "Internal loading error: invalid scalar type." );
- return E_FAIL;
- break;
- }
- break;
- default:
- assert(0);
- DPF( 0, "Internal loading error: invalid numeric type." );
- return E_FAIL;
- break;
- }
- break;
- default:
- assert(0);
- DPF( 0, "Internal loading error: invalid variable type." );
- return E_FAIL;
- break;
- }
- return S_OK;
-}
-
-}
diff --git a/lib/win32/Effects11/EffectReflection.cpp b/lib/win32/Effects11/EffectReflection.cpp
deleted file mode 100644
index 48e7b67de4..0000000000
--- a/lib/win32/Effects11/EffectReflection.cpp
+++ /dev/null
@@ -1,2183 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectReflection.cpp
-//
-// Direct3D 11 Effects public reflection APIs
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#include "pchfx.h"
-
-namespace D3DX11Effects
-{
-
-SEffectInvalidType g_InvalidType;
-
-SEffectInvalidScalarVariable g_InvalidScalarVariable;
-SEffectInvalidVectorVariable g_InvalidVectorVariable;
-SEffectInvalidMatrixVariable g_InvalidMatrixVariable;
-SEffectInvalidStringVariable g_InvalidStringVariable;
-SEffectInvalidClassInstanceVariable g_InvalidClassInstanceVariable;
-SEffectInvalidInterfaceVariable g_InvalidInterfaceVariable;
-SEffectInvalidShaderResourceVariable g_InvalidShaderResourceVariable;
-SEffectInvalidUnorderedAccessViewVariable g_InvalidUnorderedAccessViewVariable;
-SEffectInvalidRenderTargetViewVariable g_InvalidRenderTargetViewVariable;
-SEffectInvalidDepthStencilViewVariable g_InvalidDepthStencilViewVariable;
-SEffectInvalidConstantBuffer g_InvalidConstantBuffer;
-SEffectInvalidShaderVariable g_InvalidShaderVariable;
-SEffectInvalidBlendVariable g_InvalidBlendVariable;
-SEffectInvalidDepthStencilVariable g_InvalidDepthStencilVariable;
-SEffectInvalidRasterizerVariable g_InvalidRasterizerVariable;
-SEffectInvalidSamplerVariable g_InvalidSamplerVariable;
-
-SEffectInvalidPass g_InvalidPass;
-SEffectInvalidTechnique g_InvalidTechnique;
-SEffectInvalidGroup g_InvalidGroup;
-
-
-//////////////////////////////////////////////////////////////////////////
-// Helper routine implementations
-//////////////////////////////////////////////////////////////////////////
-
-ID3DX11EffectConstantBuffer * NoParentCB()
-{
- DPF(0, "ID3DX11EffectVariable::GetParentConstantBuffer: Variable does not have a parent constant buffer");
- // have to typecast because the type of g_InvalidScalarVariable has not been declared yet
- return &g_InvalidConstantBuffer;
-}
-
-_Use_decl_annotations_
-ID3DX11EffectVariable * GetAnnotationByIndexHelper(const char *pClassName, uint32_t Index, uint32_t AnnotationCount, SAnnotation *pAnnotations)
-{
- if (Index >= AnnotationCount)
- {
- DPF(0, "%s::GetAnnotationByIndex: Invalid index (%u, total: %u)", pClassName, Index, AnnotationCount);
- return &g_InvalidScalarVariable;
- }
-
- return pAnnotations + Index;
-}
-
-_Use_decl_annotations_
-ID3DX11EffectVariable * GetAnnotationByNameHelper(const char *pClassName, LPCSTR Name, uint32_t AnnotationCount, SAnnotation *pAnnotations)
-{
- uint32_t i;
- for (i = 0; i < AnnotationCount; ++ i)
- {
- if (strcmp(pAnnotations[i].pName, Name) == 0)
- {
- return pAnnotations + i;
- }
- }
-
- DPF(0, "%s::GetAnnotationByName: Annotation [%s] not found", pClassName, Name);
- return &g_InvalidScalarVariable;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// Effect routines to pool interfaces
-//////////////////////////////////////////////////////////////////////////
-
-ID3DX11EffectType * CEffect::CreatePooledSingleElementTypeInterface(_In_ SType *pType)
-{
- if (IsOptimized())
- {
- DPF(0, "ID3DX11Effect: Cannot create new type interfaces since the effect has been Optimize()'ed");
- return &g_InvalidType;
- }
-
- for (size_t i = 0; i < m_pTypeInterfaces.GetSize(); ++ i)
- {
- if (m_pTypeInterfaces[i]->pType == pType)
- {
- return (SSingleElementType*)m_pTypeInterfaces[i];
- }
- }
- SSingleElementType *pNewType;
- if (nullptr == (pNewType = new SSingleElementType))
- {
- DPF(0, "ID3DX11Effect: Out of memory while trying to create new type interface");
- return &g_InvalidType;
- }
-
- pNewType->pType = pType;
- m_pTypeInterfaces.Add(pNewType);
-
- return pNewType;
-}
-
-// Create a member variable (via GetMemberBy* or GetElement)
-_Use_decl_annotations_
-ID3DX11EffectVariable * CEffect::CreatePooledVariableMemberInterface(TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity,
- const SVariable *pMember,
- const UDataPointer Data, bool IsSingleElement, uint32_t Index)
-{
- bool IsAnnotation;
-
- if (IsOptimized())
- {
- DPF(0, "ID3DX11Effect: Cannot create new variable interfaces since the effect has been Optimize()'ed");
- return &g_InvalidScalarVariable;
- }
-
- for (size_t i = 0; i < m_pMemberInterfaces.GetSize(); ++ i)
- {
- if (m_pMemberInterfaces[i]->pType == pMember->pType &&
- m_pMemberInterfaces[i]->pName == pMember->pName &&
- m_pMemberInterfaces[i]->pSemantic == pMember->pSemantic &&
- m_pMemberInterfaces[i]->Data.pGeneric == Data.pGeneric &&
- m_pMemberInterfaces[i]->IsSingleElement == (uint32_t)IsSingleElement &&
- ((SMember*)m_pMemberInterfaces[i])->pTopLevelEntity == pTopLevelEntity)
- {
- return (ID3DX11EffectVariable *) m_pMemberInterfaces[i];
- }
- }
-
- // is this annotation or runtime data?
- if( pTopLevelEntity->pEffect->IsReflectionData(pTopLevelEntity) )
- {
- assert( pTopLevelEntity->pEffect->IsReflectionData(Data.pGeneric) );
- IsAnnotation = true;
- }
- else
- {
- // if the heap is empty, we are still loading the Effect, and thus creating a member for a variable initializer
- // ex. Interface myInt = myClassArray[2];
- if( pTopLevelEntity->pEffect->m_Heap.GetSize() > 0 )
- {
- assert( pTopLevelEntity->pEffect->IsRuntimeData(pTopLevelEntity) );
- if (!pTopLevelEntity->pType->IsObjectType(EOT_String))
- {
- // strings are funny; their data is reflection data, so ignore those
- assert( pTopLevelEntity->pEffect->IsRuntimeData(Data.pGeneric) );
- }
- }
- IsAnnotation = false;
- }
-
- SMember *pNewMember;
-
- if (nullptr == (pNewMember = CreateNewMember((SType*)pMember->pType, IsAnnotation)))
- {
- DPF(0, "ID3DX11Effect: Out of memory while trying to create new member variable interface");
- return &g_InvalidScalarVariable;
- }
-
- pNewMember->pType = pMember->pType;
- pNewMember->pName = pMember->pName;
- pNewMember->pSemantic = pMember->pSemantic;
- pNewMember->Data.pGeneric = Data.pGeneric;
- pNewMember->IsSingleElement = IsSingleElement;
- pNewMember->pTopLevelEntity = pTopLevelEntity;
-
- if( IsSingleElement && pMember->pMemberData )
- {
- assert( !IsAnnotation );
- // This is an element of a global variable array
- pNewMember->pMemberData = pMember->pMemberData + Index;
- }
-
- if (FAILED(m_pMemberInterfaces.Add(pNewMember)))
- {
- SAFE_DELETE(pNewMember);
- DPF(0, "ID3DX11Effect: Out of memory while trying to create new member variable interface");
- return &g_InvalidScalarVariable;
- }
-
- return (ID3DX11EffectVariable *) pNewMember;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectType (SType, SSingleElementType implementations)
-//////////////////////////////////////////////////////////////////////////
-
-static ID3DX11EffectType * GetTypeByIndexHelper(uint32_t Index, uint32_t VariableCount,
- SVariable *pVariables, uint32_t SizeOfVariableType)
-{
- static LPCSTR pFuncName = "ID3DX11EffectType::GetMemberTypeByIndex";
-
- if (Index >= VariableCount)
- {
- DPF(0, "%s: Invalid index (%u, total: %u)", pFuncName, Index, VariableCount);
- return &g_InvalidType;
- }
-
- SVariable *pVariable = (SVariable *)((uint8_t *)pVariables + Index * SizeOfVariableType);
- if (nullptr == pVariable->pName)
- {
- DPF(0, "%s: Cannot get member types; Effect has been Optimize()'ed", pFuncName);
- return &g_InvalidType;
- }
-
- return (ID3DX11EffectType *) pVariable->pType;
-}
-
-static ID3DX11EffectType * GetTypeByNameHelper(LPCSTR Name, uint32_t VariableCount,
- SVariable *pVariables, uint32_t SizeOfVariableType)
-{
- static LPCSTR pFuncName = "ID3DX11EffectType::GetMemberTypeByName";
-
- if (nullptr == Name)
- {
- DPF(0, "%s: Parameter Name was nullptr.", pFuncName);
- return &g_InvalidType;
- }
-
- uint32_t i;
- SVariable *pVariable;
-
- for (i = 0; i < VariableCount; ++ i)
- {
- pVariable = (SVariable *)((uint8_t *)pVariables + i * SizeOfVariableType);
- if (nullptr == pVariable->pName)
- {
- DPF(0, "%s: Cannot get member types; Effect has been Optimize()'ed", pFuncName);
- return &g_InvalidType;
- }
- if (strcmp(pVariable->pName, Name) == 0)
- {
- return (ID3DX11EffectType *) pVariable->pType;
- }
- }
-
- DPF(0, "%s: Member type [%s] not found", pFuncName, Name);
- return &g_InvalidType;
-}
-
-
-static ID3DX11EffectType * GetTypeBySemanticHelper(LPCSTR Semantic, uint32_t VariableCount,
- SVariable *pVariables, uint32_t SizeOfVariableType)
-{
- static LPCSTR pFuncName = "ID3DX11EffectType::GetMemberTypeBySemantic";
-
- if (nullptr == Semantic)
- {
- DPF(0, "%s: Parameter Semantic was nullptr.", pFuncName);
- return &g_InvalidType;
- }
-
- uint32_t i;
- SVariable *pVariable;
-
- for (i = 0; i < VariableCount; ++ i)
- {
- pVariable = (SVariable *)((uint8_t *)pVariables + i * SizeOfVariableType);
- if (nullptr == pVariable->pName)
- {
- DPF(0, "%s: Cannot get member types; Effect has been Optimize()'ed", pFuncName);
- return &g_InvalidType;
- }
- if (nullptr != pVariable->pSemantic &&
- _stricmp(pVariable->pSemantic, Semantic) == 0)
- {
- return (ID3DX11EffectType *) pVariable->pType;
- }
- }
-
- DPF(0, "%s: Member type with semantic [%s] not found", pFuncName, Semantic);
- return &g_InvalidType;
-}
-
-ID3DX11EffectType * SType::GetMemberTypeByIndex(_In_ uint32_t Index)
-{
- if (VarType != EVT_Struct)
- {
- DPF(0, "ID3DX11EffectType::GetMemberTypeByIndex: This interface does not refer to a structure");
- return &g_InvalidType;
- }
-
- return GetTypeByIndexHelper(Index, StructType.Members, StructType.pMembers, sizeof(SVariable));
-}
-
-ID3DX11EffectType * SType::GetMemberTypeByName(_In_z_ LPCSTR Name)
-{
- if (VarType != EVT_Struct)
- {
- DPF(0, "ID3DX11EffectType::GetMemberTypeByName: This interface does not refer to a structure");
- return &g_InvalidType;
- }
-
- return GetTypeByNameHelper(Name, StructType.Members, StructType.pMembers, sizeof(SVariable));
-}
-
-ID3DX11EffectType * SType::GetMemberTypeBySemantic(_In_z_ LPCSTR Semantic)
-{
- if (VarType != EVT_Struct)
- {
- DPF(0, "ID3DX11EffectType::GetMemberTypeBySemantic: This interface does not refer to a structure");
- return &g_InvalidType;
- }
-
- return GetTypeBySemanticHelper(Semantic, StructType.Members, StructType.pMembers, sizeof(SVariable));
-}
-
-LPCSTR SType::GetMemberName(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectType::GetMemberName";
-
- if (VarType != EVT_Struct)
- {
- DPF(0, "%s: This interface does not refer to a structure", pFuncName);
- return nullptr;
- }
-
- if (Index >= StructType.Members)
- {
- DPF(0, "%s: Invalid index (%u, total: %u)", pFuncName, Index, StructType.Members);
- return nullptr;
- }
-
- SVariable *pVariable = StructType.pMembers + Index;
-
- if (nullptr == pVariable->pName)
- {
- DPF(0, "%s: Cannot get member names; Effect has been Optimize()'ed", pFuncName);
- return nullptr;
- }
-
- return pVariable->pName;
-}
-
-LPCSTR SType::GetMemberSemantic(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectType::GetMemberSemantic";
-
- if (VarType != EVT_Struct)
- {
- DPF(0, "%s: This interface does not refer to a structure", pFuncName);
- return nullptr;
- }
-
- if (Index >= StructType.Members)
- {
- DPF(0, "%s: Invalid index (%u, total: %u)", pFuncName, Index, StructType.Members);
- return nullptr;
- }
-
- SVariable *pVariable = StructType.pMembers + Index;
-
- if (nullptr == pVariable->pName)
- {
- DPF(0, "%s: Cannot get member semantics; Effect has been Optimize()'ed", pFuncName);
- return nullptr;
- }
-
- return pVariable->pSemantic;
-}
-
-HRESULT SType::GetDescHelper(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc, _In_ bool IsSingleElement) const
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectType::GetDesc";
-
- VERIFYPARAMETER(pDesc);
-
- pDesc->TypeName = pTypeName;
-
- // intentionally return 0 so they know it's not a single element array
- pDesc->Elements = IsSingleElement ? 0 : Elements;
- pDesc->PackedSize = GetTotalPackedSize(IsSingleElement);
- pDesc->UnpackedSize = GetTotalUnpackedSize(IsSingleElement);
- pDesc->Stride = Stride;
-
- switch (VarType)
- {
- case EVT_Numeric:
- switch (NumericType.NumericLayout)
- {
- case ENL_Matrix:
- if (NumericType.IsColumnMajor)
- {
- pDesc->Class = D3D_SVC_MATRIX_COLUMNS;
- }
- else
- {
- pDesc->Class = D3D_SVC_MATRIX_ROWS;
- }
- break;
- case ENL_Vector:
- pDesc->Class = D3D_SVC_VECTOR;
- break;
- case ENL_Scalar:
- pDesc->Class = D3D_SVC_SCALAR;
- break;
- default:
- assert(0);
- }
-
- switch (NumericType.ScalarType)
- {
- case EST_Bool:
- pDesc->Type = D3D_SVT_BOOL;
- break;
- case EST_Int:
- pDesc->Type = D3D_SVT_INT;
- break;
- case EST_UInt:
- pDesc->Type = D3D_SVT_UINT;
- break;
- case EST_Float:
- pDesc->Type = D3D_SVT_FLOAT;
- break;
- default:
- assert(0);
- }
-
- pDesc->Rows = NumericType.Rows;
- pDesc->Columns = NumericType.Columns;
- pDesc->Members = 0;
-
- break;
-
- case EVT_Struct:
- pDesc->Rows = 0;
- pDesc->Columns = 0;
- pDesc->Members = StructType.Members;
- if( StructType.ImplementsInterface )
- {
- pDesc->Class = D3D_SVC_INTERFACE_CLASS;
- }
- else
- {
- pDesc->Class = D3D_SVC_STRUCT;
- }
- pDesc->Type = D3D_SVT_VOID;
- break;
-
- case EVT_Interface:
- pDesc->Rows = 0;
- pDesc->Columns = 0;
- pDesc->Members = 0;
- pDesc->Class = D3D_SVC_INTERFACE_POINTER;
- pDesc->Type = D3D_SVT_INTERFACE_POINTER;
- break;
-
- case EVT_Object:
- pDesc->Rows = 0;
- pDesc->Columns = 0;
- pDesc->Members = 0;
- pDesc->Class = D3D_SVC_OBJECT;
-
- switch (ObjectType)
- {
- case EOT_String:
- pDesc->Type = D3D_SVT_STRING;
- break;
- case EOT_Blend:
- pDesc->Type = D3D_SVT_BLEND;
- break;
- case EOT_DepthStencil:
- pDesc->Type = D3D_SVT_DEPTHSTENCIL;
- break;
- case EOT_Rasterizer:
- pDesc->Type = D3D_SVT_RASTERIZER;
- break;
- case EOT_PixelShader:
- case EOT_PixelShader5:
- pDesc->Type = D3D_SVT_PIXELSHADER;
- break;
- case EOT_VertexShader:
- case EOT_VertexShader5:
- pDesc->Type = D3D_SVT_VERTEXSHADER;
- break;
- case EOT_GeometryShader:
- case EOT_GeometryShaderSO:
- case EOT_GeometryShader5:
- pDesc->Type = D3D_SVT_GEOMETRYSHADER;
- break;
- case EOT_HullShader5:
- pDesc->Type = D3D_SVT_HULLSHADER;
- break;
- case EOT_DomainShader5:
- pDesc->Type = D3D_SVT_DOMAINSHADER;
- break;
- case EOT_ComputeShader5:
- pDesc->Type = D3D_SVT_COMPUTESHADER;
- break;
- case EOT_Texture:
- pDesc->Type = D3D_SVT_TEXTURE;
- break;
- case EOT_Texture1D:
- pDesc->Type = D3D_SVT_TEXTURE1D;
- break;
- case EOT_Texture1DArray:
- pDesc->Type = D3D_SVT_TEXTURE1DARRAY;
- break;
- case EOT_Texture2D:
- pDesc->Type = D3D_SVT_TEXTURE2D;
- break;
- case EOT_Texture2DArray:
- pDesc->Type = D3D_SVT_TEXTURE2DARRAY;
- break;
- case EOT_Texture2DMS:
- pDesc->Type = D3D_SVT_TEXTURE2DMS;
- break;
- case EOT_Texture2DMSArray:
- pDesc->Type = D3D_SVT_TEXTURE2DMSARRAY;
- break;
- case EOT_Texture3D:
- pDesc->Type = D3D_SVT_TEXTURE3D;
- break;
- case EOT_TextureCube:
- pDesc->Type = D3D_SVT_TEXTURECUBE;
- break;
- case EOT_TextureCubeArray:
- pDesc->Type = D3D_SVT_TEXTURECUBEARRAY;
- break;
- case EOT_Buffer:
- pDesc->Type = D3D_SVT_BUFFER;
- break;
- case EOT_Sampler:
- pDesc->Type = D3D_SVT_SAMPLER;
- break;
- case EOT_RenderTargetView:
- pDesc->Type = D3D_SVT_RENDERTARGETVIEW;
- break;
- case EOT_DepthStencilView:
- pDesc->Type = D3D_SVT_DEPTHSTENCILVIEW;
- break;
- case EOT_RWTexture1D:
- pDesc->Type = D3D_SVT_RWTEXTURE1D;
- break;
- case EOT_RWTexture1DArray:
- pDesc->Type = D3D_SVT_RWTEXTURE1DARRAY;
- break;
- case EOT_RWTexture2D:
- pDesc->Type = D3D_SVT_RWTEXTURE2D;
- break;
- case EOT_RWTexture2DArray:
- pDesc->Type = D3D_SVT_RWTEXTURE2DARRAY;
- break;
- case EOT_RWTexture3D:
- pDesc->Type = D3D_SVT_RWTEXTURE3D;
- break;
- case EOT_RWBuffer:
- pDesc->Type = D3D_SVT_RWBUFFER;
- break;
- case EOT_ByteAddressBuffer:
- pDesc->Type = D3D_SVT_BYTEADDRESS_BUFFER;
- break;
- case EOT_RWByteAddressBuffer:
- pDesc->Type = D3D_SVT_RWBYTEADDRESS_BUFFER;
- break;
- case EOT_StructuredBuffer:
- pDesc->Type = D3D_SVT_STRUCTURED_BUFFER;
- break;
- case EOT_RWStructuredBuffer:
- case EOT_RWStructuredBufferAlloc:
- case EOT_RWStructuredBufferConsume:
- pDesc->Type = D3D_SVT_RWSTRUCTURED_BUFFER;
- break;
- case EOT_AppendStructuredBuffer:
- pDesc->Type = D3D_SVT_APPEND_STRUCTURED_BUFFER;
- break;
- case EOT_ConsumeStructuredBuffer:
- pDesc->Type = D3D_SVT_CONSUME_STRUCTURED_BUFFER;
- break;
-
- default:
- assert(0);
- }
- break;
-
- default:
- assert(0);
- }
-
-lExit:
- return hr;
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectShaderVariable (SAnonymousShader implementation)
-////////////////////////////////////////////////////////////////////////////////
-
-SAnonymousShader::SAnonymousShader(_In_opt_ SShaderBlock *pBlock) noexcept :
- pShaderBlock(pBlock)
-{
-}
-
-bool SAnonymousShader::IsValid()
-{
- return pShaderBlock && pShaderBlock->IsValid;
-}
-
-ID3DX11EffectType * SAnonymousShader::GetType()
-{
- return (ID3DX11EffectType *) this;
-}
-
-HRESULT SAnonymousShader::GetDesc(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc)
-{
- pDesc->Annotations = 0;
- pDesc->Flags = 0;
-
- pDesc->Name = "$Anonymous";
- pDesc->Semantic = nullptr;
- pDesc->BufferOffset = 0;
-
- return S_OK;
-}
-
-ID3DX11EffectVariable * SAnonymousShader::GetAnnotationByIndex(_In_ uint32_t Index)
-{
- UNREFERENCED_PARAMETER(Index);
- DPF(0, "ID3DX11EffectVariable::GetAnnotationByIndex: Anonymous shaders cannot have annotations");
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectVariable * SAnonymousShader::GetAnnotationByName(_In_z_ LPCSTR Name)
-{
- UNREFERENCED_PARAMETER(Name);
- DPF(0, "ID3DX11EffectVariable::GetAnnotationByName: Anonymous shaders cannot have annotations");
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectVariable * SAnonymousShader::GetMemberByIndex(_In_ uint32_t Index)
-{
- UNREFERENCED_PARAMETER(Index);
- DPF(0, "ID3DX11EffectVariable::GetMemberByIndex: Variable is not a structure");
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectVariable * SAnonymousShader::GetMemberByName(_In_z_ LPCSTR Name)
-{
- UNREFERENCED_PARAMETER(Name);
- DPF(0, "ID3DX11EffectVariable::GetMemberByName: Variable is not a structure");
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectVariable * SAnonymousShader::GetMemberBySemantic(_In_z_ LPCSTR Semantic)
-{
- UNREFERENCED_PARAMETER(Semantic);
- DPF(0, "ID3DX11EffectVariable::GetMemberBySemantic: Variable is not a structure");
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectVariable * SAnonymousShader::GetElement(_In_ uint32_t Index)
-{
- UNREFERENCED_PARAMETER(Index);
- DPF(0, "ID3DX11EffectVariable::GetElement: Anonymous shaders cannot have elements");
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectConstantBuffer * SAnonymousShader::GetParentConstantBuffer()
-{
- return NoParentCB();
-}
-
-ID3DX11EffectShaderVariable * SAnonymousShader::AsShader()
-{
- return (ID3DX11EffectShaderVariable *) this;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::SetRawValue(const void *pData, uint32_t Offset, uint32_t Count)
-{
- UNREFERENCED_PARAMETER(pData);
- UNREFERENCED_PARAMETER(Offset);
- UNREFERENCED_PARAMETER(Count);
- return ObjectSetRawValue();
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetRawValue(void *pData, uint32_t Offset, uint32_t Count)
-{
- UNREFERENCED_PARAMETER(pData);
- UNREFERENCED_PARAMETER(Offset);
- UNREFERENCED_PARAMETER(Count);
- return ObjectGetRawValue();
-}
-
-#define ANONYMOUS_SHADER_INDEX_CHECK() \
- HRESULT hr = S_OK; \
- if (0 != ShaderIndex) \
- { \
- DPF(0, "%s: Invalid index specified", pFuncName); \
- VH(E_INVALIDARG); \
- } \
-
-HRESULT SAnonymousShader::GetShaderDesc(_In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetShaderDesc";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- hr = pShaderBlock->GetShaderDesc(pDesc, true);
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetVertexShader(uint32_t ShaderIndex, ID3D11VertexShader **ppVS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetVertexShader";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetVertexShader(ppVS) );
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetGeometryShader(uint32_t ShaderIndex, ID3D11GeometryShader **ppGS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetGeometryShader";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetGeometryShader(ppGS) );
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetPixelShader(uint32_t ShaderIndex, ID3D11PixelShader **ppPS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetPixelShader";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetPixelShader(ppPS) );
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetHullShader(uint32_t ShaderIndex, ID3D11HullShader **ppHS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetHullShader";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetHullShader(ppHS) );
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetDomainShader(uint32_t ShaderIndex, ID3D11DomainShader **ppDS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetDomainShader";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetDomainShader(ppDS) );
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetComputeShader(uint32_t ShaderIndex, ID3D11ComputeShader **ppCS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetComputeShader";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetComputeShader(ppCS) );
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetInputSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetInputSignatureElementDesc";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetSignatureElementDesc(SShaderBlock::ST_Input, Element, pDesc) );
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetOutputSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetOutputSignatureElementDesc";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetSignatureElementDesc(SShaderBlock::ST_Output, Element, pDesc) );
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SAnonymousShader::GetPatchConstantSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetPatchConstantSignatureElementDesc";
-
- ANONYMOUS_SHADER_INDEX_CHECK();
-
- VH( pShaderBlock->GetSignatureElementDesc(SShaderBlock::ST_PatchConstant, Element, pDesc) );
-
-lExit:
- return hr;
-}
-
-HRESULT SAnonymousShader::GetDesc(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc)
-{
- pDesc->Class = D3D_SVC_OBJECT;
-
- switch (pShaderBlock->GetShaderType())
- {
- case EOT_VertexShader:
- case EOT_VertexShader5:
- pDesc->TypeName = "vertexshader";
- pDesc->Type = D3D_SVT_VERTEXSHADER;
- break;
- case EOT_GeometryShader:
- case EOT_GeometryShader5:
- pDesc->TypeName = "geometryshader";
- pDesc->Type = D3D_SVT_GEOMETRYSHADER;
- break;
- case EOT_PixelShader:
- case EOT_PixelShader5:
- pDesc->TypeName = "pixelshader";
- pDesc->Type = D3D_SVT_PIXELSHADER;
- break;
- case EOT_HullShader5:
- pDesc->TypeName = "Hullshader";
- pDesc->Type = D3D_SVT_HULLSHADER;
- break;
- case EOT_DomainShader5:
- pDesc->TypeName = "Domainshader";
- pDesc->Type = D3D_SVT_DOMAINSHADER;
- break;
- case EOT_ComputeShader5:
- pDesc->TypeName = "Computeshader";
- pDesc->Type = D3D_SVT_COMPUTESHADER;
- break;
- }
-
- pDesc->Elements = 0;
- pDesc->Members = 0;
- pDesc->Rows = 0;
- pDesc->Columns = 0;
- pDesc->PackedSize = 0;
- pDesc->UnpackedSize = 0;
- pDesc->Stride = 0;
-
- return S_OK;
-}
-
-ID3DX11EffectType * SAnonymousShader::GetMemberTypeByIndex(_In_ uint32_t Index)
-{
- UNREFERENCED_PARAMETER(Index);
- DPF(0, "ID3DX11EffectType::GetMemberTypeByIndex: This interface does not refer to a structure");
- return &g_InvalidType;
-}
-
-ID3DX11EffectType * SAnonymousShader::GetMemberTypeByName(_In_z_ LPCSTR Name)
-{
- UNREFERENCED_PARAMETER(Name);
- DPF(0, "ID3DX11EffectType::GetMemberTypeByName: This interface does not refer to a structure");
- return &g_InvalidType;
-}
-
-ID3DX11EffectType * SAnonymousShader::GetMemberTypeBySemantic(_In_z_ LPCSTR Semantic)
-{
- UNREFERENCED_PARAMETER(Semantic);
- DPF(0, "ID3DX11EffectType::GetMemberTypeBySemantic: This interface does not refer to a structure");
- return &g_InvalidType;
-}
-
-LPCSTR SAnonymousShader::GetMemberName(_In_ uint32_t Index)
-{
- UNREFERENCED_PARAMETER(Index);
- DPF(0, "ID3DX11EffectType::GetMemberName: This interface does not refer to a structure");
- return nullptr;
-}
-
-LPCSTR SAnonymousShader::GetMemberSemantic(_In_ uint32_t Index)
-{
- UNREFERENCED_PARAMETER(Index);
- DPF(0, "ID3DX11EffectType::GetMemberSemantic: This interface does not refer to a structure");
- return nullptr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectConstantBuffer (SConstantBuffer implementation)
-//////////////////////////////////////////////////////////////////////////
-
-bool SConstantBuffer::IsValid()
-{
- return true;
-}
-
-ID3DX11EffectType * SConstantBuffer::GetType()
-{
- return (ID3DX11EffectType *) this;
-}
-
-HRESULT SConstantBuffer::GetDesc(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc)
-{
- pDesc->Annotations = AnnotationCount;
- pDesc->Flags = 0;
-
- pDesc->Name = pName;
- pDesc->Semantic = nullptr;
- pDesc->BufferOffset = 0;
-
- if (ExplicitBindPoint != static_cast<uint32_t>(- 1))
- {
- pDesc->ExplicitBindPoint = ExplicitBindPoint;
- pDesc->Flags |= D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT;
- }
- else
- {
- pDesc->ExplicitBindPoint = 0;
- }
-
- return S_OK;
-}
-
-ID3DX11EffectVariable * SConstantBuffer::GetAnnotationByIndex(_In_ uint32_t Index)
-{
- return GetAnnotationByIndexHelper("ID3DX11EffectVariable", Index, AnnotationCount, pAnnotations);
-}
-
-ID3DX11EffectVariable * SConstantBuffer::GetAnnotationByName(_In_z_ LPCSTR Name)
-{
- return GetAnnotationByNameHelper("ID3DX11EffectVariable", Name, AnnotationCount, pAnnotations);
-}
-
-ID3DX11EffectVariable * SConstantBuffer::GetMemberByIndex(_In_ uint32_t Index)
-{
- SGlobalVariable *pMember;
- UDataPointer dataPtr;
-
- if (IsEffectOptimized)
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberByIndex: Cannot get members; effect has been Optimize()'ed");
- return &g_InvalidScalarVariable;
- }
-
- if (!GetVariableByIndexHelper<SGlobalVariable>(Index, VariableCount, (SGlobalVariable*)pVariables,
- nullptr, &pMember, &dataPtr.pGeneric))
- {
- return &g_InvalidScalarVariable;
- }
-
- return (ID3DX11EffectVariable *) pMember;
-}
-
-ID3DX11EffectVariable * SConstantBuffer::GetMemberByName(_In_z_ LPCSTR Name)
-{
- SGlobalVariable *pMember;
- UDataPointer dataPtr;
- uint32_t index;
-
- if (IsEffectOptimized)
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberByName: Cannot get members; effect has been Optimize()'ed");
- return &g_InvalidScalarVariable;
- }
-
- if (!GetVariableByNameHelper<SGlobalVariable>(Name, VariableCount, (SGlobalVariable*)pVariables,
- nullptr, &pMember, &dataPtr.pGeneric, &index))
- {
- return &g_InvalidScalarVariable;
- }
-
- return (ID3DX11EffectVariable *) pMember;
-}
-
-ID3DX11EffectVariable * SConstantBuffer::GetMemberBySemantic(_In_z_ LPCSTR Semantic)
-{
- SGlobalVariable *pMember;
- UDataPointer dataPtr;
- uint32_t index;
-
- if (IsEffectOptimized)
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberBySemantic: Cannot get members; effect has been Optimize()'ed");
- return &g_InvalidScalarVariable;
- }
-
- if (!GetVariableBySemanticHelper<SGlobalVariable>(Semantic, VariableCount, (SGlobalVariable*)pVariables,
- nullptr, &pMember, &dataPtr.pGeneric, &index))
- {
- return &g_InvalidScalarVariable;
- }
-
- return (ID3DX11EffectVariable *) pMember;
-}
-
-ID3DX11EffectVariable * SConstantBuffer::GetElement(_In_ uint32_t Index)
-{
- UNREFERENCED_PARAMETER(Index);
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetElement";
- DPF(0, "%s: This interface does not refer to an array", pFuncName);
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectConstantBuffer * SConstantBuffer::GetParentConstantBuffer()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetParentConstantBuffer";
- DPF(0, "%s: Constant buffers do not have parent constant buffers", pFuncName);
- return &g_InvalidConstantBuffer;
-}
-
-ID3DX11EffectConstantBuffer * SConstantBuffer::AsConstantBuffer()
-{
- return (ID3DX11EffectConstantBuffer *) this;
-}
-
-HRESULT SConstantBuffer::GetDesc(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc)
-{
- pDesc->TypeName = IsTBuffer ? "tbuffer" : "cbuffer";
- pDesc->Class = D3D_SVC_OBJECT;
- pDesc->Type = IsTBuffer ? D3D_SVT_TBUFFER : D3D_SVT_CBUFFER;
-
- pDesc->Elements = 0;
- pDesc->Members = VariableCount;
- pDesc->Rows = 0;
- pDesc->Columns = 0;
-
- uint32_t i;
- pDesc->PackedSize = 0;
- for (i = 0; i < VariableCount; ++ i)
- {
- pDesc->PackedSize += pVariables[i].pType->PackedSize;
- }
-
- pDesc->UnpackedSize = Size;
- assert(pDesc->UnpackedSize >= pDesc->PackedSize);
-
- pDesc->Stride = AlignToPowerOf2(pDesc->UnpackedSize, SType::c_RegisterSize);
-
- return S_OK;
-}
-
-ID3DX11EffectType * SConstantBuffer::GetMemberTypeByIndex(_In_ uint32_t Index)
-{
- return GetTypeByIndexHelper(Index, VariableCount, pVariables, sizeof (SGlobalVariable));
-}
-
-ID3DX11EffectType * SConstantBuffer::GetMemberTypeByName(_In_z_ LPCSTR Name)
-{
- return GetTypeByNameHelper(Name, VariableCount, pVariables, sizeof (SGlobalVariable));
-}
-
-ID3DX11EffectType * SConstantBuffer::GetMemberTypeBySemantic(_In_z_ LPCSTR Semantic)
-{
- return GetTypeBySemanticHelper(Semantic, VariableCount, pVariables, sizeof (SGlobalVariable));
-}
-
-LPCSTR SConstantBuffer::GetMemberName(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectType::GetMemberName";
-
- if (IsEffectOptimized)
- {
- DPF(0, "%s: Cannot get member names; Effect has been Optimize()'ed", pFuncName);
- return nullptr;
- }
-
- if (Index >= VariableCount)
- {
- DPF(0, "%s: Invalid index (%u, total: %u)", pFuncName, Index, VariableCount);
- return nullptr;
- }
-
- return pVariables[Index].pName;
-}
-
-LPCSTR SConstantBuffer::GetMemberSemantic(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectType::GetMemberSemantic";
-
- if (IsEffectOptimized)
- {
- DPF(0, "%s: Cannot get member semantics; Effect has been Optimize()'ed", pFuncName);
- return nullptr;
- }
-
- if (Index >= VariableCount)
- {
- DPF(0, "%s: Invalid index (%u, total: %u)", pFuncName, Index, VariableCount);
- return nullptr;
- }
-
- return pVariables[Index].pSemantic;
-}
-
-_Use_decl_annotations_
-HRESULT SConstantBuffer::SetRawValue(const void *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectVariable::SetRawValue";
-
- VERIFYPARAMETER(pData);
-
- if ((Offset + Count < Offset) ||
- (Count + (uint8_t*)pData < (uint8_t*)pData) ||
- ((Offset + Count) > Size))
- {
- // overflow of some kind
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- if (IsUsedByExpression)
- {
- uint32_t i;
- for (i = 0; i < VariableCount; ++ i)
- {
- ((SGlobalVariable*)pVariables)[i].DirtyVariable();
- }
- }
- else
- {
- IsDirty = true;
- }
-
- memcpy(pBackingStore + Offset, pData, Count);
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-HRESULT SConstantBuffer::GetRawValue(void *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetRawValue";
-
- VERIFYPARAMETER(pData);
-
- if ((Offset + Count < Offset) ||
- (Count + (uint8_t*)pData < (uint8_t*)pData) ||
- ((Offset + Count) > Size))
- {
- // overflow of some kind
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- memcpy(pData, pBackingStore + Offset, Count);
-
-lExit:
- return hr;
-}
-
-bool SConstantBuffer::ClonedSingle() const
-{
- return IsSingle && ( pEffect->m_Flags & D3DX11_EFFECT_CLONE );
-}
-
-HRESULT SConstantBuffer::SetConstantBuffer(_In_ ID3D11Buffer *pConstantBuffer)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::SetConstantBuffer";
-
- if (IsTBuffer)
- {
- DPF(0, "%s: This is a texture buffer; use SetTextureBuffer instead", pFuncName);
- VH(D3DERR_INVALIDCALL);
- }
-
- // Replace all references to the old shader block with this one
- pEffect->ReplaceCBReference(this, pConstantBuffer);
-
- if( !IsUserManaged )
- {
- // Save original cbuffer in case we UndoSet
- assert( pMemberData[0].Type == MDT_Buffer );
- VB( pMemberData[0].Data.pD3DEffectsManagedConstantBuffer == nullptr );
- pMemberData[0].Data.pD3DEffectsManagedConstantBuffer = pD3DObject;
- pD3DObject = nullptr;
- IsUserManaged = true;
- IsNonUpdatable = true;
- }
-
- SAFE_ADDREF( pConstantBuffer );
- SAFE_RELEASE( pD3DObject );
- pD3DObject = pConstantBuffer;
-
-lExit:
- return hr;
-}
-
-HRESULT SConstantBuffer::GetConstantBuffer(_Outptr_ ID3D11Buffer **ppConstantBuffer)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::GetConstantBuffer";
-
- VERIFYPARAMETER(ppConstantBuffer);
-
- if (IsTBuffer)
- {
- DPF(0, "%s: This is a texture buffer; use GetTextureBuffer instead", pFuncName);
- VH(D3DERR_INVALIDCALL);
- }
-
- assert( pD3DObject );
- _Analysis_assume_( pD3DObject );
- *ppConstantBuffer = pD3DObject;
- SAFE_ADDREF(*ppConstantBuffer);
-
-lExit:
- return hr;
-}
-
-HRESULT SConstantBuffer::UndoSetConstantBuffer()
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::UndoSetConstantBuffer";
-
- if (IsTBuffer)
- {
- DPF(0, "%s: This is a texture buffer; use UndoSetTextureBuffer instead", pFuncName);
- VH(D3DERR_INVALIDCALL);
- }
-
- if( !IsUserManaged )
- {
- return S_FALSE;
- }
-
- // Replace all references to the old shader block with this one
- pEffect->ReplaceCBReference(this, pMemberData[0].Data.pD3DEffectsManagedConstantBuffer);
-
- // Revert to original cbuffer
- SAFE_RELEASE( pD3DObject );
- pD3DObject = pMemberData[0].Data.pD3DEffectsManagedConstantBuffer;
- pMemberData[0].Data.pD3DEffectsManagedConstantBuffer = nullptr;
- IsUserManaged = false;
- IsNonUpdatable = ClonedSingle();
-
-lExit:
- return hr;
-}
-
-HRESULT SConstantBuffer::SetTextureBuffer(_In_ ID3D11ShaderResourceView *pTextureBuffer)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::SetTextureBuffer";
-
- if (!IsTBuffer)
- {
- DPF(0, "%s: This is a constant buffer; use SetConstantBuffer instead", pFuncName);
- VH(D3DERR_INVALIDCALL);
- }
-
- if( !IsUserManaged )
- {
- // Save original cbuffer and tbuffer in case we UndoSet
- assert( pMemberData[0].Type == MDT_Buffer );
- VB( pMemberData[0].Data.pD3DEffectsManagedConstantBuffer == nullptr );
- pMemberData[0].Data.pD3DEffectsManagedConstantBuffer = pD3DObject;
- pD3DObject = nullptr;
- assert( pMemberData[1].Type == MDT_ShaderResourceView );
- VB( pMemberData[1].Data.pD3DEffectsManagedTextureBuffer == nullptr );
- pMemberData[1].Data.pD3DEffectsManagedTextureBuffer = TBuffer.pShaderResource;
- TBuffer.pShaderResource = nullptr;
- IsUserManaged = true;
- IsNonUpdatable = true;
- }
-
- SAFE_ADDREF( pTextureBuffer );
- SAFE_RELEASE(pD3DObject); // won't be needing this anymore...
- SAFE_RELEASE( TBuffer.pShaderResource );
- TBuffer.pShaderResource = pTextureBuffer;
-
-lExit:
- return hr;
-}
-
-HRESULT SConstantBuffer::GetTextureBuffer(_Outptr_ ID3D11ShaderResourceView **ppTextureBuffer)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::GetTextureBuffer";
-
- VERIFYPARAMETER(ppTextureBuffer);
-
- if (!IsTBuffer)
- {
- DPF(0, "%s: This is a constant buffer; use GetConstantBuffer instead", pFuncName);
- VH(D3DERR_INVALIDCALL);
- }
-
- assert( TBuffer.pShaderResource );
- _Analysis_assume_( TBuffer.pShaderResource );
- *ppTextureBuffer = TBuffer.pShaderResource;
- SAFE_ADDREF(*ppTextureBuffer);
-
-lExit:
- return hr;
-}
-
-HRESULT SConstantBuffer::UndoSetTextureBuffer()
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectConstantBuffer::UndoSetTextureBuffer";
-
- if (!IsTBuffer)
- {
- DPF(0, "%s: This is a texture buffer; use UndoSetConstantBuffer instead", pFuncName);
- VH(D3DERR_INVALIDCALL);
- }
-
- if( !IsUserManaged )
- {
- return S_FALSE;
- }
-
- // Revert to original cbuffer
- SAFE_RELEASE( pD3DObject );
- pD3DObject = pMemberData[0].Data.pD3DEffectsManagedConstantBuffer;
- pMemberData[0].Data.pD3DEffectsManagedConstantBuffer = nullptr;
- SAFE_RELEASE( TBuffer.pShaderResource );
- TBuffer.pShaderResource = pMemberData[1].Data.pD3DEffectsManagedTextureBuffer;
- pMemberData[1].Data.pD3DEffectsManagedTextureBuffer = nullptr;
- IsUserManaged = false;
- IsNonUpdatable = ClonedSingle();
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectPass (CEffectPass implementation)
-//////////////////////////////////////////////////////////////////////////
-
-bool SPassBlock::IsValid()
-{
- if( HasDependencies )
- return pEffect->ValidatePassBlock( this );
- return InitiallyValid;
-}
-
-HRESULT SPassBlock::GetDesc(_Out_ D3DX11_PASS_DESC *pDesc)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectPass::GetDesc";
-
- VERIFYPARAMETER(pDesc);
-
- ZeroMemory(pDesc, sizeof(*pDesc));
-
- pDesc->Name = pName;
- pDesc->Annotations = AnnotationCount;
-
- SAssignment *pAssignment;
- SAssignment *pLastAssn;
-
- pEffect->IncrementTimer();
-
- pAssignment = pAssignments;
- pLastAssn = pAssignments + AssignmentCount;
-
- for(; pAssignment < pLastAssn; pAssignment++)
- {
- pEffect->EvaluateAssignment(pAssignment);
- }
-
- if( BackingStore.pVertexShaderBlock && BackingStore.pVertexShaderBlock->pInputSignatureBlob )
- {
- // pInputSignatureBlob can be null if we're setting a nullptr VS "SetVertexShader( nullptr )"
- pDesc->pIAInputSignature = (uint8_t*)BackingStore.pVertexShaderBlock->pInputSignatureBlob->GetBufferPointer();
- pDesc->IAInputSignatureSize = BackingStore.pVertexShaderBlock->pInputSignatureBlob->GetBufferSize();
- }
-
- pDesc->StencilRef = BackingStore.StencilRef;
- pDesc->SampleMask = BackingStore.SampleMask;
- pDesc->BlendFactor[0] = BackingStore.BlendFactor[0];
- pDesc->BlendFactor[1] = BackingStore.BlendFactor[1];
- pDesc->BlendFactor[2] = BackingStore.BlendFactor[2];
- pDesc->BlendFactor[3] = BackingStore.BlendFactor[3];
-
-lExit:
- return hr;
-}
-
-extern SShaderBlock g_NullVS;
-extern SShaderBlock g_NullGS;
-extern SShaderBlock g_NullPS;
-extern SShaderBlock g_NullHS;
-extern SShaderBlock g_NullDS;
-extern SShaderBlock g_NullCS;
-
-SAnonymousShader g_AnonymousNullVS(&g_NullVS);
-SAnonymousShader g_AnonymousNullGS(&g_NullGS);
-SAnonymousShader g_AnonymousNullPS(&g_NullPS);
-SAnonymousShader g_AnonymousNullHS(&g_NullHS);
-SAnonymousShader g_AnonymousNullDS(&g_NullDS);
-SAnonymousShader g_AnonymousNullCS(&g_NullCS);
-
-template<EObjectType EShaderType>
-HRESULT SPassBlock::GetShaderDescHelper(D3DX11_PASS_SHADER_DESC *pDesc)
-{
- HRESULT hr = S_OK;
- uint32_t i;
- LPCSTR pFuncName = nullptr;
- SShaderBlock *pShaderBlock = nullptr;
-
- ApplyPassAssignments();
-
-#ifdef _PREFAST_
-#pragma prefast(push)
-#pragma prefast(disable:__WARNING_UNUSED_POINTER_ASSIGNMENT, "pFuncName used in DPF")
-#endif
- switch (EShaderType)
- {
- case EOT_VertexShader:
- case EOT_VertexShader5:
- pFuncName = "ID3DX11EffectPass::GetVertexShaderDesc";
- pShaderBlock = BackingStore.pVertexShaderBlock;
- break;
- case EOT_PixelShader:
- case EOT_PixelShader5:
- pFuncName = "ID3DX11EffectPass::GetPixelShaderDesc";
- pShaderBlock = BackingStore.pPixelShaderBlock;
- break;
- case EOT_GeometryShader:
- case EOT_GeometryShader5:
- pFuncName = "ID3DX11EffectPass::GetGeometryShaderDesc";
- pShaderBlock = BackingStore.pGeometryShaderBlock;
- break;
- case EOT_HullShader5:
- pFuncName = "ID3DX11EffectPass::GetHullShaderDesc";
- pShaderBlock = BackingStore.pHullShaderBlock;
- break;
- case EOT_DomainShader5:
- pFuncName = "ID3DX11EffectPass::GetDomainShaderDesc";
- pShaderBlock = BackingStore.pDomainShaderBlock;
- break;
- case EOT_ComputeShader5:
- pFuncName = "ID3DX11EffectPass::GetComputeShaderDesc";
- pShaderBlock = BackingStore.pComputeShaderBlock;
- break;
-#ifdef _PREFAST_
-#pragma prefast(pop)
-#endif
- default:
- assert(0);
- }
-
- VERIFYPARAMETER(pDesc);
-
- // in case of error (or in case the assignment doesn't exist), return something reasonable
- pDesc->pShaderVariable = &g_InvalidShaderVariable;
- pDesc->ShaderIndex = 0;
-
- if (nullptr != pShaderBlock)
- {
- uint32_t elements, varCount, anonymousShaderCount;
- SGlobalVariable *pVariables;
- SAnonymousShader *pAnonymousShaders;
-
- if (pShaderBlock == &g_NullVS)
- {
- pDesc->pShaderVariable = &g_AnonymousNullVS;
- pDesc->ShaderIndex = 0;
- // we're done
- goto lExit;
- }
- else if (pShaderBlock == &g_NullGS)
- {
- pDesc->pShaderVariable = &g_AnonymousNullGS;
- pDesc->ShaderIndex = 0;
- // we're done
- goto lExit;
- }
- else if (pShaderBlock == &g_NullPS)
- {
- pDesc->pShaderVariable = &g_AnonymousNullPS;
- pDesc->ShaderIndex = 0;
- // we're done
- goto lExit;
- }
- else if (pShaderBlock == &g_NullHS)
- {
- pDesc->pShaderVariable = &g_AnonymousNullHS;
- pDesc->ShaderIndex = 0;
- // we're done
- goto lExit;
- }
- else if (pShaderBlock == &g_NullDS)
- {
- pDesc->pShaderVariable = &g_AnonymousNullDS;
- pDesc->ShaderIndex = 0;
- // we're done
- goto lExit;
- }
- else if (pShaderBlock == &g_NullCS)
- {
- pDesc->pShaderVariable = &g_AnonymousNullCS;
- pDesc->ShaderIndex = 0;
- // we're done
- goto lExit;
- }
- else
- {
- VB( pEffect->IsRuntimeData(pShaderBlock) );
- varCount = pEffect->m_VariableCount;
- pVariables = pEffect->m_pVariables;
- anonymousShaderCount = pEffect->m_AnonymousShaderCount;
- pAnonymousShaders = pEffect->m_pAnonymousShaders;
- }
-
- for (i = 0; i < varCount; ++ i)
- {
- elements = std::max<uint32_t>(1, pVariables[i].pType->Elements);
- // make sure the variable type matches, and don't forget about GeometryShaderSO's
- if (pVariables[i].pType->IsShader())
- {
- if (pShaderBlock >= pVariables[i].Data.pShader && pShaderBlock < pVariables[i].Data.pShader + elements)
- {
- pDesc->pShaderVariable = (ID3DX11EffectShaderVariable *)(pVariables + i);
- pDesc->ShaderIndex = (uint32_t)(UINT_PTR)(pShaderBlock - pVariables[i].Data.pShader);
- // we're done
- goto lExit;
- }
- }
- }
-
- for (i = 0; i < anonymousShaderCount; ++ i)
- {
- if (pShaderBlock == pAnonymousShaders[i].pShaderBlock)
- {
- VB(EShaderType == pAnonymousShaders[i].pShaderBlock->GetShaderType())
- pDesc->pShaderVariable = (pAnonymousShaders + i);
- pDesc->ShaderIndex = 0;
- // we're done
- goto lExit;
- }
- }
-
- DPF(0, "%s: Internal error; shader not found", pFuncName);
- VH( E_FAIL );
- }
-
-lExit:
- return hr;
-}
-
-HRESULT SPassBlock::GetVertexShaderDesc(_Out_ D3DX11_PASS_SHADER_DESC *pDesc)
-{
- return GetShaderDescHelper<EOT_VertexShader>(pDesc);
-}
-
-HRESULT SPassBlock::GetPixelShaderDesc(_Out_ D3DX11_PASS_SHADER_DESC *pDesc)
-{
- return GetShaderDescHelper<EOT_PixelShader>(pDesc);
-}
-
-HRESULT SPassBlock::GetGeometryShaderDesc(_Out_ D3DX11_PASS_SHADER_DESC *pDesc)
-{
- return GetShaderDescHelper<EOT_GeometryShader>(pDesc);
-}
-
-HRESULT SPassBlock::GetHullShaderDesc(_Out_ D3DX11_PASS_SHADER_DESC *pDesc)
-{
- return GetShaderDescHelper<EOT_HullShader5>(pDesc);
-}
-
-HRESULT SPassBlock::GetDomainShaderDesc(_Out_ D3DX11_PASS_SHADER_DESC *pDesc)
-{
- return GetShaderDescHelper<EOT_DomainShader5>(pDesc);
-}
-
-HRESULT SPassBlock::GetComputeShaderDesc(_Out_ D3DX11_PASS_SHADER_DESC *pDesc)
-{
- return GetShaderDescHelper<EOT_ComputeShader5>(pDesc);
-}
-
-ID3DX11EffectVariable * SPassBlock::GetAnnotationByIndex(_In_ uint32_t Index)
-{
- return GetAnnotationByIndexHelper("ID3DX11EffectPass", Index, AnnotationCount, pAnnotations);
-}
-
-ID3DX11EffectVariable * SPassBlock::GetAnnotationByName(_In_z_ LPCSTR Name)
-{
- return GetAnnotationByNameHelper("ID3DX11EffectPass", Name, AnnotationCount, pAnnotations);
-}
-
-HRESULT SPassBlock::Apply(_In_ uint32_t Flags, _In_ ID3D11DeviceContext* pContext)
-
-{
- UNREFERENCED_PARAMETER(Flags);
- HRESULT hr = S_OK;
-
- // Flags are unused, so should be 0
-
-
- assert( pEffect->m_pContext == nullptr );
- pEffect->m_pContext = pContext;
- pEffect->ApplyPassBlock(this);
- pEffect->m_pContext = nullptr;
-
- return hr;
-}
-
-HRESULT SPassBlock::ComputeStateBlockMask(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask)
-{
- HRESULT hr = S_OK;
-
- // flags indicating whether the following shader types were caught by assignment checks or not
- bool bVS = false, bGS = false, bPS = false, bHS = false, bDS = false, bCS = false;
-
- for (size_t i = 0; i < AssignmentCount; ++ i)
- {
- bool bShader = false;
-
- switch (pAssignments[i].LhsType)
- {
- case ELHS_VertexShaderBlock:
- bVS = true;
- bShader = true;
- break;
- case ELHS_GeometryShaderBlock:
- bGS = true;
- bShader = true;
- break;
- case ELHS_PixelShaderBlock:
- bPS = true;
- bShader = true;
- break;
- case ELHS_HullShaderBlock:
- bHS = true;
- bShader = true;
- break;
- case ELHS_DomainShaderBlock:
- bDS = true;
- bShader = true;
- break;
- case ELHS_ComputeShaderBlock:
- bCS = true;
- bShader = true;
- break;
-
- case ELHS_RasterizerBlock:
- pStateBlockMask->RSRasterizerState = 1;
- break;
- case ELHS_BlendBlock:
- pStateBlockMask->OMBlendState = 1;
- break;
- case ELHS_DepthStencilBlock:
- pStateBlockMask->OMDepthStencilState = 1;
- break;
-
- default:
- // ignore this assignment (must be a scalar/vector assignment associated with a state object)
- break;
- }
-
- if (bShader)
- {
- for (size_t j = 0; j < pAssignments[i].MaxElements; ++ j)
- {
- // compute state block mask for the union of ALL shaders
- VH( pAssignments[i].Source.pShader[j].ComputeStateBlockMask(pStateBlockMask) );
- }
- }
- }
-
- // go over the state block objects in case there was no corresponding assignment
- if (nullptr != BackingStore.pRasterizerBlock)
- {
- pStateBlockMask->RSRasterizerState = 1;
- }
- if (nullptr != BackingStore.pBlendBlock)
- {
- pStateBlockMask->OMBlendState = 1;
- }
- if (nullptr != BackingStore.pDepthStencilBlock)
- {
- pStateBlockMask->OMDepthStencilState = 1;
- }
-
- // go over the shaders only if an assignment didn't already catch them
- if (false == bVS && nullptr != BackingStore.pVertexShaderBlock)
- {
- VH( BackingStore.pVertexShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
- }
- if (false == bGS && nullptr != BackingStore.pGeometryShaderBlock)
- {
- VH( BackingStore.pGeometryShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
- }
- if (false == bPS && nullptr != BackingStore.pPixelShaderBlock)
- {
- VH( BackingStore.pPixelShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
- }
- if (false == bHS && nullptr != BackingStore.pHullShaderBlock)
- {
- VH( BackingStore.pHullShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
- }
- if (false == bDS && nullptr != BackingStore.pDomainShaderBlock)
- {
- VH( BackingStore.pDomainShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
- }
- if (false == bCS && nullptr != BackingStore.pComputeShaderBlock)
- {
- VH( BackingStore.pComputeShaderBlock->ComputeStateBlockMask(pStateBlockMask) );
- }
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectTechnique (STechnique implementation)
-//////////////////////////////////////////////////////////////////////////
-
-bool STechnique::IsValid()
-{
- if( HasDependencies )
- {
- for( size_t i = 0; i < PassCount; i++ )
- {
- if( !((SPassBlock*)pPasses)[i].IsValid() )
- return false;
- }
- return true;
- }
- return InitiallyValid;
-}
-
-HRESULT STechnique::GetDesc(_Out_ D3DX11_TECHNIQUE_DESC *pDesc)
-{
- HRESULT hr = S_OK;
-
- static LPCSTR pFuncName = "ID3DX11EffectTechnique::GetDesc";
-
- VERIFYPARAMETER(pDesc);
-
- pDesc->Name = pName;
- pDesc->Annotations = AnnotationCount;
- pDesc->Passes = PassCount;
-
-lExit:
- return hr;
-}
-
-ID3DX11EffectVariable * STechnique::GetAnnotationByIndex(_In_ uint32_t Index)
-{
- return GetAnnotationByIndexHelper("ID3DX11EffectTechnique", Index, AnnotationCount, pAnnotations);
-}
-
-ID3DX11EffectVariable * STechnique::GetAnnotationByName(_In_z_ LPCSTR Name)
-{
- return GetAnnotationByNameHelper("ID3DX11EffectTechnique", Name, AnnotationCount, pAnnotations);
-}
-
-ID3DX11EffectPass * STechnique::GetPassByIndex(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectTechnique::GetPassByIndex";
-
- if (Index >= PassCount)
- {
- DPF(0, "%s: Invalid pass index (%u, total: %u)", pFuncName, Index, PassCount);
- return &g_InvalidPass;
- }
-
- return (ID3DX11EffectPass *)(pPasses + Index);
-}
-
-ID3DX11EffectPass * STechnique::GetPassByName(_In_z_ LPCSTR Name)
-{
- static LPCSTR pFuncName = "ID3DX11EffectTechnique::GetPassByName";
-
- uint32_t i;
-
- for (i = 0; i < PassCount; ++ i)
- {
- if (nullptr != pPasses[i].pName &&
- strcmp(pPasses[i].pName, Name) == 0)
- {
- break;
- }
- }
-
- if (i == PassCount)
- {
- DPF(0, "%s: Pass [%s] not found", pFuncName, Name);
- return &g_InvalidPass;
- }
-
- return (ID3DX11EffectPass *)(pPasses + i);
-}
-
-HRESULT STechnique::ComputeStateBlockMask(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask)
-{
- HRESULT hr = S_OK;
- uint32_t i;
-
- _Analysis_assume_( PassCount == 0 || pPasses != 0 );
- for (i = 0; i < PassCount; ++ i)
- {
- VH( ((SPassBlock*)pPasses)[i].ComputeStateBlockMask(pStateBlockMask) );
- }
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectGroup (SGroup implementation)
-//////////////////////////////////////////////////////////////////////////
-
-bool SGroup::IsValid()
-{
- if( HasDependencies )
- {
- for( size_t i = 0; i < TechniqueCount; i++ )
- {
- if( !((STechnique*)pTechniques)[i].IsValid() )
- return false;
- }
- return true;
- }
- return InitiallyValid;
-}
-
-HRESULT SGroup::GetDesc(_Out_ D3DX11_GROUP_DESC *pDesc)
-{
- HRESULT hr = S_OK;
-
- static LPCSTR pFuncName = "ID3DX11EffectGroup::GetDesc";
-
- VERIFYPARAMETER(pDesc);
-
- pDesc->Name = pName;
- pDesc->Annotations = AnnotationCount;
- pDesc->Techniques = TechniqueCount;
-
-lExit:
- return hr;
-}
-
-ID3DX11EffectVariable * SGroup::GetAnnotationByIndex(_In_ uint32_t Index)
-{
- return GetAnnotationByIndexHelper("ID3DX11EffectGroup", Index, AnnotationCount, pAnnotations);
-}
-
-ID3DX11EffectVariable * SGroup::GetAnnotationByName(_In_z_ LPCSTR Name)
-{
- return GetAnnotationByNameHelper("ID3DX11EffectGroup", Name, AnnotationCount, pAnnotations);
-}
-
-ID3DX11EffectTechnique * SGroup::GetTechniqueByIndex(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectGroup::GetTechniqueByIndex";
-
- if (Index >= TechniqueCount)
- {
- DPF(0, "%s: Invalid pass index (%u, total: %u)", pFuncName, Index, TechniqueCount);
- return &g_InvalidTechnique;
- }
-
- return (ID3DX11EffectTechnique *)(pTechniques + Index);
-}
-
-ID3DX11EffectTechnique * SGroup::GetTechniqueByName(_In_z_ LPCSTR Name)
-{
- static LPCSTR pFuncName = "ID3DX11EffectGroup::GetTechniqueByName";
-
- uint32_t i;
-
- for (i = 0; i < TechniqueCount; ++ i)
- {
- if (nullptr != pTechniques[i].pName &&
- strcmp(pTechniques[i].pName, Name) == 0)
- {
- break;
- }
- }
-
- if (i == TechniqueCount)
- {
- DPF(0, "%s: Technique [%s] not found", pFuncName, Name);
- return &g_InvalidTechnique;
- }
-
- return (ID3DX11EffectTechnique *)(pTechniques + i);
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11Effect Public Reflection APIs (CEffect)
-//////////////////////////////////////////////////////////////////////////
-
-HRESULT CEffect::GetDevice(_Outptr_ ID3D11Device **ppDevice)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11Effect::GetDevice";
- VERIFYPARAMETER(ppDevice);
-
- m_pDevice->AddRef();
- *ppDevice = m_pDevice;
-
-lExit:
- return hr;
-}
-
-HRESULT CEffect::GetDesc(_Out_ D3DX11_EFFECT_DESC *pDesc)
-{
- HRESULT hr = S_OK;
-
- static LPCSTR pFuncName = "ID3DX11Effect::GetDesc";
-
- VERIFYPARAMETER(pDesc);
-
- pDesc->ConstantBuffers = m_CBCount;
- pDesc->GlobalVariables = m_VariableCount;
- pDesc->Techniques = m_TechniqueCount;
- pDesc->Groups = m_GroupCount;
- pDesc->InterfaceVariables = m_InterfaceCount;
-
-lExit:
- return hr;
-}
-
-ID3DX11EffectConstantBuffer * CEffect::GetConstantBufferByIndex(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetConstantBufferByIndex";
-
- if (Index < m_CBCount)
- {
- return m_pCBs + Index;
- }
-
- DPF(0, "%s: Invalid constant buffer index", pFuncName);
- return &g_InvalidConstantBuffer;
-}
-
-ID3DX11EffectConstantBuffer * CEffect::GetConstantBufferByName(_In_z_ LPCSTR Name)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetConstantBufferByName";
-
- if (IsOptimized())
- {
- DPF(0, "%s: Cannot get constant buffer interfaces by name since the effect has been Optimize()'ed", pFuncName);
- return &g_InvalidConstantBuffer;
- }
-
- if (nullptr == Name)
- {
- DPF(0, "%s: Parameter Name was nullptr.", pFuncName);
- return &g_InvalidConstantBuffer;
- }
-
- for (uint32_t i = 0; i < m_CBCount; ++ i)
- {
- if (strcmp(m_pCBs[i].pName, Name) == 0)
- {
- return m_pCBs + i;
- }
- }
-
- DPF(0, "%s: Constant Buffer [%s] not found", pFuncName, Name);
- return &g_InvalidConstantBuffer;
-}
-
-ID3DX11EffectVariable * CEffect::GetVariableByIndex(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetVariableByIndex";
-
- if (Index < m_VariableCount)
- {
- return m_pVariables + Index;
- }
-
- DPF(0, "%s: Invalid variable index", pFuncName);
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectVariable * CEffect::GetVariableByName(_In_z_ LPCSTR Name)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetVariableByName";
-
- if (IsOptimized())
- {
- DPF(0, "%s: Cannot get variable interfaces by name since the effect has been Optimize()'ed", pFuncName);
- return &g_InvalidScalarVariable;
- }
-
- if (nullptr == Name)
- {
- DPF(0, "%s: Parameter Name was nullptr.", pFuncName);
- return &g_InvalidScalarVariable;
- }
-
- for (uint32_t i = 0; i < m_VariableCount; ++ i)
- {
- if (strcmp(m_pVariables[i].pName, Name) == 0)
- {
- return m_pVariables + i;
- }
- }
-
- DPF(0, "%s: Variable [%s] not found", pFuncName, Name);
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectVariable * CEffect::GetVariableBySemantic(_In_z_ LPCSTR Semantic)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetVariableBySemantic";
-
- if (IsOptimized())
- {
- DPF(0, "%s: Cannot get variable interfaces by semantic since the effect has been Optimize()'ed", pFuncName);
- return &g_InvalidScalarVariable;
- }
-
- if (nullptr == Semantic)
- {
- DPF(0, "%s: Parameter Semantic was nullptr.", pFuncName);
- return &g_InvalidScalarVariable;
- }
-
- uint32_t i;
-
- for (i = 0; i < m_VariableCount; ++ i)
- {
- if (nullptr != m_pVariables[i].pSemantic &&
- _stricmp(m_pVariables[i].pSemantic, Semantic) == 0)
- {
- return (ID3DX11EffectVariable *)(m_pVariables + i);
- }
- }
-
- DPF(0, "%s: Variable with semantic [%s] not found", pFuncName, Semantic);
- return &g_InvalidScalarVariable;
-}
-
-ID3DX11EffectTechnique * CEffect::GetTechniqueByIndex(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetTechniqueByIndex";
-
- if( Index < m_TechniqueCount )
- {
- for( size_t i=0; i < m_GroupCount; i++ )
- {
- if( Index < m_pGroups[i].TechniqueCount )
- {
- return (ID3DX11EffectTechnique *)(m_pGroups[i].pTechniques + Index);
- }
- Index -= m_pGroups[i].TechniqueCount;
- }
- assert( false );
- }
- DPF(0, "%s: Invalid technique index (%u)", pFuncName, Index);
- return &g_InvalidTechnique;
-}
-
-ID3DX11EffectTechnique * CEffect::GetTechniqueByName(_In_z_ LPCSTR Name)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetTechniqueByName";
- const size_t MAX_GROUP_TECHNIQUE_SIZE = 256;
- char NameCopy[MAX_GROUP_TECHNIQUE_SIZE];
-
- if (IsOptimized())
- {
- DPF(0, "ID3DX11Effect::GetTechniqueByName: Cannot get technique interfaces by name since the effect has been Optimize()'ed");
- return &g_InvalidTechnique;
- }
-
- if (nullptr == Name)
- {
- DPF(0, "%s: Parameter Name was nullptr.", pFuncName);
- return &g_InvalidTechnique;
- }
-
- if( FAILED( strcpy_s( NameCopy, MAX_GROUP_TECHNIQUE_SIZE, Name ) ) )
- {
- DPF( 0, "Group|Technique name has a length greater than %zu.", MAX_GROUP_TECHNIQUE_SIZE );
- return &g_InvalidTechnique;
- }
-
- char* pDelimiter = strchr( NameCopy, '|' );
- if( pDelimiter == nullptr )
- {
- if ( m_pNullGroup == nullptr )
- {
- DPF( 0, "The effect contains no default group." );
- return &g_InvalidTechnique;
- }
-
- return m_pNullGroup->GetTechniqueByName( Name );
- }
-
- // separate group name and technique name
- *pDelimiter = 0;
-
- return GetGroupByName( NameCopy )->GetTechniqueByName( pDelimiter + 1 );
-}
-
-ID3D11ClassLinkage * CEffect::GetClassLinkage()
-{
- SAFE_ADDREF( m_pClassLinkage );
- return m_pClassLinkage;
-}
-
-ID3DX11EffectGroup * CEffect::GetGroupByIndex(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetGroupByIndex";
-
- if( Index < m_GroupCount )
- {
- return (ID3DX11EffectGroup *)(m_pGroups + Index);
- }
- DPF(0, "%s: Invalid group index (%u)", pFuncName, Index);
- return &g_InvalidGroup;
-}
-
-ID3DX11EffectGroup * CEffect::GetGroupByName(_In_z_ LPCSTR Name)
-{
- static LPCSTR pFuncName = "ID3DX11Effect::GetGroupByName";
-
- if (IsOptimized())
- {
- DPF(0, "ID3DX11Effect::GetGroupByName: Cannot get group interfaces by name since the effect has been Optimize()'ed");
- return &g_InvalidGroup;
- }
-
- if (nullptr == Name || Name[0] == 0 )
- {
- return m_pNullGroup ? (ID3DX11EffectGroup *)m_pNullGroup : &g_InvalidGroup;
- }
-
- uint32_t i = 0;
- for (; i < m_GroupCount; ++ i)
- {
- if (nullptr != m_pGroups[i].pName &&
- strcmp(m_pGroups[i].pName, Name) == 0)
- {
- break;
- }
- }
-
- if (i == m_GroupCount)
- {
- DPF(0, "%s: Group [%s] not found", pFuncName, Name);
- return &g_InvalidGroup;
- }
-
- return (ID3DX11EffectGroup *)(m_pGroups + i);
-}
-
-}
diff --git a/lib/win32/Effects11/EffectRuntime.cpp b/lib/win32/Effects11/EffectRuntime.cpp
deleted file mode 100644
index 90a4194794..0000000000
--- a/lib/win32/Effects11/EffectRuntime.cpp
+++ /dev/null
@@ -1,718 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectRuntime.cpp
-//
-// Direct3D 11 Effect runtime routines (performance critical)
-// These functions are expected to be called at high frequency
-// (when applying a pass).
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#include "pchfx.h"
-
-namespace D3DX11Effects
-{
- // D3D11_KEEP_UNORDERED_ACCESS_VIEWS == (uint32_t)-1
- uint32_t g_pNegativeOnes[8] = { D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS,
- D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS,
- D3D11_KEEP_UNORDERED_ACCESS_VIEWS, D3D11_KEEP_UNORDERED_ACCESS_VIEWS };
-
-bool SBaseBlock::ApplyAssignments(CEffect *pEffect)
-{
- SAssignment *pAssignment = pAssignments;
- SAssignment *pLastAssn = pAssignments + AssignmentCount;
- bool bRecreate = false;
-
- for(; pAssignment < pLastAssn; pAssignment++)
- {
- bRecreate |= pEffect->EvaluateAssignment(pAssignment);
- }
-
- return bRecreate;
-}
-
-void SPassBlock::ApplyPassAssignments()
-{
- SAssignment *pAssignment = pAssignments;
- SAssignment *pLastAssn = pAssignments + AssignmentCount;
-
- pEffect->IncrementTimer();
-
- for(; pAssignment < pLastAssn; pAssignment++)
- {
- pEffect->EvaluateAssignment(pAssignment);
- }
-}
-
-// Returns true if the shader uses global interfaces (since these interfaces can be updated through SetClassInstance)
-bool SPassBlock::CheckShaderDependencies( _In_ const SShaderBlock* pBlock )
-{
- if( pBlock->InterfaceDepCount > 0 )
- {
- assert( pBlock->InterfaceDepCount == 1 );
- for( size_t i=0; i < pBlock->pInterfaceDeps[0].Count; i++ )
- {
- SInterface* pInterfaceDep = pBlock->pInterfaceDeps[0].ppFXPointers[i];
- if( pInterfaceDep > pEffect->m_pInterfaces && pInterfaceDep < (pEffect->m_pInterfaces + pEffect->m_InterfaceCount) )
- {
- // This is a global interface pointer (as opposed to an SInterface created in a BindInterface call
- return true;
- }
- }
- }
- return false;
-}
-
-// Returns true if the pass (and sets HasDependencies) if the pass sets objects whose backing stores can be updated
-#pragma warning(push)
-#pragma warning(disable: 4616 6282)
-bool SPassBlock::CheckDependencies()
-{
- if( HasDependencies )
- return true;
-
- for( size_t i=0; i < AssignmentCount; i++ )
- {
- if( pAssignments[i].DependencyCount > 0 )
- return HasDependencies = true;
- }
- if( BackingStore.pBlendBlock && BackingStore.pBlendBlock->AssignmentCount > 0 )
- {
- for( size_t i=0; i < BackingStore.pBlendBlock->AssignmentCount; i++ )
- {
- if( BackingStore.pBlendBlock->pAssignments[i].DependencyCount > 0 )
- return HasDependencies = true;
- }
- }
- if( BackingStore.pDepthStencilBlock && BackingStore.pDepthStencilBlock->AssignmentCount > 0 )
- {
- for( size_t i=0; i < BackingStore.pDepthStencilBlock->AssignmentCount; i++ )
- {
- if( BackingStore.pDepthStencilBlock->pAssignments[i].DependencyCount > 0 )
- return HasDependencies = true;
- }
- }
- if( BackingStore.pRasterizerBlock && BackingStore.pRasterizerBlock->AssignmentCount > 0 )
- {
- for( size_t i=0; i < BackingStore.pRasterizerBlock->AssignmentCount; i++ )
- {
- if( BackingStore.pRasterizerBlock->pAssignments[i].DependencyCount > 0 )
- return HasDependencies = true;
- }
- }
- if( BackingStore.pVertexShaderBlock && CheckShaderDependencies( BackingStore.pVertexShaderBlock ) )
- {
- return HasDependencies = true;
- }
- if( BackingStore.pGeometryShaderBlock && CheckShaderDependencies( BackingStore.pGeometryShaderBlock ) )
- {
- return HasDependencies = true;
- }
- if( BackingStore.pPixelShaderBlock && CheckShaderDependencies( BackingStore.pPixelShaderBlock ) )
- {
- return HasDependencies = true;
- }
- if( BackingStore.pHullShaderBlock && CheckShaderDependencies( BackingStore.pHullShaderBlock ) )
- {
- return HasDependencies = true;
- }
- if( BackingStore.pDomainShaderBlock && CheckShaderDependencies( BackingStore.pDomainShaderBlock ) )
- {
- return HasDependencies = true;
- }
- if( BackingStore.pComputeShaderBlock && CheckShaderDependencies( BackingStore.pComputeShaderBlock ) )
- {
- return HasDependencies = true;
- }
-
- return HasDependencies;
-}
-#pragma warning(pop)
-
-// Update constant buffer contents if necessary
-inline void CheckAndUpdateCB_FX(ID3D11DeviceContext *pContext, SConstantBuffer *pCB)
-{
- if (pCB->IsDirty && !pCB->IsNonUpdatable)
- {
- // CB out of date; rebuild it
- pContext->UpdateSubresource(pCB->pD3DObject, 0, nullptr, pCB->pBackingStore, pCB->Size, pCB->Size);
- pCB->IsDirty = false;
- }
-}
-
-
-//--------------------------------------------------------------------------------------
-//--------------------------------------------------------------------------------------
-
-// Set the shader and dependent state (SRVs, samplers, UAVs, interfaces)
-void CEffect::ApplyShaderBlock(_In_ SShaderBlock *pBlock)
-{
- SD3DShaderVTable *pVT = pBlock->pVT;
-
- // Apply constant buffers first (tbuffers are done later)
- SShaderCBDependency *pCBDep = pBlock->pCBDeps;
- SShaderCBDependency *pLastCBDep = pBlock->pCBDeps + pBlock->CBDepCount;
-
- for (; pCBDep<pLastCBDep; pCBDep++)
- {
- assert(pCBDep->ppFXPointers);
-
- for (size_t i = 0; i < pCBDep->Count; ++ i)
- {
- CheckAndUpdateCB_FX(m_pContext, (SConstantBuffer*)pCBDep->ppFXPointers[i]);
- }
-
- (m_pContext->*(pVT->pSetConstantBuffers))(pCBDep->StartIndex, pCBDep->Count, pCBDep->ppD3DObjects);
- }
-
- // Next, apply samplers
- SShaderSamplerDependency *pSampDep = pBlock->pSampDeps;
- SShaderSamplerDependency *pLastSampDep = pBlock->pSampDeps + pBlock->SampDepCount;
-
- for (; pSampDep<pLastSampDep; pSampDep++)
- {
- assert(pSampDep->ppFXPointers);
-
- for (size_t i=0; i<pSampDep->Count; i++)
- {
- if ( ApplyRenderStateBlock(pSampDep->ppFXPointers[i]) )
- {
- // If the sampler was updated, its pointer will have changed
- pSampDep->ppD3DObjects[i] = pSampDep->ppFXPointers[i]->pD3DObject;
- }
- }
- (m_pContext->*(pVT->pSetSamplers))(pSampDep->StartIndex, pSampDep->Count, pSampDep->ppD3DObjects);
- }
-
- // Set the UAVs
- // UAV ranges were combined in EffectLoad. This code remains unchanged, however, so that ranges can be easily split
- assert( pBlock->UAVDepCount < 2 );
- if( pBlock->UAVDepCount > 0 )
- {
- SUnorderedAccessViewDependency *pUAVDep = pBlock->pUAVDeps;
- assert(pUAVDep->ppFXPointers != 0);
- _Analysis_assume_(pUAVDep->ppFXPointers != 0);
-
- for (size_t i=0; i<pUAVDep->Count; i++)
- {
- pUAVDep->ppD3DObjects[i] = pUAVDep->ppFXPointers[i]->pUnorderedAccessView;
- }
-
- if( EOT_ComputeShader5 == pBlock->GetShaderType() )
- {
- m_pContext->CSSetUnorderedAccessViews( pUAVDep->StartIndex, pUAVDep->Count, pUAVDep->ppD3DObjects, g_pNegativeOnes );
- }
- else
- {
- // This call could be combined with the call to set render targets if both exist in the pass
- m_pContext->OMSetRenderTargetsAndUnorderedAccessViews( D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, pUAVDep->StartIndex, pUAVDep->Count, pUAVDep->ppD3DObjects, g_pNegativeOnes );
- }
- }
-
- // TBuffers are funny:
- // We keep two references to them. One is in as a standard texture dep, and that gets used for all sets
- // The other is as a part of the TBufferDeps array, which tells us to rebuild the matching CBs.
- // These two refs could be rolled into one, but then we would have to predicate on each CB or each texture.
- SConstantBuffer **ppTB = pBlock->ppTbufDeps;
- SConstantBuffer **ppLastTB = ppTB + pBlock->TBufferDepCount;
-
- for (; ppTB<ppLastTB; ppTB++)
- {
- CheckAndUpdateCB_FX(m_pContext, (SConstantBuffer*)*ppTB);
- }
-
- // Set the textures
- SShaderResourceDependency *pResourceDep = pBlock->pResourceDeps;
- SShaderResourceDependency *pLastResourceDep = pBlock->pResourceDeps + pBlock->ResourceDepCount;
-
- for (; pResourceDep<pLastResourceDep; pResourceDep++)
- {
- assert(pResourceDep->ppFXPointers != 0);
- _Analysis_assume_(pResourceDep->ppFXPointers != 0);
-
- for (size_t i=0; i<pResourceDep->Count; i++)
- {
- pResourceDep->ppD3DObjects[i] = pResourceDep->ppFXPointers[i]->pShaderResource;
- }
-
- (m_pContext->*(pVT->pSetShaderResources))(pResourceDep->StartIndex, pResourceDep->Count, pResourceDep->ppD3DObjects);
- }
-
- // Update Interface dependencies
- uint32_t Interfaces = 0;
- ID3D11ClassInstance** ppClassInstances = nullptr;
- assert( pBlock->InterfaceDepCount < 2 );
- if( pBlock->InterfaceDepCount > 0 )
- {
- SInterfaceDependency *pInterfaceDep = pBlock->pInterfaceDeps;
- assert(pInterfaceDep->ppFXPointers);
-
- ppClassInstances = pInterfaceDep->ppD3DObjects;
- Interfaces = pInterfaceDep->Count;
- for (size_t i=0; i<pInterfaceDep->Count; i++)
- {
- assert(pInterfaceDep->ppFXPointers != 0);
- _Analysis_assume_(pInterfaceDep->ppFXPointers != 0);
- SClassInstanceGlobalVariable* pCI = pInterfaceDep->ppFXPointers[i]->pClassInstance;
- if( pCI )
- {
- assert( pCI->pMemberData != 0 );
- _Analysis_assume_( pCI->pMemberData != 0 );
- pInterfaceDep->ppD3DObjects[i] = pCI->pMemberData->Data.pD3DClassInstance;
- }
- else
- {
- pInterfaceDep->ppD3DObjects[i] = nullptr;
- }
- }
- }
-
- // Now set the shader
- (m_pContext->*(pVT->pSetShader))(pBlock->pD3DObject, ppClassInstances, Interfaces);
-}
-
-// Returns true if the block D3D data was recreated
-bool CEffect::ApplyRenderStateBlock(_In_ SBaseBlock *pBlock)
-{
- if( pBlock->IsUserManaged )
- {
- return false;
- }
-
- bool bRecreate = pBlock->ApplyAssignments(this);
-
- if (bRecreate)
- {
- switch (pBlock->BlockType)
- {
- case EBT_Sampler:
- {
- SSamplerBlock *pSBlock = pBlock->AsSampler();
-
- assert(pSBlock->pD3DObject != 0);
- _Analysis_assume_(pSBlock->pD3DObject != 0);
- pSBlock->pD3DObject->Release();
-
- HRESULT hr = m_pDevice->CreateSamplerState( &pSBlock->BackingStore.SamplerDesc, &pSBlock->pD3DObject );
- if ( SUCCEEDED(hr) )
- {
- SetDebugObjectName(pSBlock->pD3DObject, "D3DX11Effect");
- }
- }
- break;
-
- case EBT_DepthStencil:
- {
- SDepthStencilBlock *pDSBlock = pBlock->AsDepthStencil();
-
- assert(nullptr != pDSBlock->pDSObject);
- SAFE_RELEASE( pDSBlock->pDSObject );
- if( SUCCEEDED( m_pDevice->CreateDepthStencilState( &pDSBlock->BackingStore, &pDSBlock->pDSObject ) ) )
- {
- pDSBlock->IsValid = true;
- SetDebugObjectName( pDSBlock->pDSObject, "D3DX11Effect" );
- }
- else
- pDSBlock->IsValid = false;
- }
- break;
-
- case EBT_Blend:
- {
- SBlendBlock *pBBlock = pBlock->AsBlend();
-
- assert(nullptr != pBBlock->pBlendObject);
- SAFE_RELEASE( pBBlock->pBlendObject );
- if( SUCCEEDED( m_pDevice->CreateBlendState( &pBBlock->BackingStore, &pBBlock->pBlendObject ) ) )
- {
- pBBlock->IsValid = true;
- SetDebugObjectName( pBBlock->pBlendObject, "D3DX11Effect" );
- }
- else
- pBBlock->IsValid = false;
- }
- break;
-
- case EBT_Rasterizer:
- {
- SRasterizerBlock *pRBlock = pBlock->AsRasterizer();
-
- assert(nullptr != pRBlock->pRasterizerObject);
-
- SAFE_RELEASE( pRBlock->pRasterizerObject );
- if( SUCCEEDED( m_pDevice->CreateRasterizerState( &pRBlock->BackingStore, &pRBlock->pRasterizerObject ) ) )
- {
- pRBlock->IsValid = true;
- SetDebugObjectName( pRBlock->pRasterizerObject, "D3DX11Effect" );
- }
- else
- pRBlock->IsValid = false;
- }
- break;
-
- default:
- assert(0);
- }
- }
-
- return bRecreate;
-}
-
-void CEffect::ValidateIndex(_In_ uint32_t Elements)
-{
- if (m_FXLIndex >= Elements)
- {
- DPF(0, "ID3DX11Effect: Overindexing variable array (size: %u, index: %u), using index = 0 instead", Elements, m_FXLIndex);
- m_FXLIndex = 0;
- }
-}
-
-// Returns true if the assignment was changed
-bool CEffect::EvaluateAssignment(_Inout_ SAssignment *pAssignment)
-{
- bool bNeedUpdate = false;
- SGlobalVariable *pVarDep0, *pVarDep1;
-
- switch (pAssignment->AssignmentType)
- {
- case ERAT_NumericVariable:
- assert(pAssignment->DependencyCount == 1);
- if (pAssignment->pDependencies[0].pVariable->LastModifiedTime >= pAssignment->LastRecomputedTime)
- {
- memcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);
- bNeedUpdate = true;
- }
- break;
-
- case ERAT_NumericVariableIndex:
- assert(pAssignment->DependencyCount == 2);
- pVarDep0 = pAssignment->pDependencies[0].pVariable;
- pVarDep1 = pAssignment->pDependencies[1].pVariable;
-
- if (pVarDep0->LastModifiedTime >= pAssignment->LastRecomputedTime)
- {
- m_FXLIndex = *pVarDep0->Data.pNumericDword;
-
- ValidateIndex(pVarDep1->pType->Elements);
-
- // Array index variable is dirty, update the pointer
- pAssignment->Source.pNumeric = pVarDep1->Data.pNumeric + pVarDep1->pType->Stride * m_FXLIndex;
-
- // Copy the new data
- memcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);
- bNeedUpdate = true;
- }
- else if (pVarDep1->LastModifiedTime >= pAssignment->LastRecomputedTime)
- {
- // Only the array variable is dirty, copy the new data
- memcpy(pAssignment->Destination.pNumeric, pAssignment->Source.pNumeric, pAssignment->DataSize);
- bNeedUpdate = true;
- }
- break;
-
- case ERAT_ObjectVariableIndex:
- assert(pAssignment->DependencyCount == 1);
- pVarDep0 = pAssignment->pDependencies[0].pVariable;
- if (pVarDep0->LastModifiedTime >= pAssignment->LastRecomputedTime)
- {
- m_FXLIndex = *pVarDep0->Data.pNumericDword;
- ValidateIndex(pAssignment->MaxElements);
-
- // Array index variable is dirty, update the destination pointer
- *((void **)pAssignment->Destination.pGeneric) = pAssignment->Source.pNumeric +
- pAssignment->DataSize * m_FXLIndex;
- bNeedUpdate = true;
- }
- break;
-
- default:
- //case ERAT_Constant: -- These are consumed and discarded
- //case ERAT_ObjectVariable: -- These are consumed and discarded
- //case ERAT_ObjectConstIndex: -- These are consumed and discarded
- //case ERAT_ObjectInlineShader: -- These are consumed and discarded
- //case ERAT_NumericConstIndex: -- ERAT_NumericVariable should be generated instead
- assert(0);
- break;
- }
-
- // Mark the assignment as not dirty
- pAssignment->LastRecomputedTime = m_LocalTimer;
-
- return bNeedUpdate;
-}
-
-// Returns false if this shader has interface dependencies which are nullptr (SetShader will fail).
-bool CEffect::ValidateShaderBlock( _Inout_ SShaderBlock* pBlock )
-{
- if( !pBlock->IsValid )
- return false;
- if( pBlock->InterfaceDepCount > 0 )
- {
- assert( pBlock->InterfaceDepCount == 1 );
- for( size_t i=0; i < pBlock->pInterfaceDeps[0].Count; i++ )
- {
- SInterface* pInterfaceDep = pBlock->pInterfaceDeps[0].ppFXPointers[i];
- assert( pInterfaceDep != 0 );
- _Analysis_assume_( pInterfaceDep != 0 );
- if( pInterfaceDep->pClassInstance == nullptr )
- {
- return false;
- }
- }
- }
- return true;
-}
-
-// Returns false if any state in the pass is invalid
-bool CEffect::ValidatePassBlock( _Inout_ SPassBlock* pBlock )
-{
- pBlock->ApplyPassAssignments();
-
- if (nullptr != pBlock->BackingStore.pBlendBlock)
- {
- ApplyRenderStateBlock(pBlock->BackingStore.pBlendBlock);
- pBlock->BackingStore.pBlendState = pBlock->BackingStore.pBlendBlock->pBlendObject;
- if( !pBlock->BackingStore.pBlendBlock->IsValid )
- return false;
- }
-
- if( nullptr != pBlock->BackingStore.pDepthStencilBlock )
- {
- ApplyRenderStateBlock( pBlock->BackingStore.pDepthStencilBlock );
- pBlock->BackingStore.pDepthStencilState = pBlock->BackingStore.pDepthStencilBlock->pDSObject;
- if( !pBlock->BackingStore.pDepthStencilBlock->IsValid )
- return false;
- }
-
- if( nullptr != pBlock->BackingStore.pRasterizerBlock )
- {
- ApplyRenderStateBlock( pBlock->BackingStore.pRasterizerBlock );
- if( !pBlock->BackingStore.pRasterizerBlock->IsValid )
- return false;
- }
-
- if( nullptr != pBlock->BackingStore.pVertexShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pVertexShaderBlock) )
- return false;
-
- if( nullptr != pBlock->BackingStore.pGeometryShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pGeometryShaderBlock) )
- return false;
-
- if( nullptr != pBlock->BackingStore.pPixelShaderBlock )
- {
- if( !ValidateShaderBlock(pBlock->BackingStore.pPixelShaderBlock) )
- return false;
- else if( pBlock->BackingStore.pPixelShaderBlock->UAVDepCount > 0 &&
- pBlock->BackingStore.RenderTargetViewCount > pBlock->BackingStore.pPixelShaderBlock->pUAVDeps[0].StartIndex )
- {
- return false;
- }
- }
-
- if( nullptr != pBlock->BackingStore.pHullShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pHullShaderBlock) )
- return false;
-
- if( nullptr != pBlock->BackingStore.pDomainShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pDomainShaderBlock) )
- return false;
-
- if( nullptr != pBlock->BackingStore.pComputeShaderBlock && !ValidateShaderBlock(pBlock->BackingStore.pComputeShaderBlock) )
- return false;
-
- return true;
-}
-
-// Set all state defined in the pass
-void CEffect::ApplyPassBlock(_Inout_ SPassBlock *pBlock)
-{
- pBlock->ApplyPassAssignments();
-
- if (nullptr != pBlock->BackingStore.pBlendBlock)
- {
- ApplyRenderStateBlock(pBlock->BackingStore.pBlendBlock);
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pBlendBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid BlendState." );
-#endif
- pBlock->BackingStore.pBlendState = pBlock->BackingStore.pBlendBlock->pBlendObject;
- m_pContext->OMSetBlendState(pBlock->BackingStore.pBlendState,
- pBlock->BackingStore.BlendFactor,
- pBlock->BackingStore.SampleMask);
- }
-
- if (nullptr != pBlock->BackingStore.pDepthStencilBlock)
- {
- ApplyRenderStateBlock(pBlock->BackingStore.pDepthStencilBlock);
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pDepthStencilBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid DepthStencilState." );
-#endif
- pBlock->BackingStore.pDepthStencilState = pBlock->BackingStore.pDepthStencilBlock->pDSObject;
- m_pContext->OMSetDepthStencilState(pBlock->BackingStore.pDepthStencilState,
- pBlock->BackingStore.StencilRef);
- }
-
- if (nullptr != pBlock->BackingStore.pRasterizerBlock)
- {
- ApplyRenderStateBlock(pBlock->BackingStore.pRasterizerBlock);
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pRasterizerBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid RasterizerState." );
-#endif
- m_pContext->RSSetState(pBlock->BackingStore.pRasterizerBlock->pRasterizerObject);
- }
-
- if (nullptr != pBlock->BackingStore.pRenderTargetViews[0])
- {
- // Grab all render targets
- ID3D11RenderTargetView *pRTV[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
-
- assert(pBlock->BackingStore.RenderTargetViewCount <= D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT);
- _Analysis_assume_(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT >= pBlock->BackingStore.RenderTargetViewCount);
-
- for (uint32_t i=0; i<pBlock->BackingStore.RenderTargetViewCount; i++)
- {
- pRTV[i] = pBlock->BackingStore.pRenderTargetViews[i]->pRenderTargetView;
- }
-
- // This call could be combined with the call to set PS UAVs if both exist in the pass
- m_pContext->OMSetRenderTargetsAndUnorderedAccessViews( pBlock->BackingStore.RenderTargetViewCount, pRTV, pBlock->BackingStore.pDepthStencilView->pDepthStencilView, 7, D3D11_KEEP_UNORDERED_ACCESS_VIEWS, nullptr, nullptr );
- }
-
- if (nullptr != pBlock->BackingStore.pVertexShaderBlock)
- {
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pVertexShaderBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid vertex shader." );
-#endif
- ApplyShaderBlock(pBlock->BackingStore.pVertexShaderBlock);
- }
-
- if (nullptr != pBlock->BackingStore.pPixelShaderBlock)
- {
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pPixelShaderBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid pixel shader." );
-#endif
- ApplyShaderBlock(pBlock->BackingStore.pPixelShaderBlock);
- }
-
- if (nullptr != pBlock->BackingStore.pGeometryShaderBlock)
- {
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pGeometryShaderBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid geometry shader." );
-#endif
- ApplyShaderBlock(pBlock->BackingStore.pGeometryShaderBlock);
- }
-
- if (nullptr != pBlock->BackingStore.pHullShaderBlock)
- {
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pHullShaderBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid hull shader." );
-#endif
- ApplyShaderBlock(pBlock->BackingStore.pHullShaderBlock);
- }
-
- if (nullptr != pBlock->BackingStore.pDomainShaderBlock)
- {
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pDomainShaderBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid domain shader." );
-#endif
- ApplyShaderBlock(pBlock->BackingStore.pDomainShaderBlock);
- }
-
- if (nullptr != pBlock->BackingStore.pComputeShaderBlock)
- {
-#ifdef FXDEBUG
- if( !pBlock->BackingStore.pComputeShaderBlock->IsValid )
- DPF( 0, "Pass::Apply - warning: applying invalid compute shader." );
-#endif
- ApplyShaderBlock(pBlock->BackingStore.pComputeShaderBlock);
- }
-}
-
-void CEffect::IncrementTimer()
-{
- m_LocalTimer++;
-
-#if !defined(_M_X64) && !defined(_M_ARM64)
-#ifdef _DEBUG
- if (m_LocalTimer > g_TimerRolloverCount)
- {
- DPF(0, "Rolling over timer (current time: %zu, rollover cap: %u).", m_LocalTimer, g_TimerRolloverCount);
-#else
- if (m_LocalTimer >= 0x80000000) // check to see if we've exceeded ~2 billion
- {
-#endif
- HandleLocalTimerRollover();
-
- m_LocalTimer = 1;
- }
-#endif // _M_X64
-}
-
-// This function resets all timers, rendering all assignments dirty
-// This is clearly bad for performance, but should only happen every few billion ticks
-void CEffect::HandleLocalTimerRollover()
-{
- uint32_t i, j, k;
-
- // step 1: update variables
- for (i = 0; i < m_VariableCount; ++ i)
- {
- m_pVariables[i].LastModifiedTime = 0;
- }
-
- // step 2: update assignments on all blocks (pass, depth stencil, rasterizer, blend, sampler)
- for (uint32_t iGroup = 0; iGroup < m_GroupCount; ++ iGroup)
- {
- for (i = 0; i < m_pGroups[iGroup].TechniqueCount; ++ i)
- {
- for (j = 0; j < m_pGroups[iGroup].pTechniques[i].PassCount; ++ j)
- {
- for (k = 0; k < m_pGroups[iGroup].pTechniques[i].pPasses[j].AssignmentCount; ++ k)
- {
- m_pGroups[iGroup].pTechniques[i].pPasses[j].pAssignments[k].LastRecomputedTime = 0;
- }
- }
- }
- }
-
- for (i = 0; i < m_DepthStencilBlockCount; ++ i)
- {
- for (j = 0; j < m_pDepthStencilBlocks[i].AssignmentCount; ++ j)
- {
- m_pDepthStencilBlocks[i].pAssignments[j].LastRecomputedTime = 0;
- }
- }
-
- for (i = 0; i < m_RasterizerBlockCount; ++ i)
- {
- for (j = 0; j < m_pRasterizerBlocks[i].AssignmentCount; ++ j)
- {
- m_pRasterizerBlocks[i].pAssignments[j].LastRecomputedTime = 0;
- }
- }
-
- for (i = 0; i < m_BlendBlockCount; ++ i)
- {
- for (j = 0; j < m_pBlendBlocks[i].AssignmentCount; ++ j)
- {
- m_pBlendBlocks[i].pAssignments[j].LastRecomputedTime = 0;
- }
- }
-
- for (i = 0; i < m_SamplerBlockCount; ++ i)
- {
- for (j = 0; j < m_pSamplerBlocks[i].AssignmentCount; ++ j)
- {
- m_pSamplerBlocks[i].pAssignments[j].LastRecomputedTime = 0;
- }
- }
-}
-
-}
diff --git a/lib/win32/Effects11/EffectVariable.inl b/lib/win32/Effects11/EffectVariable.inl
deleted file mode 100644
index d287e85f56..0000000000
--- a/lib/win32/Effects11/EffectVariable.inl
+++ /dev/null
@@ -1,4964 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: EffectVariable.inl
-//
-// Direct3D 11 Effects Variable reflection template
-// These templates define the many Effect variable types.
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma warning(push)
-#pragma warning(disable : 4127)
-
-//////////////////////////////////////////////////////////////////////////
-// Invalid variable forward defines
-//////////////////////////////////////////////////////////////////////////
-
-struct SEffectInvalidScalarVariable;
-struct SEffectInvalidVectorVariable;
-struct SEffectInvalidMatrixVariable;
-struct SEffectInvalidStringVariable;
-struct SEffectInvalidClassInstanceVariable;
-struct SEffectInvalidInterfaceVariable;
-struct SEffectInvalidShaderResourceVariable;
-struct SEffectInvalidUnorderedAccessViewVariable;
-struct SEffectInvalidRenderTargetViewVariable;
-struct SEffectInvalidDepthStencilViewVariable;
-struct SEffectInvalidConstantBuffer;
-struct SEffectInvalidShaderVariable;
-struct SEffectInvalidBlendVariable;
-struct SEffectInvalidDepthStencilVariable;
-struct SEffectInvalidRasterizerVariable;
-struct SEffectInvalidSamplerVariable;
-struct SEffectInvalidTechnique;
-struct SEffectInvalidPass;
-struct SEffectInvalidType;
-
-extern SEffectInvalidScalarVariable g_InvalidScalarVariable;
-extern SEffectInvalidVectorVariable g_InvalidVectorVariable;
-extern SEffectInvalidMatrixVariable g_InvalidMatrixVariable;
-extern SEffectInvalidStringVariable g_InvalidStringVariable;
-extern SEffectInvalidClassInstanceVariable g_InvalidClassInstanceVariable;
-extern SEffectInvalidInterfaceVariable g_InvalidInterfaceVariable;
-extern SEffectInvalidShaderResourceVariable g_InvalidShaderResourceVariable;
-extern SEffectInvalidUnorderedAccessViewVariable g_InvalidUnorderedAccessViewVariable;
-extern SEffectInvalidRenderTargetViewVariable g_InvalidRenderTargetViewVariable;
-extern SEffectInvalidDepthStencilViewVariable g_InvalidDepthStencilViewVariable;
-extern SEffectInvalidConstantBuffer g_InvalidConstantBuffer;
-extern SEffectInvalidShaderVariable g_InvalidShaderVariable;
-extern SEffectInvalidBlendVariable g_InvalidBlendVariable;
-extern SEffectInvalidDepthStencilVariable g_InvalidDepthStencilVariable;
-extern SEffectInvalidRasterizerVariable g_InvalidRasterizerVariable;
-extern SEffectInvalidSamplerVariable g_InvalidSamplerVariable;
-extern SEffectInvalidTechnique g_InvalidTechnique;
-extern SEffectInvalidPass g_InvalidPass;
-extern SEffectInvalidType g_InvalidType;
-
-enum ETemplateVarType
-{
- ETVT_Bool,
- ETVT_Int,
- ETVT_Float,
- ETVT_bool
-};
-
-//////////////////////////////////////////////////////////////////////////
-// Invalid effect variable struct definitions
-//////////////////////////////////////////////////////////////////////////
-
-struct SEffectInvalidType : public ID3DX11EffectType
-{
- STDMETHOD_(bool, IsValid)() override { return false; }
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidType; }
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidType; }
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(_In_z_ LPCSTR Semantic) override { UNREFERENCED_PARAMETER(Semantic); return &g_InvalidType; }
- STDMETHOD_(LPCSTR, GetMemberName)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return nullptr; }
- STDMETHOD_(LPCSTR, GetMemberSemantic)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return nullptr; }
- IUNKNOWN_IMP(SEffectInvalidType, ID3DX11EffectType, IUnknown);
-};
-
-template<typename IBaseInterface>
-struct TEffectInvalidVariable : public IBaseInterface
-{
-public:
- STDMETHOD_(bool, IsValid)() override { return false; }
- STDMETHOD_(ID3DX11EffectType*, GetType)() override { return &g_InvalidType; }
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic) override { UNREFERENCED_PARAMETER(Semantic); return &g_InvalidScalarVariable; }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override { return &g_InvalidConstantBuffer; }
-
- STDMETHOD_(ID3DX11EffectScalarVariable*, AsScalar)() override { return &g_InvalidScalarVariable; }
- STDMETHOD_(ID3DX11EffectVectorVariable*, AsVector)() override { return &g_InvalidVectorVariable; }
- STDMETHOD_(ID3DX11EffectMatrixVariable*, AsMatrix)() override { return &g_InvalidMatrixVariable; }
- STDMETHOD_(ID3DX11EffectStringVariable*, AsString)() override { return &g_InvalidStringVariable; }
- STDMETHOD_(ID3DX11EffectClassInstanceVariable*, AsClassInstance)() override { return &g_InvalidClassInstanceVariable; }
- STDMETHOD_(ID3DX11EffectInterfaceVariable*, AsInterface)() override { return &g_InvalidInterfaceVariable; }
- STDMETHOD_(ID3DX11EffectShaderResourceVariable*, AsShaderResource)() override { return &g_InvalidShaderResourceVariable; }
- STDMETHOD_(ID3DX11EffectUnorderedAccessViewVariable*, AsUnorderedAccessView)() override { return &g_InvalidUnorderedAccessViewVariable; }
- STDMETHOD_(ID3DX11EffectRenderTargetViewVariable*, AsRenderTargetView)() override { return &g_InvalidRenderTargetViewVariable; }
- STDMETHOD_(ID3DX11EffectDepthStencilViewVariable*, AsDepthStencilView)() override { return &g_InvalidDepthStencilViewVariable; }
- STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)() override { return &g_InvalidConstantBuffer; }
- STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)() override { return &g_InvalidShaderVariable; }
- STDMETHOD_(ID3DX11EffectBlendVariable*, AsBlend)() override { return &g_InvalidBlendVariable; }
- STDMETHOD_(ID3DX11EffectDepthStencilVariable*, AsDepthStencil)() override { return &g_InvalidDepthStencilVariable; }
- STDMETHOD_(ID3DX11EffectRasterizerVariable*, AsRasterizer)() override { return &g_InvalidRasterizerVariable; }
- STDMETHOD_(ID3DX11EffectSamplerVariable*, AsSampler)() override { return &g_InvalidSamplerVariable; }
-
- STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetRawValue)(_Out_writes_bytes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-};
-
-struct SEffectInvalidScalarVariable : public TEffectInvalidVariable<ID3DX11EffectScalarVariable>
-{
-public:
-
- STDMETHOD(SetFloat)(_In_ const float Value) override { UNREFERENCED_PARAMETER(Value); return E_FAIL; }
- STDMETHOD(GetFloat)(_Out_ float *pValue) override { UNREFERENCED_PARAMETER(pValue); return E_FAIL; }
-
- STDMETHOD(SetFloatArray)(_In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetFloatArray)(_Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- STDMETHOD(SetInt)(_In_ const int Value) override { UNREFERENCED_PARAMETER(Value); return E_FAIL; }
- STDMETHOD(GetInt)(_Out_ int *pValue) override { UNREFERENCED_PARAMETER(pValue); return E_FAIL; }
-
- STDMETHOD(SetIntArray)(_In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetIntArray)(_Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- STDMETHOD(SetBool)(_In_ const bool Value) override { UNREFERENCED_PARAMETER(Value); return E_FAIL; }
- STDMETHOD(GetBool)(_Out_ bool *pValue) override { UNREFERENCED_PARAMETER(pValue); return E_FAIL; }
-
- STDMETHOD(SetBoolArray)(_In_reads_(Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetBoolArray)(_Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidScalarVariable, ID3DX11EffectScalarVariable, ID3DX11EffectVariable);
-};
-
-
-struct SEffectInvalidVectorVariable : public TEffectInvalidVariable<ID3DX11EffectVectorVariable>
-{
-public:
- STDMETHOD(SetFloatVector)(_In_reads_(4) const float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
- STDMETHOD(SetIntVector)(_In_reads_(4) const int *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
- STDMETHOD(SetBoolVector)(_In_reads_(4) const bool *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
-
- STDMETHOD(GetFloatVector)(_Out_writes_(4) float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
- STDMETHOD(GetIntVector)(_Out_writes_(4) int *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
- STDMETHOD(GetBoolVector)(_Out_writes_(4) bool *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; };
-
- STDMETHOD(SetBoolVectorArray) (_In_reads_(4*Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
- STDMETHOD(SetIntVectorArray) (_In_reads_(4*Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
- STDMETHOD(SetFloatVectorArray)(_In_reads_(4*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
-
- STDMETHOD(GetBoolVectorArray) (_Out_writes_(4*Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
- STDMETHOD(GetIntVectorArray) (_Out_writes_(4*Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
- STDMETHOD(GetFloatVectorArray)(_Out_writes_(4*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; };
-
- IUNKNOWN_IMP(SEffectInvalidVectorVariable, ID3DX11EffectVectorVariable, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidMatrixVariable : public TEffectInvalidVariable<ID3DX11EffectMatrixVariable>
-{
-public:
-
- STDMETHOD(SetMatrix)(_In_reads_(16) const float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; }
- STDMETHOD(GetMatrix)(_Out_writes_(16) float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; }
-
- STDMETHOD(SetMatrixArray)(_In_reads_(16*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetMatrixArray)(_Out_writes_(16*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- STDMETHOD(SetMatrixPointerArray)(_In_reads_(16*Count) const float **ppData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetMatrixPointerArray)(_Out_writes_(16*Count) float **ppData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- STDMETHOD(SetMatrixTranspose)(_In_reads_(16) const float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; }
- STDMETHOD(GetMatrixTranspose)(_Out_writes_(16) float *pData) override { UNREFERENCED_PARAMETER(pData); return E_FAIL; }
-
- STDMETHOD(SetMatrixTransposeArray)(_In_reads_(16*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetMatrixTransposeArray)(_Out_writes_(16*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- STDMETHOD(SetMatrixTransposePointerArray)(_In_reads_(16*Count) const float **ppData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetMatrixTransposePointerArray)(_Out_writes_(16*Count) float **ppData, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidMatrixVariable, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidStringVariable : public TEffectInvalidVariable<ID3DX11EffectStringVariable>
-{
-public:
-
- STDMETHOD(GetString)(_Outptr_result_z_ LPCSTR *ppString) override { UNREFERENCED_PARAMETER(ppString); return E_FAIL; }
- STDMETHOD(GetStringArray)(_Out_writes_(Count) LPCSTR *ppStrings, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppStrings); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidStringVariable, ID3DX11EffectStringVariable, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidClassInstanceVariable : public TEffectInvalidVariable<ID3DX11EffectClassInstanceVariable>
-{
-public:
-
- STDMETHOD(GetClassInstance)(_Outptr_ ID3D11ClassInstance **ppClassInstance) override { UNREFERENCED_PARAMETER(ppClassInstance); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidClassInstanceVariable, ID3DX11EffectClassInstanceVariable, ID3DX11EffectVariable);
-};
-
-
-struct SEffectInvalidInterfaceVariable : public TEffectInvalidVariable<ID3DX11EffectInterfaceVariable>
-{
-public:
-
- STDMETHOD(SetClassInstance)(_In_ ID3DX11EffectClassInstanceVariable *pEffectClassInstance) override
- { UNREFERENCED_PARAMETER(pEffectClassInstance); return E_FAIL; }
- STDMETHOD(GetClassInstance)(_Outptr_ ID3DX11EffectClassInstanceVariable **ppEffectClassInstance) override
- { UNREFERENCED_PARAMETER(ppEffectClassInstance); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidInterfaceVariable, ID3DX11EffectInterfaceVariable, ID3DX11EffectVariable);
-};
-
-
-struct SEffectInvalidShaderResourceVariable : public TEffectInvalidVariable<ID3DX11EffectShaderResourceVariable>
-{
-public:
-
- STDMETHOD(SetResource)(_In_ ID3D11ShaderResourceView *pResource) override { UNREFERENCED_PARAMETER(pResource); return E_FAIL; }
- STDMETHOD(GetResource)(_Outptr_ ID3D11ShaderResourceView **ppResource) override { UNREFERENCED_PARAMETER(ppResource); return E_FAIL; }
-
- STDMETHOD(SetResourceArray)(_In_reads_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetResourceArray)(_Out_writes_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidShaderResourceVariable, ID3DX11EffectShaderResourceVariable, ID3DX11EffectVariable);
-};
-
-
-struct SEffectInvalidUnorderedAccessViewVariable : public TEffectInvalidVariable<ID3DX11EffectUnorderedAccessViewVariable>
-{
-public:
-
- STDMETHOD(SetUnorderedAccessView)(_In_ ID3D11UnorderedAccessView *pResource) override { UNREFERENCED_PARAMETER(pResource); return E_FAIL; }
- STDMETHOD(GetUnorderedAccessView)(_Outptr_ ID3D11UnorderedAccessView **ppResource) override { UNREFERENCED_PARAMETER(ppResource); return E_FAIL; }
-
- STDMETHOD(SetUnorderedAccessViewArray)(_In_reads_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetUnorderedAccessViewArray)(_Out_writes_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidUnorderedAccessViewVariable, ID3DX11EffectUnorderedAccessViewVariable, ID3DX11EffectVariable);
-};
-
-
-struct SEffectInvalidRenderTargetViewVariable : public TEffectInvalidVariable<ID3DX11EffectRenderTargetViewVariable>
-{
-public:
-
- STDMETHOD(SetRenderTarget)(_In_ ID3D11RenderTargetView *pResource) override { UNREFERENCED_PARAMETER(pResource); return E_FAIL; }
- STDMETHOD(GetRenderTarget)(_Outptr_ ID3D11RenderTargetView **ppResource) override { UNREFERENCED_PARAMETER(ppResource); return E_FAIL; }
-
- STDMETHOD(SetRenderTargetArray)(_In_reads_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetRenderTargetArray)(_Out_writes_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidRenderTargetViewVariable, ID3DX11EffectRenderTargetViewVariable, ID3DX11EffectVariable);
-};
-
-
-struct SEffectInvalidDepthStencilViewVariable : public TEffectInvalidVariable<ID3DX11EffectDepthStencilViewVariable>
-{
-public:
-
- STDMETHOD(SetDepthStencil)(_In_ ID3D11DepthStencilView *pResource) override { UNREFERENCED_PARAMETER(pResource); return E_FAIL; }
- STDMETHOD(GetDepthStencil)(_Outptr_ ID3D11DepthStencilView **ppResource) override { UNREFERENCED_PARAMETER(ppResource); return E_FAIL; }
-
- STDMETHOD(SetDepthStencilArray)(_In_reads_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
- STDMETHOD(GetDepthStencilArray)(_Out_writes_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override
- { UNREFERENCED_PARAMETER(ppResources); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidDepthStencilViewVariable, ID3DX11EffectDepthStencilViewVariable, ID3DX11EffectVariable);
-};
-
-
-struct SEffectInvalidConstantBuffer : public TEffectInvalidVariable<ID3DX11EffectConstantBuffer>
-{
-public:
-
- STDMETHOD(SetConstantBuffer)(_In_ ID3D11Buffer *pConstantBuffer) override { UNREFERENCED_PARAMETER(pConstantBuffer); return E_FAIL; }
- STDMETHOD(GetConstantBuffer)(_Outptr_ ID3D11Buffer **ppConstantBuffer) override { UNREFERENCED_PARAMETER(ppConstantBuffer); return E_FAIL; }
- STDMETHOD(UndoSetConstantBuffer)() override { return E_FAIL; }
-
- STDMETHOD(SetTextureBuffer)(_In_ ID3D11ShaderResourceView *pTextureBuffer) override { UNREFERENCED_PARAMETER(pTextureBuffer); return E_FAIL; }
- STDMETHOD(GetTextureBuffer)(_Outptr_ ID3D11ShaderResourceView **ppTextureBuffer) override { UNREFERENCED_PARAMETER(ppTextureBuffer); return E_FAIL; }
- STDMETHOD(UndoSetTextureBuffer)() override { return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidConstantBuffer, ID3DX11EffectConstantBuffer, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidShaderVariable : public TEffectInvalidVariable<ID3DX11EffectShaderVariable>
-{
-public:
-
- STDMETHOD(GetShaderDesc)(_In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- STDMETHOD(GetVertexShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11VertexShader **ppVS) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppVS); return E_FAIL; }
- STDMETHOD(GetGeometryShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11GeometryShader **ppGS) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppGS); return E_FAIL; }
- STDMETHOD(GetPixelShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11PixelShader **ppPS) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppPS); return E_FAIL; }
- STDMETHOD(GetHullShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11HullShader **ppHS) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppHS); return E_FAIL; }
- STDMETHOD(GetDomainShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11DomainShader **ppDS) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppDS); return E_FAIL; }
- STDMETHOD(GetComputeShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11ComputeShader **ppCS) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(ppCS); return E_FAIL; }
-
- STDMETHOD(GetInputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(Element); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
- STDMETHOD(GetOutputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(Element); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
- STDMETHOD(GetPatchConstantSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override
- { UNREFERENCED_PARAMETER(ShaderIndex); UNREFERENCED_PARAMETER(Element); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidShaderVariable, ID3DX11EffectShaderVariable, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidBlendVariable : public TEffectInvalidVariable<ID3DX11EffectBlendVariable>
-{
-public:
-
- STDMETHOD(GetBlendState)(_In_ uint32_t Index, _Outptr_ ID3D11BlendState **ppState) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(ppState); return E_FAIL; }
- STDMETHOD(SetBlendState)(_In_ uint32_t Index, _In_ ID3D11BlendState *pState) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pState); return E_FAIL; }
- STDMETHOD(UndoSetBlendState)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return E_FAIL; }
- STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_BLEND_DESC *pDesc) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidBlendVariable, ID3DX11EffectBlendVariable, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidDepthStencilVariable : public TEffectInvalidVariable<ID3DX11EffectDepthStencilVariable>
-{
-public:
-
- STDMETHOD(GetDepthStencilState)(_In_ uint32_t Index, _Outptr_ ID3D11DepthStencilState **ppState) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(ppState); return E_FAIL; }
- STDMETHOD(SetDepthStencilState)(_In_ uint32_t Index, _In_ ID3D11DepthStencilState *pState) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pState); return E_FAIL; }
- STDMETHOD(UndoSetDepthStencilState)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return E_FAIL; }
- STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_DEPTH_STENCIL_DESC *pDesc) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidDepthStencilVariable, ID3DX11EffectDepthStencilVariable, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidRasterizerVariable : public TEffectInvalidVariable<ID3DX11EffectRasterizerVariable>
-{
-public:
-
- STDMETHOD(GetRasterizerState)(_In_ uint32_t Index, _Outptr_ ID3D11RasterizerState **ppState) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(ppState); return E_FAIL; }
- STDMETHOD(SetRasterizerState)(_In_ uint32_t Index, _In_ ID3D11RasterizerState *pState) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pState); return E_FAIL; }
- STDMETHOD(UndoSetRasterizerState)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return E_FAIL; }
- STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_RASTERIZER_DESC *pDesc) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidRasterizerVariable, ID3DX11EffectRasterizerVariable, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidSamplerVariable : public TEffectInvalidVariable<ID3DX11EffectSamplerVariable>
-{
-public:
-
- STDMETHOD(GetSampler)(_In_ uint32_t Index, _Outptr_ ID3D11SamplerState **ppSampler) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(ppSampler); return E_FAIL; }
- STDMETHOD(SetSampler)(_In_ uint32_t Index, _In_ ID3D11SamplerState *pSampler) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pSampler); return E_FAIL; }
- STDMETHOD(UndoSetSampler)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return E_FAIL; }
- STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_SAMPLER_DESC *pDesc) override
- { UNREFERENCED_PARAMETER(Index); UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidSamplerVariable, ID3DX11EffectSamplerVariable, ID3DX11EffectVariable);
-};
-
-struct SEffectInvalidPass : public ID3DX11EffectPass
-{
-public:
- STDMETHOD_(bool, IsValid)() override { return false; }
- STDMETHOD(GetDesc)(_Out_ D3DX11_PASS_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- STDMETHOD(GetVertexShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
- STDMETHOD(GetGeometryShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
- STDMETHOD(GetPixelShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
- STDMETHOD(GetHullShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
- STDMETHOD(GetDomainShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
- STDMETHOD(GetComputeShaderDesc)(_Out_ D3DX11_PASS_SHADER_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
-
- STDMETHOD(Apply)(_In_ uint32_t Flags, _In_ ID3D11DeviceContext* pContext) override
- { UNREFERENCED_PARAMETER(Flags); UNREFERENCED_PARAMETER(pContext); return E_FAIL; }
- STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override { UNREFERENCED_PARAMETER(pStateBlockMask); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidPass, ID3DX11EffectPass, IUnknown);
-};
-
-struct SEffectInvalidTechnique : public ID3DX11EffectTechnique
-{
-public:
- STDMETHOD_(bool, IsValid)() override { return false; }
- STDMETHOD(GetDesc)(_Out_ D3DX11_TECHNIQUE_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
-
- STDMETHOD_(ID3DX11EffectPass*, GetPassByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidPass; }
- STDMETHOD_(ID3DX11EffectPass*, GetPassByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidPass; }
-
- STDMETHOD(ComputeStateBlockMask)(_Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) override { UNREFERENCED_PARAMETER(pStateBlockMask); return E_FAIL; }
-
- IUNKNOWN_IMP(SEffectInvalidTechnique, ID3DX11EffectTechnique, IUnknown);
-};
-
-struct SEffectInvalidGroup : public ID3DX11EffectGroup
-{
-public:
- STDMETHOD_(bool, IsValid)() override { return false; }
- STDMETHOD(GetDesc)(_Out_ D3DX11_GROUP_DESC *pDesc) override { UNREFERENCED_PARAMETER(pDesc); return E_FAIL; }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidScalarVariable; }
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidScalarVariable; }
-
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(_In_ uint32_t Index) override { UNREFERENCED_PARAMETER(Index); return &g_InvalidTechnique; }
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(_In_z_ LPCSTR Name) override { UNREFERENCED_PARAMETER(Name); return &g_InvalidTechnique; }
-
- IUNKNOWN_IMP(SEffectInvalidGroup, ID3DX11EffectGroup, IUnknown);
-};
-
-//////////////////////////////////////////////////////////////////////////
-// Helper routines
-//////////////////////////////////////////////////////////////////////////
-
-// This is an annoying warning that pops up in retail builds because
-// the code that jumps to "lExit" is conditionally not compiled.
-// The only alternative is more #ifdefs in every function
-#pragma warning( disable : 4102 ) // 'label' : unreferenced label
-
-#define VERIFYPARAMETER(x) \
-{ if (!(x)) { DPF(0, "%s: Parameter " #x " was nullptr.", pFuncName); \
- __BREAK_ON_FAIL; hr = E_INVALIDARG; goto lExit; } }
-
-static HRESULT AnnotationInvalidSetCall(LPCSTR pFuncName)
-{
- DPF(0, "%s: Annotations are readonly", pFuncName);
- return D3DERR_INVALIDCALL;
-}
-
-static HRESULT ObjectSetRawValue()
-{
- DPF(0, "ID3DX11EffectVariable::SetRawValue: Objects do not support ths call; please use the specific object accessors instead.");
- return D3DERR_INVALIDCALL;
-}
-
-static HRESULT ObjectGetRawValue()
-{
- DPF(0, "ID3DX11EffectVariable::GetRawValue: Objects do not support ths call; please use the specific object accessors instead.");
- return D3DERR_INVALIDCALL;
-}
-
-ID3DX11EffectConstantBuffer * NoParentCB();
-
-ID3DX11EffectVariable * GetAnnotationByIndexHelper(_In_z_ const char *pClassName, _In_ uint32_t Index,
- _In_ uint32_t AnnotationCount, _In_reads_(AnnotationCount) SAnnotation *pAnnotations);
-
-ID3DX11EffectVariable * GetAnnotationByNameHelper(_In_z_ const char *pClassName, _In_z_ LPCSTR Name,
- _In_ uint32_t AnnotationCount, _In_reads_(AnnotationCount) SAnnotation *pAnnotations);
-
-template<typename SVarType>
-_Success_(return)
-bool GetVariableByIndexHelper(_In_ uint32_t Index, _In_ uint32_t VariableCount, _In_reads_(VariableCount) SVarType *pVariables,
- _In_opt_ uint8_t *pBaseAddress, _Outptr_ SVarType **ppMember, _Outptr_ void **ppDataPtr)
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetMemberByIndex";
-
- if (Index >= VariableCount)
- {
- DPF(0, "%s: Invalid index (%u, total: %u)", pFuncName, Index, VariableCount);
- return false;
- }
-
- *ppMember = pVariables + Index;
- *ppDataPtr = pBaseAddress + (*ppMember)->Data.Offset;
- return true;
-}
-
-template<typename SVarType>
-_Success_(return)
-bool GetVariableByNameHelper(_In_z_ LPCSTR Name, _In_ uint32_t VariableCount, _In_reads_(VariableCount) SVarType *pVariables,
- _In_opt_ uint8_t *pBaseAddress, _Outptr_ SVarType **ppMember, _Outptr_ void **ppDataPtr, _Out_ uint32_t* pIndex)
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetMemberByName";
-
- if (nullptr == Name)
- {
- DPF(0, "%s: Parameter Name was nullptr.", pFuncName);
- return false;
- }
-
- bool bHasSuper = false;
-
- for (uint32_t i = 0; i < VariableCount; ++ i)
- {
- *ppMember = pVariables + i;
- assert((*ppMember)->pName != 0);
- _Analysis_assume_((*ppMember)->pName != 0);
- if (strcmp((*ppMember)->pName, Name) == 0)
- {
- *ppDataPtr = pBaseAddress + (*ppMember)->Data.Offset;
- *pIndex = i;
- return true;
- }
- else if (i == 0 &&
- (*ppMember)->pName[0] == '$' &&
- strcmp((*ppMember)->pName, "$super") == 0)
- {
- bHasSuper = true;
- }
- }
-
- if (bHasSuper)
- {
- SVarType* pSuper = pVariables;
-
- return GetVariableByNameHelper<SVarType>(Name,
- pSuper->pType->StructType.Members,
- (SVarType*)pSuper->pType->StructType.pMembers,
- pBaseAddress + pSuper->Data.Offset,
- ppMember,
- ppDataPtr,
- pIndex);
- }
-
- DPF(0, "%s: Variable [%s] not found", pFuncName, Name);
- return false;
-}
-
-template<typename SVarType>
-_Success_(return)
-bool GetVariableBySemanticHelper(_In_z_ LPCSTR Semantic, _In_ uint32_t VariableCount, _In_reads_(VariableCount) SVarType *pVariables,
- _In_opt_ uint8_t *pBaseAddress, _Outptr_ SVarType **ppMember, _Outptr_ void **ppDataPtr, _Out_ uint32_t* pIndex)
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetMemberBySemantic";
-
- if (nullptr == Semantic)
- {
- DPF(0, "%s: Parameter Semantic was nullptr.", pFuncName);
- return false;
- }
-
- for (uint32_t i = 0; i < VariableCount; ++ i)
- {
- *ppMember = pVariables + i;
- if (nullptr != (*ppMember)->pSemantic &&
- _stricmp((*ppMember)->pSemantic, Semantic) == 0)
- {
- *ppDataPtr = pBaseAddress + (*ppMember)->Data.Offset;
- *pIndex = i;
- return true;
- }
- }
-
- DPF(0, "%s: Variable with semantic [%s] not found", pFuncName, Semantic);
- return false;
-}
-
-inline bool AreBoundsValid(_In_ uint32_t Offset, _In_ uint32_t Count, _In_ const void *pData, _In_ const SType *pType, _In_ uint32_t TotalUnpackedSize)
-{
- if (Count == 0) return true;
- uint32_t singleElementSize = pType->GetTotalUnpackedSize(true);
- assert(singleElementSize <= pType->Stride);
-
- return ((Offset + Count >= Offset) &&
- ((Offset + Count) < ((uint32_t)-1) / pType->Stride) &&
- (Count * pType->Stride + (uint8_t*)pData >= (uint8_t*)pData) &&
- ((Offset + Count - 1) * pType->Stride + singleElementSize <= TotalUnpackedSize));
-}
-
-// Note that the branches in this code is based on template parameters and will be compiled out
-template<ETemplateVarType SourceType, ETemplateVarType DestType, typename SRC_TYPE, bool ValidatePtr>
-__forceinline HRESULT CopyScalarValue(_In_ SRC_TYPE SrcValue, _Out_ void *pDest, _In_z_ const char *pFuncName)
-{
- HRESULT hr = S_OK;
-#ifdef _DEBUG
- if (ValidatePtr)
- VERIFYPARAMETER(pDest);
-#else
- UNREFERENCED_PARAMETER(pFuncName);
-#endif
-
- switch (SourceType)
- {
- case ETVT_Bool:
- switch (DestType)
- {
- case ETVT_Bool:
- *(int*)pDest = (SrcValue != 0) ? -1 : 0;
- break;
-
- case ETVT_Int:
- *(int*)pDest = SrcValue ? 1 : 0;
- break;
-
- case ETVT_Float:
- *(float*)pDest = SrcValue ? 1.0f : 0.0f;
- break;
-
- case ETVT_bool:
- *(bool*)pDest = (SrcValue != 0) ? true : false;
- break;
-
- default:
- assert(0);
- }
- break;
-
- case ETVT_Int:
- switch (DestType)
- {
- case ETVT_Bool:
- *(int*)pDest = (SrcValue != 0) ? -1 : 0;
- break;
-
- case ETVT_Int:
- *(int*)pDest = (int) SrcValue;
- break;
-
- case ETVT_Float:
- *(float*)pDest = (float)(SrcValue);
- break;
-
- case ETVT_bool:
- *(bool*)pDest = (SrcValue != 0) ? true : false;
- break;
-
- default:
- assert(0);
- }
- break;
-
- case ETVT_Float:
- switch (DestType)
- {
- case ETVT_Bool:
- *(int*)pDest = (SrcValue != 0.0f) ? -1 : 0;
- break;
-
- case ETVT_Int:
- *(int*)pDest = (int) (SrcValue);
- break;
-
- case ETVT_Float:
- *(float*)pDest = (float) SrcValue;
- break;
-
- case ETVT_bool:
- *(bool*)pDest = (SrcValue != 0.0f) ? true : false;
- break;
-
- default:
- assert(0);
- }
- break;
-
- case ETVT_bool:
- switch (DestType)
- {
- case ETVT_Bool:
- *(int*)pDest = SrcValue ? -1 : 0;
- break;
-
- case ETVT_Int:
- *(int*)pDest = SrcValue ? 1 : 0;
- break;
-
- case ETVT_Float:
- *(float*)pDest = SrcValue ? 1.0f : 0.0f;
- break;
-
- case ETVT_bool:
- *(bool*)pDest = (SrcValue != 0) ? true : false;
- break;
-
- default:
- assert(0);
- }
- break;
-
- default:
- assert(0);
- }
-
-lExit:
- return hr;
-}
-
-#pragma warning(push)
-#pragma warning( disable : 6103 )
-template<ETemplateVarType SourceType, ETemplateVarType DestType, typename SRC_TYPE, typename DEST_TYPE>
-inline HRESULT SetScalarArray(_In_reads_(Count) const SRC_TYPE *pSrcValues, _Out_writes_(Count) DEST_TYPE *pDestValues,
- _In_ uint32_t Offset, _In_ uint32_t Count,
- _In_ const SType *pType, _In_ uint32_t TotalUnpackedSize, _In_z_ const char *pFuncName)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- VERIFYPARAMETER(pSrcValues);
-
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pSrcValues, pType, TotalUnpackedSize))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#else
- UNREFERENCED_PARAMETER(TotalUnpackedSize);
- UNREFERENCED_PARAMETER(pFuncName);
-#endif
-
- uint32_t i, j, delta = pType->NumericType.IsPackedArray ? 1 : SType::c_ScalarsPerRegister;
- pDestValues += Offset * delta;
- for (i = 0, j = 0; j < Count; i += delta, ++ j)
- {
- // pDestValues[i] = (DEST_TYPE)pSrcValues[j];
- CopyScalarValue<SourceType, DestType, SRC_TYPE, false>(pSrcValues[j], &pDestValues[i], "SetScalarArray");
- }
-
-lExit:
- return hr;
-}
-#pragma warning(pop)
-
-#pragma warning( disable : 6103 )
-template<ETemplateVarType SourceType, ETemplateVarType DestType, typename SRC_TYPE, typename DEST_TYPE>
-inline HRESULT GetScalarArray(_In_reads_(Count) SRC_TYPE *pSrcValues, _Out_writes_(Count) DEST_TYPE *pDestValues,
- _In_ uint32_t Offset, _In_ uint32_t Count,
- _In_ const SType *pType, _In_ uint32_t TotalUnpackedSize, _In_z_ const char *pFuncName)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- VERIFYPARAMETER(pDestValues);
-
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pDestValues, pType, TotalUnpackedSize))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#else
- UNREFERENCED_PARAMETER(TotalUnpackedSize);
- UNREFERENCED_PARAMETER(pFuncName);
-#endif
-
- uint32_t i, j, delta = pType->NumericType.IsPackedArray ? 1 : SType::c_ScalarsPerRegister;
- pSrcValues += Offset * delta;
- for (i = 0, j = 0; j < Count; i += delta, ++ j)
- {
- // pDestValues[j] = (DEST_TYPE)pSrcValues[i];
- CopyScalarValue<SourceType, DestType, SRC_TYPE, false>(pSrcValues[i], &pDestValues[j], "GetScalarArray");
- }
-
-lExit:
- return hr;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// TVariable - implements type casting and member/element retrieval
-//////////////////////////////////////////////////////////////////////////
-
-// requires that IBaseInterface contain SVariable's fields and support ID3DX11EffectVariable
-template<typename IBaseInterface>
-struct TVariable : public IBaseInterface
-{
- STDMETHOD_(bool, IsValid)() override { return true; }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(_In_ uint32_t Index)
- {
- SVariable *pMember;
- UDataPointer dataPtr;
- TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity2 = GetTopLevelEntity();
-
- if (((ID3DX11Effect*)pTopLevelEntity2->pEffect)->IsOptimized())
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberByIndex: Cannot get members; effect has been Optimize()'ed");
- return &g_InvalidScalarVariable;
- }
-
- if (pType->VarType != EVT_Struct)
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberByIndex: Variable is not a structure");
- return &g_InvalidScalarVariable;
- }
-
- if (!GetVariableByIndexHelper<SVariable>(Index, pType->StructType.Members, pType->StructType.pMembers,
- Data.pNumeric, &pMember, &dataPtr.pGeneric))
- {
- return &g_InvalidScalarVariable;
- }
-
- return pTopLevelEntity2->pEffect->CreatePooledVariableMemberInterface(pTopLevelEntity2, pMember, dataPtr, false, Index);
- }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(_In_z_ LPCSTR Name)
- {
- SVariable *pMember;
- UDataPointer dataPtr;
- uint32_t index;
- TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity2 = GetTopLevelEntity();
-
- if (pTopLevelEntity2->pEffect->IsOptimized())
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberByName: Cannot get members; effect has been Optimize()'ed");
- return &g_InvalidScalarVariable;
- }
-
- if (pType->VarType != EVT_Struct)
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberByName: Variable is not a structure");
- return &g_InvalidScalarVariable;
- }
-
- if (!GetVariableByNameHelper<SVariable>(Name, pType->StructType.Members, pType->StructType.pMembers,
- Data.pNumeric, &pMember, &dataPtr.pGeneric, &index))
- {
- return &g_InvalidScalarVariable;
-
- }
-
- return pTopLevelEntity2->pEffect->CreatePooledVariableMemberInterface(pTopLevelEntity2, pMember, dataPtr, false, index);
- }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(_In_z_ LPCSTR Semantic)
- {
- SVariable *pMember;
- UDataPointer dataPtr;
- uint32_t index;
- TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity2 = GetTopLevelEntity();
-
- if (pTopLevelEntity2->pEffect->IsOptimized())
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberBySemantic: Cannot get members; effect has been Optimize()'ed");
- return &g_InvalidScalarVariable;
- }
-
- if (pType->VarType != EVT_Struct)
- {
- DPF(0, "ID3DX11EffectVariable::GetMemberBySemantic: Variable is not a structure");
- return &g_InvalidScalarVariable;
- }
-
- if (!GetVariableBySemanticHelper<SVariable>(Semantic, pType->StructType.Members, pType->StructType.pMembers,
- Data.pNumeric, &pMember, &dataPtr.pGeneric, &index))
- {
- return &g_InvalidScalarVariable;
-
- }
-
- return pTopLevelEntity2->pEffect->CreatePooledVariableMemberInterface(pTopLevelEntity2, pMember, dataPtr, false, index);
- }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetElement)(_In_ uint32_t Index)
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetElement";
- TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity2 = GetTopLevelEntity();
- UDataPointer dataPtr;
-
- if (pTopLevelEntity2->pEffect->IsOptimized())
- {
- DPF(0, "ID3DX11EffectVariable::GetElement: Cannot get element; effect has been Optimize()'ed");
- return &g_InvalidScalarVariable;
- }
-
- if (!IsArray())
- {
- DPF(0, "%s: This interface does not refer to an array", pFuncName);
- return &g_InvalidScalarVariable;
- }
-
- if (Index >= pType->Elements)
- {
- DPF(0, "%s: Invalid element index (%u, total: %u)", pFuncName, Index, pType->Elements);
- return &g_InvalidScalarVariable;
- }
-
- if (pType->BelongsInConstantBuffer())
- {
- dataPtr.pGeneric = Data.pNumeric + pType->Stride * Index;
- }
- else
- {
- dataPtr.pGeneric = GetBlockByIndex(pType->VarType, pType->ObjectType, Data.pGeneric, Index);
- if (nullptr == dataPtr.pGeneric)
- {
- DPF(0, "%s: Internal error", pFuncName);
- return &g_InvalidScalarVariable;
- }
- }
-
- return pTopLevelEntity2->pEffect->CreatePooledVariableMemberInterface(pTopLevelEntity2, (SVariable *) this, dataPtr, true, Index);
- }
-
- STDMETHOD_(ID3DX11EffectScalarVariable*, AsScalar)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsScalar";
-
- if (pType->VarType != EVT_Numeric ||
- pType->NumericType.NumericLayout != ENL_Scalar)
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidScalarVariable;
- }
-
- return (ID3DX11EffectScalarVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectVectorVariable*, AsVector)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsVector";
-
- if (pType->VarType != EVT_Numeric ||
- pType->NumericType.NumericLayout != ENL_Vector)
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidVectorVariable;
- }
-
- return (ID3DX11EffectVectorVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectMatrixVariable*, AsMatrix)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsMatrix";
-
- if (pType->VarType != EVT_Numeric ||
- pType->NumericType.NumericLayout != ENL_Matrix)
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidMatrixVariable;
- }
-
- return (ID3DX11EffectMatrixVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectStringVariable*, AsString)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsString";
-
- if (!pType->IsObjectType(EOT_String))
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidStringVariable;
- }
-
- return (ID3DX11EffectStringVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectClassInstanceVariable*, AsClassInstance)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsClassInstance";
-
- if (!pType->IsClassInstance() )
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidClassInstanceVariable;
- }
- else if( pMemberData == nullptr )
- {
- DPF(0, "%s: Non-global class instance variables (members of structs or classes) and class instances "
- "inside tbuffers are not supported.", pFuncName );
- return &g_InvalidClassInstanceVariable;
- }
-
- return (ID3DX11EffectClassInstanceVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectInterfaceVariable*, AsInterface)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsInterface";
-
- if (!pType->IsInterface())
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidInterfaceVariable;
- }
-
- return (ID3DX11EffectInterfaceVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectShaderResourceVariable*, AsShaderResource)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsShaderResource";
-
- if (!pType->IsShaderResource())
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidShaderResourceVariable;
- }
-
- return (ID3DX11EffectShaderResourceVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectUnorderedAccessViewVariable*, AsUnorderedAccessView)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsUnorderedAccessView";
-
- if (!pType->IsUnorderedAccessView())
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidUnorderedAccessViewVariable;
- }
-
- return (ID3DX11EffectUnorderedAccessViewVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectRenderTargetViewVariable*, AsRenderTargetView)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsRenderTargetView";
-
- if (!pType->IsRenderTargetView())
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidRenderTargetViewVariable;
- }
-
- return (ID3DX11EffectRenderTargetViewVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectDepthStencilViewVariable*, AsDepthStencilView)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsDepthStencilView";
-
- if (!pType->IsDepthStencilView())
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidDepthStencilViewVariable;
- }
-
- return (ID3DX11EffectDepthStencilViewVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsConstantBuffer";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidConstantBuffer;
- }
-
- STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsShader";
-
- if (!pType->IsShader())
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidShaderVariable;
- }
-
- return (ID3DX11EffectShaderVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectBlendVariable*, AsBlend)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsBlend";
-
- if (!pType->IsObjectType(EOT_Blend))
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidBlendVariable;
- }
-
- return (ID3DX11EffectBlendVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectDepthStencilVariable*, AsDepthStencil)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsDepthStencil";
-
- if (!pType->IsObjectType(EOT_DepthStencil))
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidDepthStencilVariable;
- }
-
- return (ID3DX11EffectDepthStencilVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectRasterizerVariable*, AsRasterizer)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsRasterizer";
-
- if (!pType->IsObjectType(EOT_Rasterizer))
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidRasterizerVariable;
- }
-
- return (ID3DX11EffectRasterizerVariable *) this;
- }
-
- STDMETHOD_(ID3DX11EffectSamplerVariable*, AsSampler)()
- {
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsSampler";
-
- if (!pType->IsSampler())
- {
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidSamplerVariable;
- }
-
- return (ID3DX11EffectSamplerVariable *) this;
- }
-
- // Numeric variables should override this
- STDMETHOD(SetRawValue)(_In_reads_bytes_(Count) const void *pData, _In_ uint32_t Offset, _In_ uint32_t Count)
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return ObjectSetRawValue(); }
- STDMETHOD(GetRawValue)(_Out_writes_(Count) void *pData, _In_ uint32_t Offset, _In_ uint32_t Count)
- { UNREFERENCED_PARAMETER(pData); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Count); return ObjectGetRawValue(); }
-};
-
-//////////////////////////////////////////////////////////////////////////
-// TTopLevelVariable - functionality for annotations and global variables
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TTopLevelVariable : public SVariable, public IBaseInterface
-{
- // Required to create member/element variable interfaces
- CEffect *pEffect;
-
- CEffect* GetEffect()
- {
- return pEffect;
- }
-
- TTopLevelVariable() noexcept :
- pEffect(nullptr)
- {
- }
-
- uint32_t GetTotalUnpackedSize()
- {
- return ((SType*)pType)->GetTotalUnpackedSize(false);
- }
-
- STDMETHOD_(ID3DX11EffectType*, GetType)()
- {
- return (ID3DX11EffectType*)(SType*)pType;
- }
-
- TTopLevelVariable<ID3DX11EffectVariable> * GetTopLevelEntity()
- {
- return (TTopLevelVariable<ID3DX11EffectVariable> *)this;
- }
-
- bool IsArray()
- {
- return (pType->Elements > 0);
- }
-
-};
-
-//////////////////////////////////////////////////////////////////////////
-// TMember - functionality for structure/array members of other variables
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TMember : public SVariable, public IBaseInterface
-{
- // Indicates that this is a single element of a containing array
- uint32_t IsSingleElement : 1;
-
- // Required to create member/element variable interfaces
- TTopLevelVariable<ID3DX11EffectVariable> *pTopLevelEntity;
-
- TMember() noexcept :
- IsSingleElement(false),
- pTopLevelEntity(nullptr)
- {
- }
-
- CEffect* GetEffect()
- {
- return pTopLevelEntity->pEffect;
- }
-
- uint32_t GetTotalUnpackedSize()
- {
- return pType->GetTotalUnpackedSize(IsSingleElement);
- }
-
- STDMETHOD_(ID3DX11EffectType*, GetType)() override
- {
- if (IsSingleElement)
- {
- return pTopLevelEntity->pEffect->CreatePooledSingleElementTypeInterface( pType );
- }
- else
- {
- return (ID3DX11EffectType*) pType;
- }
- }
-
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override
- {
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetDesc";
-
- VERIFYPARAMETER(pDesc != nullptr);
-
- pDesc->Name = pName;
- pDesc->Semantic = pSemantic;
- pDesc->Flags = 0;
-
- if (pTopLevelEntity->pEffect->IsReflectionData(pTopLevelEntity))
- {
- // Is part of an annotation
- assert(pTopLevelEntity->pEffect->IsReflectionData(Data.pGeneric));
- pDesc->Annotations = 0;
- pDesc->BufferOffset = 0;
- pDesc->Flags |= D3DX11_EFFECT_VARIABLE_ANNOTATION;
- }
- else
- {
- // Is part of a global variable
- assert(pTopLevelEntity->pEffect->IsRuntimeData(pTopLevelEntity));
- if (!pTopLevelEntity->pType->IsObjectType(EOT_String))
- {
- // strings are funny; their data is reflection data, so ignore those
- assert(pTopLevelEntity->pEffect->IsRuntimeData(Data.pGeneric));
- }
-
- pDesc->Annotations = ((TGlobalVariable<ID3DX11Effect>*)pTopLevelEntity)->AnnotationCount;
-
- SConstantBuffer *pCB = ((TGlobalVariable<ID3DX11Effect>*)pTopLevelEntity)->pCB;
-
- if (pType->BelongsInConstantBuffer())
- {
- assert(pCB != 0);
- _Analysis_assume_(pCB != 0);
- UINT_PTR offset = Data.pNumeric - pCB->pBackingStore;
- assert(offset == (uint32_t)offset);
- pDesc->BufferOffset = (uint32_t)offset;
- assert(pDesc->BufferOffset >= 0 && pDesc->BufferOffset + GetTotalUnpackedSize() <= pCB->Size);
- }
- else
- {
- assert(pCB == nullptr);
- pDesc->BufferOffset = 0;
- }
- }
-
-lExit:
- return hr;
- }
-
- TTopLevelVariable<ID3DX11EffectVariable> * GetTopLevelEntity()
- {
- return pTopLevelEntity;
- }
-
- bool IsArray()
- {
- return (pType->Elements > 0 && !IsSingleElement);
- }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override
- { return pTopLevelEntity->GetAnnotationByIndex(Index); }
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override
- { return pTopLevelEntity->GetAnnotationByName(Name); }
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override
- { return pTopLevelEntity->GetParentConstantBuffer(); }
-
- // Annotations should never be able to go down this codepath
- void DirtyVariable()
- {
- // make sure to call the global variable's version of dirty variable
- ((TGlobalVariable<ID3DX11EffectVariable>*)pTopLevelEntity)->DirtyVariable();
- }
-};
-
-//////////////////////////////////////////////////////////////////////////
-// TAnnotation - functionality for top level annotations
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TAnnotation : public TVariable<TTopLevelVariable<IBaseInterface> >
-{
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) override
- {
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetDesc";
-
- VERIFYPARAMETER(pDesc != nullptr);
-
- pDesc->Name = pName;
- pDesc->Semantic = pSemantic;
- pDesc->Flags = D3DX11_EFFECT_VARIABLE_ANNOTATION;
- pDesc->Annotations = 0;
- pDesc->BufferOffset = 0;
- pDesc->ExplicitBindPoint = 0;
-
-lExit:
- return hr;
-
- }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index) override
- {
- UNREFERENCED_PARAMETER(Index);
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetAnnotationByIndex";
- DPF(0, "%s: Only variables may have annotations", pFuncName);
- return &g_InvalidScalarVariable;
- }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name) override
- {
- UNREFERENCED_PARAMETER(Name);
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetAnnotationByName";
- DPF(0, "%s: Only variables may have annotations", pFuncName);
- return &g_InvalidScalarVariable;
- }
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)() override
- { return NoParentCB(); }
-
- void DirtyVariable()
- {
- assert(0);
- }
-};
-
-//////////////////////////////////////////////////////////////////////////
-// TGlobalVariable - functionality for top level global variables
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TGlobalVariable : public TVariable<TTopLevelVariable<IBaseInterface> >
-{
- Timer LastModifiedTime;
-
- // if numeric, pointer to the constant buffer where this variable lives
- SConstantBuffer *pCB;
-
- uint32_t AnnotationCount;
- SAnnotation *pAnnotations;
-
- TGlobalVariable() noexcept :
- LastModifiedTime(0),
- pCB(nullptr),
- AnnotationCount(0),
- pAnnotations(nullptr)
- {
- }
-
- STDMETHOD(GetDesc)(_Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc)
- {
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetDesc";
-
- VERIFYPARAMETER(pDesc != nullptr);
-
- pDesc->Name = pName;
- pDesc->Semantic = pSemantic;
- pDesc->Flags = 0;
- pDesc->Annotations = AnnotationCount;
-
- if (pType->BelongsInConstantBuffer())
- {
- assert(pCB != 0);
- _Analysis_assume_(pCB != 0);
- UINT_PTR offset = Data.pNumeric - pCB->pBackingStore;
- assert(offset == (uint32_t)offset);
- pDesc->BufferOffset = (uint32_t)offset;
- assert(pDesc->BufferOffset >= 0 && pDesc->BufferOffset + GetTotalUnpackedSize() <= pCB->Size );
- }
- else
- {
- assert(pCB == nullptr);
- pDesc->BufferOffset = 0;
- }
-
- if (ExplicitBindPoint != -1)
- {
- pDesc->ExplicitBindPoint = ExplicitBindPoint;
- pDesc->Flags |= D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT;
- }
- else
- {
- pDesc->ExplicitBindPoint = 0;
- }
-
-lExit:
- return hr;
- }
-
- // these are all well defined for global vars
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(_In_ uint32_t Index)
- {
- return GetAnnotationByIndexHelper("ID3DX11EffectVariable", Index, AnnotationCount, pAnnotations);
- }
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(_In_z_ LPCSTR Name)
- {
- return GetAnnotationByNameHelper("ID3DX11EffectVariable", Name, AnnotationCount, pAnnotations);
- }
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)()
- {
- if (nullptr != pCB)
- {
- assert(pType->BelongsInConstantBuffer());
- return (ID3DX11EffectConstantBuffer*)pCB;
- }
- else
- {
- assert(!pType->BelongsInConstantBuffer());
- return &g_InvalidConstantBuffer;
- }
- }
-
- inline void DirtyVariable()
- {
- assert(pCB != 0);
- _Analysis_assume_(pCB != 0);
- pCB->IsDirty = true;
- LastModifiedTime = pEffect->GetCurrentTime();
- }
-
-};
-
-//////////////////////////////////////////////////////////////////////////
-// TNumericVariable - implements raw set/get functionality
-//////////////////////////////////////////////////////////////////////////
-
-// IMPORTANT NOTE: All of these numeric & object aspect classes MUST NOT
-// add data members to the base variable classes. Otherwise type sizes
-// will disagree between object & numeric variables and we cannot eaily
-// create arrays of global variables using SGlobalVariable
-
-// Requires that IBaseInterface have SVariable's members, GetTotalUnpackedSize() and DirtyVariable()
-template<typename IBaseInterface, bool IsAnnotation>
-struct TNumericVariable : public IBaseInterface
-{
- STDMETHOD(SetRawValue)(_In_reads_bytes_(ByteCount) const void *pData, _In_ uint32_t ByteOffset, _In_ uint32_t ByteCount) override
- {
- if (IsAnnotation)
- {
- return AnnotationInvalidSetCall("ID3DX11EffectVariable::SetRawValue");
- }
- else
- {
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectVariable::SetRawValue";
-
- VERIFYPARAMETER(pData);
-
- if ((ByteOffset + ByteCount < ByteOffset) ||
- (ByteCount + (uint8_t*)pData < (uint8_t*)pData) ||
- ((ByteOffset + ByteCount) > GetTotalUnpackedSize()))
- {
- // overflow of some kind
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- DirtyVariable();
- memcpy(Data.pNumeric + ByteOffset, pData, ByteCount);
-
-lExit:
- return hr;
- }
- }
-
- STDMETHOD(GetRawValue)(_Out_writes_bytes_(ByteCount) void *pData, _In_ uint32_t ByteOffset, _In_ uint32_t ByteCount) override
- {
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectVariable::GetRawValue";
-
- VERIFYPARAMETER(pData);
-
- if ((ByteOffset + ByteCount < ByteOffset) ||
- (ByteCount + (uint8_t*)pData < (uint8_t*)pData) ||
- ((ByteOffset + ByteCount) > GetTotalUnpackedSize()))
- {
- // overflow of some kind
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- memcpy(pData, Data.pNumeric + ByteOffset, ByteCount);
-
-lExit:
- return hr;
- }
-};
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectScalarVariable (TFloatScalarVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface, bool IsAnnotation>
-struct TFloatScalarVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
-{
- STDMETHOD(SetFloat)(_In_ const float Value) override;
- STDMETHOD(GetFloat)(_Out_ float *pValue) override;
-
- STDMETHOD(SetFloatArray)(_In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetFloatArray)(_Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(SetInt)(_In_ const int Value) override;
- STDMETHOD(GetInt)(_Out_ int *pValue) override;
-
- STDMETHOD(SetIntArray)(_In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetIntArray)(_Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(SetBool)(_In_ const bool Value) override;
- STDMETHOD(GetBool)(_Out_ bool *pValue) override;
-
- STDMETHOD(SetBoolArray)(_In_reads_(Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetBoolArray)(_Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetFloat(float Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloat";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_Float, ETVT_Float, float, false>(Value, Data.pNumericFloat, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetFloat(float *pValue)
-{
- return CopyScalarValue<ETVT_Float, ETVT_Float, float, true>(*Data.pNumericFloat, pValue, "ID3DX11EffectScalarVariable::GetFloat");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetFloatArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloatArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_Float, ETVT_Float, float, float>(pData, Data.pNumericFloat, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetFloatArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Float, ETVT_Float, float, float>(Data.pNumericFloat, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetFloatArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetInt(const int Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetInt";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_Int, ETVT_Float, int, false>(Value, Data.pNumericFloat, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetInt(int *pValue)
-{
- return CopyScalarValue<ETVT_Float, ETVT_Int, float, true>(*Data.pNumericFloat, pValue, "ID3DX11EffectScalarVariable::GetInt");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetIntArray(const int *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetIntArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_Int, ETVT_Float, int, float>(pData, Data.pNumericFloat, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetIntArray(int *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Float, ETVT_Int, float, int>(Data.pNumericFloat, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetIntArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetBool(const bool Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBool";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_bool, ETVT_Float, bool, false>(Value, Data.pNumericFloat, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)
-{
- return CopyScalarValue<ETVT_Float, ETVT_bool, float, true>(*Data.pNumericFloat, pValue, "ID3DX11EffectScalarVariable::GetBool");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::SetBoolArray(const bool *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBoolArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_bool, ETVT_Float, bool, float>(pData, Data.pNumericFloat, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Float, ETVT_bool, float, bool>(Data.pNumericFloat, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetBoolArray");
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectScalarVariable (TIntScalarVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface, bool IsAnnotation>
-struct TIntScalarVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
-{
- STDMETHOD(SetFloat)(_In_ const float Value) override;
- STDMETHOD(GetFloat)(_Out_ float *pValue) override;
-
- STDMETHOD(SetFloatArray)(_In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetFloatArray)(_Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(SetInt)(_In_ const int Value) override;
- STDMETHOD(GetInt)(_Out_ int *pValue) override;
-
- STDMETHOD(SetIntArray)(_In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetIntArray)(_Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(SetBool)(_In_ const bool Value) override;
- STDMETHOD(GetBool)(_Out_ bool *pValue) override;
-
- STDMETHOD(SetBoolArray)(_In_reads_(Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetBoolArray)(_Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetFloat(float Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloat";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_Float, ETVT_Int, float, false>(Value, Data.pNumericInt, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetFloat(float *pValue)
-{
- return CopyScalarValue<ETVT_Int, ETVT_Float, int, true>(*Data.pNumericInt, pValue, "ID3DX11EffectScalarVariable::GetFloat");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetFloatArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloatArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_Float, ETVT_Int, float, int>(pData, Data.pNumericInt, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetFloatArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Int, ETVT_Float, int, float>(Data.pNumericInt, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetFloatArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetInt(const int Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetInt";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_Int, ETVT_Int, int, false>(Value, Data.pNumericInt, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetInt(int *pValue)
-{
- return CopyScalarValue<ETVT_Int, ETVT_Int, int, true>(*Data.pNumericInt, pValue, "ID3DX11EffectScalarVariable::GetInt");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetIntArray(const int *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetIntArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_Int, ETVT_Int, int, int>(pData, Data.pNumericInt, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetIntArray(int *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Int, ETVT_Int, int, int>(Data.pNumericInt, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetIntArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetBool(const bool Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBool";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_bool, ETVT_Int, bool, false>(Value, Data.pNumericInt, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)
-{
- return CopyScalarValue<ETVT_Int, ETVT_bool, int, true>(*Data.pNumericInt, pValue, "ID3DX11EffectScalarVariable::GetBool");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetBoolArray(const bool *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBoolArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_bool, ETVT_Int, bool, int>(pData, Data.pNumericInt, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Int, ETVT_bool, int, bool>(Data.pNumericInt, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetBoolArray");
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectScalarVariable (TBoolScalarVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface, bool IsAnnotation>
-struct TBoolScalarVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
-{
- STDMETHOD(SetFloat)(_In_ const float Value) override;
- STDMETHOD(GetFloat)(_Out_ float *pValue) override;
-
- STDMETHOD(SetFloatArray)(_In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetFloatArray)(_Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(SetInt)(_In_ const int Value) override;
- STDMETHOD(GetInt)(_Out_ int *pValue) override;
-
- STDMETHOD(SetIntArray)(_In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetIntArray)(_Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(SetBool)(_In_ const bool Value) override;
- STDMETHOD(GetBool)(_Out_ bool *pValue) override;
-
- STDMETHOD(SetBoolArray)(_In_reads_(Count) const bool *pData, uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetBoolArray)(_Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetFloat(float Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloat";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_Float, ETVT_Bool, float, false>(Value, Data.pNumericBool, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetFloat(float *pValue)
-{
- return CopyScalarValue<ETVT_Bool, ETVT_Float, BOOL, true>(*Data.pNumericBool, pValue, "ID3DX11EffectScalarVariable::GetFloat");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetFloatArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloatArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_Float, ETVT_Bool, float, BOOL>(pData, Data.pNumericBool, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetFloatArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Bool, ETVT_Float, BOOL, float>(Data.pNumericBool, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetFloatArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetInt(const int Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetInt";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_Int, ETVT_Bool, int, false>(Value, Data.pNumericBool, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetInt(int *pValue)
-{
- return CopyScalarValue<ETVT_Bool, ETVT_Int, BOOL, true>(*Data.pNumericBool, pValue, "ID3DX11EffectScalarVariable::GetInt");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetIntArray(const int *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetIntArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_Int, ETVT_Bool, int, BOOL>(pData, Data.pNumericBool, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetIntArray(int *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Bool, ETVT_Int, BOOL, int>(Data.pNumericBool, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetIntArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetBool(const bool Value)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBool";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return CopyScalarValue<ETVT_bool, ETVT_Bool, bool, false>(Value, Data.pNumericBool, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)
-{
- return CopyScalarValue<ETVT_Bool, ETVT_bool, BOOL, true>(*Data.pNumericBool, pValue, "ID3DX11EffectScalarVariable::GetBool");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::SetBoolArray(const bool *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetBoolArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return SetScalarArray<ETVT_bool, ETVT_Bool, bool, BOOL>(pData, Data.pNumericBool, Offset, Count,
- pType, GetTotalUnpackedSize(), pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)
-{
- return GetScalarArray<ETVT_Bool, ETVT_bool, BOOL, bool>(Data.pNumericBool, pData, Offset, Count,
- pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetBoolArray");
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectVectorVariable (TVectorVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType >
-struct TVectorVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
-{
- STDMETHOD(SetBoolVector) (_In_reads_(4) const bool *pData) override;
- STDMETHOD(SetIntVector) (_In_reads_(4) const int *pData) override;
- STDMETHOD(SetFloatVector)(_In_reads_(4) const float *pData) override;
-
- STDMETHOD(GetBoolVector) (_Out_writes_(4) bool *pData) override;
- STDMETHOD(GetIntVector) (_Out_writes_(4) int *pData) override;
- STDMETHOD(GetFloatVector)(_Out_writes_(4) float *pData) override;
-
-
- STDMETHOD(SetBoolVectorArray) (_In_reads_(Count*4) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(SetIntVectorArray) (_In_reads_(Count*4) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(SetFloatVectorArray)(_In_reads_(Count*4) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(GetBoolVectorArray) (_Out_writes_(Count*4) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetIntVectorArray) (_Out_writes_(Count*4) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetFloatVectorArray)(_Out_writes_(Count*4) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-// Note that branches in this code is based on template parameters and will be compiled out
-#pragma warning (push)
-#pragma warning (disable : 6101)
-template <ETemplateVarType DestType, ETemplateVarType SourceType>
-void __forceinline CopyDataWithTypeConversion(_Out_ void *pDest,
- _In_ const void *pSource,
- _In_ size_t dstVecSize, _In_ size_t srcVecSize,
- _In_ size_t elementCount, _In_ size_t vecCount)
-{
- switch (SourceType)
- {
- case ETVT_Bool:
- switch (DestType)
- {
- case ETVT_Bool:
- for (size_t j=0; j<vecCount; j++)
- {
- memcpy(pDest, pSource, elementCount * SType::c_ScalarSize);
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_Int:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((int*)pDest)[i] = ((bool*)pSource)[i] ? -1 : 0;
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_Float:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((float*)pDest)[i] = ((bool*)pSource)[i] ? -1.0f : 0.0f;
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_bool:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((bool*)pDest)[i] = (((int*)pSource)[i] != 0) ? true : false;
-
- pDest = ((bool*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- default:
- assert(0);
- }
- break;
-
- case ETVT_Int:
- switch (DestType)
- {
- case ETVT_Bool:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((int*)pDest)[i] = (((int*)pSource)[i] != 0) ? -1 : 0;
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_Int:
- for (size_t j=0; j<vecCount; j++)
- {
- memcpy(pDest, pSource, elementCount * SType::c_ScalarSize);
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_Float:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((float*)pDest)[i] = (float)(((int*)pSource)[i]);
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_bool:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((bool*)pDest)[i] = (((int*)pSource)[i] != 0) ? true : false;
-
- pDest = ((bool*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- default:
- assert(0);
- }
- break;
-
- case ETVT_Float:
- switch (DestType)
- {
- case ETVT_Bool:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((int*)pDest)[i] = (((float*)pSource)[i] != 0.0f) ? -1 : 0;
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_Int:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((int*)pDest)[i] = (int)((float*)pSource)[i];
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_Float:
- for (size_t i=0; i<vecCount; i++)
- {
- memcpy( pDest, pSource, elementCount * SType::c_ScalarSize);
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_bool:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- ((bool*)pDest)[i] = (((float*)pSource)[i] != 0.0f) ? true : false;
-
- pDest = ((bool*) pDest) + dstVecSize;
- pSource = ((float*) pSource) + srcVecSize;
- }
- break;
-
- default:
- assert(0);
- }
- break;
-
- case ETVT_bool:
- switch (DestType)
- {
- case ETVT_Bool:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- reinterpret_cast<int*>(pDest)[i] = reinterpret_cast<const bool*>(pSource)[i] ? -1 : 0;
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((bool*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_Int:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- reinterpret_cast<int*>(pDest)[i] = reinterpret_cast<const bool*>(pSource)[i] ? -1 : 0;
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((bool*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_Float:
- for (size_t j=0; j<vecCount; j++)
- {
- for (size_t i=0; i<elementCount; i++)
- reinterpret_cast<float*>(pDest)[i] = reinterpret_cast<const bool*>(pSource)[i] ? -1.0f : 0.0f;
-
- pDest = ((float*) pDest) + dstVecSize;
- pSource = ((bool*) pSource) + srcVecSize;
- }
- break;
-
- case ETVT_bool:
- for (size_t j=0; j<vecCount; j++)
- {
- memcpy(pDest, pSource, elementCount);
-
- pDest = ((bool*) pDest) + dstVecSize;
- pSource = ((bool*) pSource) + srcVecSize;
- }
- break;
-
- default:
- assert(0);
- }
- break;
-
- default:
- assert(0);
- }
-}
-#pragma warning (pop)
-
-// Float Vector
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType >::SetFloatVector(const float *pData)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetFloatVector";
-
-#ifdef _DEBUG
- VERIFYPARAMETER(pData);
-#endif
-
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- CopyDataWithTypeConversion<BaseType, ETVT_Float>(Data.pVector, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, 1);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetFloatVector(float *pData)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetFloatVector";
-
-#ifdef _DEBUG
- VERIFYPARAMETER(pData);
-#endif
-
- CopyDataWithTypeConversion<ETVT_Float, BaseType>(pData, Data.pVector, pType->NumericType.Columns, 4, pType->NumericType.Columns, 1);
-
-lExit:
- return hr;
-}
-
-// Int Vector
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType >::SetIntVector(const int *pData)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetIntVector";
-
-#ifdef _DEBUG
- VERIFYPARAMETER(pData);
-#endif
-
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- CopyDataWithTypeConversion<BaseType, ETVT_Int>(Data.pVector, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, 1);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetIntVector(int *pData)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetIntVector";
- VERIFYPARAMETER(pData);
-#endif
-
- CopyDataWithTypeConversion<ETVT_Int, BaseType>(pData, Data.pVector, pType->NumericType.Columns, 4, pType->NumericType.Columns, 1);
-
-lExit:
- return hr;
-}
-
-// Bool Vector
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType >::SetBoolVector(const bool *pData)
-{
- HRESULT hr = S_OK;
-
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetBoolVector";
-
-#ifdef _DEBUG
- VERIFYPARAMETER(pData);
-#endif
-
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- CopyDataWithTypeConversion<BaseType, ETVT_bool>(Data.pVector, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, 1);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetBoolVector(bool *pData)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetBoolVector";
- VERIFYPARAMETER(pData);
-#endif
-
- CopyDataWithTypeConversion<ETVT_bool, BaseType>(pData, Data.pVector, pType->NumericType.Columns, 4, pType->NumericType.Columns, 1);
-
-lExit:
- return hr;
-}
-
-// Vector Arrays /////////////////////////////////////////////////////////
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::SetFloatVectorArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetFloatVectorArray";
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- // ensure we don't write over the padding at the end of the vector array
- CopyDataWithTypeConversion<BaseType, ETVT_Float>(Data.pVector + Offset, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetFloatVectorArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetFloatVectorArray";
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- // ensure we don't read past the end of the vector array
- CopyDataWithTypeConversion<ETVT_Float, BaseType>(pData, Data.pVector + Offset, pType->NumericType.Columns, 4, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
-
-lExit:
- return hr;
-}
-
-// int
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::SetIntVectorArray(const int *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetIntVectorArray";
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- // ensure we don't write over the padding at the end of the vector array
- CopyDataWithTypeConversion<BaseType, ETVT_Int>(Data.pVector + Offset, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetIntVectorArray(int *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetIntVectorArray";
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- // ensure we don't read past the end of the vector array
- CopyDataWithTypeConversion<ETVT_Int, BaseType>(pData, Data.pVector + Offset, pType->NumericType.Columns, 4, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
-
-lExit:
- return hr;
-}
-
-// bool
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::SetBoolVectorArray(const bool *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetBoolVectorArray";
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- // ensure we don't write over the padding at the end of the vector array
- CopyDataWithTypeConversion<BaseType, ETVT_bool>(Data.pVector + Offset, pData, 4, pType->NumericType.Columns, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface, bool IsAnnotation, ETemplateVarType BaseType>
-_Use_decl_annotations_
-HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetBoolVectorArray(bool *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetBoolVectorArray";
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- // ensure we don't read past the end of the vector array
- CopyDataWithTypeConversion<ETVT_bool, BaseType>(pData, Data.pVector + Offset, pType->NumericType.Columns, 4, pType->NumericType.Columns, std::max(std::min((int)Count, (int)pType->Elements - (int)Offset), 0));
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectVector4Variable (TVectorVariable implementation) [OPTIMIZED]
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TVector4Variable : public TVectorVariable<IBaseInterface, false, ETVT_Float>
-{
- STDMETHOD(SetFloatVector)(_In_reads_(4) const float *pData) override;
- STDMETHOD(GetFloatVector)(_Out_writes_(4) float *pData) override;
-
- STDMETHOD(SetFloatVectorArray)(_In_reads_(Count*4) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetFloatVectorArray)(_Out_writes_(Count*4) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TVector4Variable<IBaseInterface>::SetFloatVector(const float *pData)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetFloatVector";
-
-#ifdef _DEBUG
- VERIFYPARAMETER(pData);
-#endif
-
- DirtyVariable();
- Data.pVector[0] = ((CEffectVector4*) pData)[0];
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TVector4Variable<IBaseInterface>::GetFloatVector(float *pData)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetFloatVector";
-
-#ifdef _DEBUG
- VERIFYPARAMETER(pData);
-#endif
-
- memcpy(pData, Data.pVector, pType->NumericType.Columns * SType::c_ScalarSize);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TVector4Variable<IBaseInterface>::SetFloatVectorArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::SetFloatVectorArray";
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- DirtyVariable();
- // ensure we don't write over the padding at the end of the vector array
- memcpy(Data.pVector + Offset, pData,
- std::min<size_t>(Count * sizeof(CEffectVector4), pType->TotalSize - (Offset * sizeof(CEffectVector4))));
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TVector4Variable<IBaseInterface>::GetFloatVectorArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectVectorVariable::GetFloatVectorArray";
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pData, pType, GetTotalUnpackedSize()))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#endif
-
- // ensure we don't read past the end of the vector array
- memcpy(pData, Data.pVector + Offset,
- std::min<size_t>(Count * sizeof(CEffectVector4), pType->TotalSize - (Offset * sizeof(CEffectVector4))));
-
-lExit:
- return hr;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectMatrixVariable (TMatrixVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface, bool IsAnnotation>
-struct TMatrixVariable : public TNumericVariable<IBaseInterface, IsAnnotation>
-{
- STDMETHOD(SetMatrix)(_In_reads_(16) const float *pData) override;
- STDMETHOD(GetMatrix)(_Out_writes_(16) float *pData) override;
-
- STDMETHOD(SetMatrixArray)(_In_reads_(Count*16) const float *pData, uint32_t Offset, uint32_t Count) override;
- STDMETHOD(GetMatrixArray)(_Out_writes_(Count*16) float *pData, uint32_t Offset, uint32_t Count) override;
-
- STDMETHOD(SetMatrixPointerArray)(_In_reads_(Count*16) const float **ppData, uint32_t Offset, uint32_t Count) override;
- STDMETHOD(GetMatrixPointerArray)(_Out_writes_(Count*16) float **ppData, uint32_t Offset, uint32_t Count) override;
-
- STDMETHOD(SetMatrixTranspose)(_In_reads_(16) const float *pData) override;
- STDMETHOD(GetMatrixTranspose)(_Out_writes_(16) float *pData) override;
-
- STDMETHOD(SetMatrixTransposeArray)(_In_reads_(Count*16) const float *pData, uint32_t Offset, uint32_t Count) override;
- STDMETHOD(GetMatrixTransposeArray)(_Out_writes_(Count*16) float *pData, uint32_t Offset, uint32_t Count) override;
-
- STDMETHOD(SetMatrixTransposePointerArray)(_In_reads_(Count*16) const float **ppData, uint32_t Offset, uint32_t Count) override;
- STDMETHOD(GetMatrixTransposePointerArray)(_Out_writes_(Count*16) float **ppData, uint32_t Offset, uint32_t Count) override;
-};
-
-#pragma warning (push)
-#pragma warning (disable : 6101)
-template<bool Transpose>
-static void SetMatrixTransposeHelper(_In_ const SType *pType, _Out_writes_bytes_(64) uint8_t *pDestData, _In_reads_(16) const float* pMatrix)
-{
- uint32_t registers, entries;
-
- if (Transpose)
- {
- // row major
- registers = pType->NumericType.Rows;
- entries = pType->NumericType.Columns;
- }
- else
- {
- // column major
- registers = pType->NumericType.Columns;
- entries = pType->NumericType.Rows;
- }
- _Analysis_assume_( registers <= 4 );
- _Analysis_assume_( entries <= 4 );
-
- for (size_t i = 0; i < registers; ++ i)
- {
- for (size_t j = 0; j < entries; ++ j)
- {
-#pragma prefast(suppress:__WARNING_UNRELATED_LOOP_TERMINATION, "regs / entries <= 4")
- ((float*)pDestData)[j] = ((float*)pMatrix)[j * 4 + i];
- }
- pDestData += SType::c_RegisterSize;
- }
-}
-
-template<bool Transpose>
-static void GetMatrixTransposeHelper(_In_ const SType *pType, _In_reads_bytes_(64) uint8_t *pSrcData, _Out_writes_(16) float* pMatrix)
-{
- uint32_t registers, entries;
-
- if (Transpose)
- {
- // row major
- registers = pType->NumericType.Rows;
- entries = pType->NumericType.Columns;
- }
- else
- {
- // column major
- registers = pType->NumericType.Columns;
- entries = pType->NumericType.Rows;
- }
- _Analysis_assume_( registers <= 4 );
- _Analysis_assume_( entries <= 4 );
-
- for (size_t i = 0; i < registers; ++ i)
- {
- for (size_t j = 0; j < entries; ++ j)
- {
- ((float*)pMatrix)[j * 4 + i] = ((float*)pSrcData)[j];
- }
- pSrcData += SType::c_RegisterSize;
- }
-}
-
-template<bool Transpose, bool IsSetting, bool ExtraIndirection>
-HRESULT DoMatrixArrayInternal(_In_ const SType *pType, _In_ uint32_t TotalUnpackedSize,
- _Out_ uint8_t *pEffectData,
- void *pMatrixData,
- _In_ uint32_t Offset, _In_ uint32_t Count, _In_z_ LPCSTR pFuncName)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pMatrixData, pType, TotalUnpackedSize))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-#else
- UNREFERENCED_PARAMETER(TotalUnpackedSize);
- UNREFERENCED_PARAMETER(pFuncName);
-#endif
-
- if ((pType->NumericType.IsColumnMajor && Transpose) || (!pType->NumericType.IsColumnMajor && !Transpose))
- {
- // fast path
- uint32_t dataSize;
- if (Transpose)
- {
- dataSize = ((pType->NumericType.Columns - 1) * 4 + pType->NumericType.Rows) * SType::c_ScalarSize;
- }
- else
- {
- dataSize = ((pType->NumericType.Rows - 1) * 4 + pType->NumericType.Columns) * SType::c_ScalarSize;
- }
-
- for (size_t i = 0; i < Count; ++ i)
- {
- CEffectMatrix *pMatrix;
- if (ExtraIndirection)
- {
- pMatrix = ((CEffectMatrix **)pMatrixData)[i];
- if (!pMatrix)
- {
- continue;
- }
- }
- else
- {
- pMatrix = ((CEffectMatrix *)pMatrixData) + i;
- }
-
- if (IsSetting)
- {
- memcpy(pEffectData + pType->Stride * (i + Offset), pMatrix, dataSize);
- }
- else
- {
- memcpy(pMatrix, pEffectData + pType->Stride * (i + Offset), dataSize);
- }
- }
- }
- else
- {
- // slow path
- for (size_t i = 0; i < Count; ++ i)
- {
- CEffectMatrix *pMatrix;
- if (ExtraIndirection)
- {
- pMatrix = ((CEffectMatrix **)pMatrixData)[i];
- if (!pMatrix)
- {
- continue;
- }
- }
- else
- {
- pMatrix = ((CEffectMatrix *)pMatrixData) + i;
- }
-
- if (IsSetting)
- {
- SetMatrixTransposeHelper<Transpose>(pType, pEffectData + pType->Stride * (i + Offset), (float*) pMatrix);
- }
- else
- {
- GetMatrixTransposeHelper<Transpose>(pType, pEffectData + pType->Stride * (i + Offset), (float*) pMatrix);
- }
- }
- }
-
-lExit:
- return hr;
-}
-#pragma warning (pop)
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrix(const float *pData)
-{
- static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrix";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return DoMatrixArrayInternal<false, true, false>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, const_cast<float*>(pData), 0, 1, pFuncName);
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrix(float *pData)
-{
- return DoMatrixArrayInternal<false, false, false>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, pData, 0, 1, "ID3DX11EffectMatrixVariable::GetMatrix");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return DoMatrixArrayInternal<false, true, false>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, const_cast<float*>(pData), Offset, Count, "ID3DX11EffectMatrixVariable::SetMatrixArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- return DoMatrixArrayInternal<false, false, false>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, pData, Offset, Count, "ID3DX11EffectMatrixVariable::GetMatrixArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixPointerArray(const float **ppData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixPointerArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return DoMatrixArrayInternal<false, true, true>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, const_cast<float**>(ppData), Offset, Count, "ID3DX11EffectMatrixVariable::SetMatrixPointerArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixPointerArray(float **ppData, uint32_t Offset, uint32_t Count)
-{
- return DoMatrixArrayInternal<false, false, true>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, ppData, Offset, Count, "ID3DX11EffectMatrixVariable::GetMatrixPointerArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixTranspose(const float *pData)
-{
- static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixTranspose";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return DoMatrixArrayInternal<true, true, false>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, const_cast<float*>(pData), 0, 1, "ID3DX11EffectMatrixVariable::SetMatrixTranspose");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixTranspose(float *pData)
-{
- return DoMatrixArrayInternal<true, false, false>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, pData, 0, 1, "ID3DX11EffectMatrixVariable::GetMatrixTranspose");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixTransposeArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixTransposeArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return DoMatrixArrayInternal<true, true, false>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, const_cast<float*>(pData), Offset, Count, "ID3DX11EffectMatrixVariable::SetMatrixTransposeArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixTransposeArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- return DoMatrixArrayInternal<true, false, false>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, pData, Offset, Count, "ID3DX11EffectMatrixVariable::GetMatrixTransposeArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::SetMatrixTransposePointerArray(const float **ppData, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectMatrixVariable::SetMatrixTransposePointerArray";
- if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
- DirtyVariable();
- return DoMatrixArrayInternal<true, true, true>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, const_cast<float**>(ppData), Offset, Count, "ID3DX11EffectMatrixVariable::SetMatrixTransposePointerArray");
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TMatrixVariable<IBaseInterface, IsAnnotation>::GetMatrixTransposePointerArray(float **ppData, uint32_t Offset, uint32_t Count)
-{
- return DoMatrixArrayInternal<true, false, true>(pType, GetTotalUnpackedSize(),
- Data.pNumeric, ppData, Offset, Count, "ID3DX11EffectMatrixVariable::GetMatrixTransposePointerArray");
-}
-
-// Optimize commonly used fast paths
-// (non-annotations only!)
-template<typename IBaseInterface, bool IsColumnMajor>
-struct TMatrix4x4Variable : public TMatrixVariable<IBaseInterface, false>
-{
- STDMETHOD(SetMatrix)(_In_reads_(16) const float *pData) override;
- STDMETHOD(GetMatrix)(_Out_writes_(16) float *pData) override;
-
- STDMETHOD(SetMatrixArray)(_In_reads_(16*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetMatrixArray)(_Out_writes_(16*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-
- STDMETHOD(SetMatrixTranspose)(_In_reads_(16) const float *pData) override;
- STDMETHOD(GetMatrixTranspose)(_Out_writes_(16) float *pData) override;
-
- STDMETHOD(SetMatrixTransposeArray)(_In_reads_(16*Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetMatrixTransposeArray)(_Out_writes_(16*Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-inline static void Matrix4x4TransposeHelper(_In_reads_bytes_(64) const void *pSrc, _Out_writes_bytes_(64) void *pDst)
-{
- uint8_t *pDestData = (uint8_t*)pDst;
- uint32_t *pMatrix = (uint32_t*)pSrc;
-
- ((uint32_t*)pDestData)[0 * 4 + 0] = pMatrix[0 * 4 + 0];
- ((uint32_t*)pDestData)[0 * 4 + 1] = pMatrix[1 * 4 + 0];
- ((uint32_t*)pDestData)[0 * 4 + 2] = pMatrix[2 * 4 + 0];
- ((uint32_t*)pDestData)[0 * 4 + 3] = pMatrix[3 * 4 + 0];
-
- ((uint32_t*)pDestData)[1 * 4 + 0] = pMatrix[0 * 4 + 1];
- ((uint32_t*)pDestData)[1 * 4 + 1] = pMatrix[1 * 4 + 1];
- ((uint32_t*)pDestData)[1 * 4 + 2] = pMatrix[2 * 4 + 1];
- ((uint32_t*)pDestData)[1 * 4 + 3] = pMatrix[3 * 4 + 1];
-
- ((uint32_t*)pDestData)[2 * 4 + 0] = pMatrix[0 * 4 + 2];
- ((uint32_t*)pDestData)[2 * 4 + 1] = pMatrix[1 * 4 + 2];
- ((uint32_t*)pDestData)[2 * 4 + 2] = pMatrix[2 * 4 + 2];
- ((uint32_t*)pDestData)[2 * 4 + 3] = pMatrix[3 * 4 + 2];
-
- ((uint32_t*)pDestData)[3 * 4 + 0] = pMatrix[0 * 4 + 3];
- ((uint32_t*)pDestData)[3 * 4 + 1] = pMatrix[1 * 4 + 3];
- ((uint32_t*)pDestData)[3 * 4 + 2] = pMatrix[2 * 4 + 3];
- ((uint32_t*)pDestData)[3 * 4 + 3] = pMatrix[3 * 4 + 3];
-}
-
-inline static void Matrix4x4Copy(_In_reads_bytes_(64) const void *pSrc, _Out_writes_bytes_(64) void *pDst)
-{
-#if 1
- // In tests, this path ended up generating faster code both on x86 and x64
- // T1 - Matrix4x4Copy - this path
- // T2 - Matrix4x4Transpose
- // T1: 1.88 T2: 1.92 - with 32 bit copies
- // T1: 1.85 T2: 1.80 - with 64 bit copies
-
- uint64_t *pDestData = (uint64_t*)pDst;
- uint64_t *pMatrix = (uint64_t*)pSrc;
-
- pDestData[0 * 4 + 0] = pMatrix[0 * 4 + 0];
- pDestData[0 * 4 + 1] = pMatrix[0 * 4 + 1];
- pDestData[0 * 4 + 2] = pMatrix[0 * 4 + 2];
- pDestData[0 * 4 + 3] = pMatrix[0 * 4 + 3];
-
- pDestData[1 * 4 + 0] = pMatrix[1 * 4 + 0];
- pDestData[1 * 4 + 1] = pMatrix[1 * 4 + 1];
- pDestData[1 * 4 + 2] = pMatrix[1 * 4 + 2];
- pDestData[1 * 4 + 3] = pMatrix[1 * 4 + 3];
-#else
- uint32_t *pDestData = (uint32_t*)pDst;
- uint32_t *pMatrix = (uint32_t*)pSrc;
-
- pDestData[0 * 4 + 0] = pMatrix[0 * 4 + 0];
- pDestData[0 * 4 + 1] = pMatrix[0 * 4 + 1];
- pDestData[0 * 4 + 2] = pMatrix[0 * 4 + 2];
- pDestData[0 * 4 + 3] = pMatrix[0 * 4 + 3];
-
- pDestData[1 * 4 + 0] = pMatrix[1 * 4 + 0];
- pDestData[1 * 4 + 1] = pMatrix[1 * 4 + 1];
- pDestData[1 * 4 + 2] = pMatrix[1 * 4 + 2];
- pDestData[1 * 4 + 3] = pMatrix[1 * 4 + 3];
-
- pDestData[2 * 4 + 0] = pMatrix[2 * 4 + 0];
- pDestData[2 * 4 + 1] = pMatrix[2 * 4 + 1];
- pDestData[2 * 4 + 2] = pMatrix[2 * 4 + 2];
- pDestData[2 * 4 + 3] = pMatrix[2 * 4 + 3];
-
- pDestData[3 * 4 + 0] = pMatrix[3 * 4 + 0];
- pDestData[3 * 4 + 1] = pMatrix[3 * 4 + 1];
- pDestData[3 * 4 + 2] = pMatrix[3 * 4 + 2];
- pDestData[3 * 4 + 3] = pMatrix[3 * 4 + 3];
-#endif
-}
-
-
-// Note that branches in this code is based on template parameters and will be compiled out
-#pragma warning (push)
-#pragma warning (disable : 6101)
-template<bool IsColumnMajor, bool Transpose, bool IsSetting>
-inline HRESULT DoMatrix4x4ArrayInternal(_In_ uint8_t *pEffectData,
- _When_(IsSetting, _In_reads_bytes_(64 * Count))
- _When_(!IsSetting, _Out_writes_bytes_(64 * Count))
- void *pMatrixData,
- _In_ uint32_t Offset, _In_ uint32_t Count
-#ifdef _DEBUG
- , _In_ const SType *pType, _In_ uint32_t TotalUnpackedSize, _In_z_ LPCSTR pFuncName
-#endif
-
- )
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
-#pragma warning( suppress : 6001 )
- if (!AreBoundsValid(Offset, Count, pMatrixData, pType, TotalUnpackedSize))
- {
- DPF(0, "%s: Invalid range specified", pFuncName);
- VH(E_INVALIDARG);
- }
-
- assert(pType->NumericType.IsColumnMajor == IsColumnMajor && pType->Stride == (4 * SType::c_RegisterSize));
-#endif
-
- if ((IsColumnMajor && Transpose) || (!IsColumnMajor && !Transpose))
- {
- // fast path
- for (size_t i = 0; i < Count; ++ i)
- {
- CEffectMatrix *pMatrix = ((CEffectMatrix *)pMatrixData) + i;
-
- if (IsSetting)
- {
- Matrix4x4Copy(pMatrix, pEffectData + 4 * SType::c_RegisterSize * (i + Offset));
- }
- else
- {
- Matrix4x4Copy(pEffectData + 4 * SType::c_RegisterSize * (i + Offset), pMatrix);
- }
- }
- }
- else
- {
- // slow path
- for (size_t i = 0; i < Count; ++ i)
- {
- CEffectMatrix *pMatrix = ((CEffectMatrix *)pMatrixData) + i;
-
- if (IsSetting)
- {
- Matrix4x4TransposeHelper((float*) pMatrix, pEffectData + 4 * SType::c_RegisterSize * (i + Offset));
- }
- else
- {
- Matrix4x4TransposeHelper(pEffectData + 4 * SType::c_RegisterSize * (i + Offset), (float*) pMatrix);
- }
- }
- }
-
-lExit:
- return hr;
-}
-#pragma warning (pop)
-
-template<typename IBaseInterface, bool IsColumnMajor>
-_Use_decl_annotations_
-HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::SetMatrix(const float *pData)
-{
- DirtyVariable();
- return DoMatrix4x4ArrayInternal<IsColumnMajor, false, true>(Data.pNumeric, const_cast<float*>(pData), 0, 1
-#ifdef _DEBUG
- , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::SetMatrix");
-#else
- );
-#endif
-}
-
-template<typename IBaseInterface, bool IsColumnMajor>
-_Use_decl_annotations_
-HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::GetMatrix(float *pData)
-{
- return DoMatrix4x4ArrayInternal<IsColumnMajor, false, false>(Data.pNumeric, pData, 0, 1
-#ifdef _DEBUG
- , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::GetMatrix");
-#else
- );
-#endif
-}
-
-template<typename IBaseInterface, bool IsColumnMajor>
-_Use_decl_annotations_
-HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::SetMatrixArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- DirtyVariable();
- return DoMatrix4x4ArrayInternal<IsColumnMajor, false, true>(Data.pNumeric, const_cast<float*>(pData), Offset, Count
-#ifdef _DEBUG
- , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::SetMatrixArray");
-#else
- );
-#endif
-}
-
-template<typename IBaseInterface, bool IsColumnMajor>
-_Use_decl_annotations_
-HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::GetMatrixArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- return DoMatrix4x4ArrayInternal<IsColumnMajor, false, false>(Data.pNumeric, pData, Offset, Count
-#ifdef _DEBUG
- , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::GetMatrixArray");
-#else
- );
-#endif
-}
-
-template<typename IBaseInterface, bool IsColumnMajor>
-_Use_decl_annotations_
-HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::SetMatrixTranspose(const float *pData)
-{
- DirtyVariable();
- return DoMatrix4x4ArrayInternal<IsColumnMajor, true, true>(Data.pNumeric, const_cast<float*>(pData), 0, 1
-#ifdef _DEBUG
- , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::SetMatrixTranspose");
-#else
- );
-#endif
-}
-
-template<typename IBaseInterface, bool IsColumnMajor>
-_Use_decl_annotations_
-HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::GetMatrixTranspose(float *pData)
-{
- return DoMatrix4x4ArrayInternal<IsColumnMajor, true, false>(Data.pNumeric, pData, 0, 1
-#ifdef _DEBUG
- , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::GetMatrixTranspose");
-#else
- );
-#endif
-}
-
-template<typename IBaseInterface, bool IsColumnMajor>
-_Use_decl_annotations_
-HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::SetMatrixTransposeArray(const float *pData, uint32_t Offset, uint32_t Count)
-{
- DirtyVariable();
- return DoMatrix4x4ArrayInternal<IsColumnMajor, true, true>(Data.pNumeric, const_cast<float*>(pData), Offset, Count
-#ifdef _DEBUG
- , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::SetMatrixTransposeArray");
-#else
- );
-#endif
-}
-
-template<typename IBaseInterface, bool IsColumnMajor>
-_Use_decl_annotations_
-HRESULT TMatrix4x4Variable<IBaseInterface, IsColumnMajor>::GetMatrixTransposeArray(float *pData, uint32_t Offset, uint32_t Count)
-{
- return DoMatrix4x4ArrayInternal<IsColumnMajor, true, false>(Data.pNumeric, pData, Offset, Count
-#ifdef _DEBUG
- , pType, GetTotalUnpackedSize(), "ID3DX11EffectMatrixVariable::GetMatrixTransposeArray");
-#else
- );
-#endif
-}
-
-#ifdef _DEBUG
-
-// Useful object macro to check bounds and parameters
-#define CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, Pointer) \
- HRESULT hr = S_OK; \
- VERIFYPARAMETER(Pointer) \
- uint32_t elements = IsArray() ? pType->Elements : 1; \
- \
- if ((Offset + Count < Offset) || (elements < Offset + Count)) \
- { \
- DPF(0, "%s: Invalid range specified", pFuncName); \
- VH(E_INVALIDARG); \
- } \
-
-#define CHECK_OBJECT_SCALAR_BOUNDS(Index, Pointer) \
- HRESULT hr = S_OK; \
- VERIFYPARAMETER(Pointer) \
- uint32_t elements = IsArray() ? pType->Elements : 1; \
- \
- if (Index >= elements) \
- { \
- DPF(0, "%s: Invalid index specified", pFuncName); \
- VH(E_INVALIDARG); \
- } \
-
-#define CHECK_SCALAR_BOUNDS(Index) \
- HRESULT hr = S_OK; \
- uint32_t elements = IsArray() ? pType->Elements : 1; \
- \
- if (Index >= elements) \
-{ \
- DPF(0, "%s: Invalid index specified", pFuncName); \
- VH(E_INVALIDARG); \
-} \
-
-#else // _DEBUG
-
-#define CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, Pointer) \
- HRESULT hr = S_OK; \
-
-#define CHECK_OBJECT_SCALAR_BOUNDS(Index, Pointer) \
- HRESULT hr = S_OK; \
-
-#define CHECK_SCALAR_BOUNDS(Index) \
- HRESULT hr = S_OK; \
-
-#endif // _DEBUG
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectStringVariable (TStringVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface, bool IsAnnotation>
-struct TStringVariable : public IBaseInterface
-{
- STDMETHOD(GetString)(_Outptr_result_z_ LPCSTR *ppString) override;
- STDMETHOD(GetStringArray)( _Out_writes_(Count) LPCSTR *ppStrings, _In_ uint32_t Offset, _In_ uint32_t Count ) override;
-};
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-HRESULT TStringVariable<IBaseInterface, IsAnnotation>::GetString(LPCSTR *ppString)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectStringVariable::GetString";
-
- VERIFYPARAMETER(ppString);
-
- if (GetTopLevelEntity()->pEffect->IsOptimized())
- {
- DPF(0, "%s: Effect has been Optimize()'ed; all string/reflection data has been deleted", pFuncName);
- return D3DERR_INVALIDCALL;
- }
-
- assert(Data.pString != 0);
- _Analysis_assume_(Data.pString != 0);
-
- *ppString = Data.pString->pString;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface, bool IsAnnotation>
-_Use_decl_annotations_
-#pragma warning(suppress : 6054)
-HRESULT TStringVariable<IBaseInterface, IsAnnotation>::GetStringArray( LPCSTR *ppStrings, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectStringVariable::GetStringArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppStrings);
-
- if (GetTopLevelEntity()->pEffect->IsOptimized())
- {
- DPF(0, "%s: Effect has been Optimize()'ed; all string/reflection data has been deleted", pFuncName);
- return D3DERR_INVALIDCALL;
- }
-
- assert(Data.pString != 0);
- _Analysis_assume_(Data.pString != 0);
-
- for (size_t i = 0; i < Count; ++ i)
- {
- ppStrings[i] = (Data.pString + Offset + i)->pString;
- }
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectClassInstanceVariable (TClassInstanceVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TClassInstanceVariable : public IBaseInterface
-{
- STDMETHOD(GetClassInstance)(_Outptr_ ID3D11ClassInstance **ppClassInstance) override;
-};
-
-template<typename IBaseClassInstance>
-HRESULT TClassInstanceVariable<IBaseClassInstance>::GetClassInstance(_Outptr_ ID3D11ClassInstance** ppClassInstance)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectClassInstanceVariable::GetClassInstance";
-
- assert( pMemberData != 0 && pMemberData->Data.pD3DClassInstance != 0);
- _Analysis_assume_( pMemberData != 0 && pMemberData->Data.pD3DClassInstance != 0);
- *ppClassInstance = pMemberData->Data.pD3DClassInstance;
- SAFE_ADDREF(*ppClassInstance);
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectInterfaceeVariable (TInterfaceVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TInterfaceVariable : public IBaseInterface
-{
- STDMETHOD(SetClassInstance)(_In_ ID3DX11EffectClassInstanceVariable *pEffectClassInstance) override;
- STDMETHOD(GetClassInstance)(_Outptr_ ID3DX11EffectClassInstanceVariable **ppEffectClassInstance) override;
-};
-
-template<typename IBaseInterface>
-HRESULT TInterfaceVariable<IBaseInterface>::SetClassInstance(_In_ ID3DX11EffectClassInstanceVariable *pEffectClassInstance)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectInterfaceVariable::SetClassInstance";
-
- // Note that we don't check if the types are compatible. The debug layer will complain if it is.
- // IsValid() will not catch type mismatches.
- SClassInstanceGlobalVariable* pCI = (SClassInstanceGlobalVariable*)pEffectClassInstance;
- Data.pInterface->pClassInstance = pCI;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-HRESULT TInterfaceVariable<IBaseInterface>::GetClassInstance(_Outptr_ ID3DX11EffectClassInstanceVariable **ppEffectClassInstance)
-{
- HRESULT hr = S_OK;
- static LPCSTR pFuncName = "ID3DX11EffectInterfaceVariable::GetClassInstance";
-
-#ifdef _DEBUG
- VERIFYPARAMETER(ppEffectClassInstance);
-#endif
-
- *ppEffectClassInstance = Data.pInterface->pClassInstance;
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectShaderResourceVariable (TShaderResourceVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TShaderResourceVariable : public IBaseInterface
-{
- STDMETHOD(SetResource)(_In_ ID3D11ShaderResourceView *pResource) override;
- STDMETHOD(GetResource)(_Outptr_ ID3D11ShaderResourceView **ppResource) override;
-
- STDMETHOD(SetResourceArray)(_In_reads_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetResourceArray)(_Out_writes_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-static LPCSTR GetTextureTypeNameFromEnum(_In_ EObjectType ObjectType)
-{
- switch (ObjectType)
- {
- case EOT_Buffer:
- return "Buffer";
- case EOT_Texture:
- return "texture";
- case EOT_Texture1D:
- case EOT_Texture1DArray:
- return "Texture1D";
- case EOT_Texture2DMS:
- case EOT_Texture2DMSArray:
- return "Texture2DMS";
- case EOT_Texture2D:
- case EOT_Texture2DArray:
- return "Texture2D";
- case EOT_Texture3D:
- return "Texture3D";
- case EOT_TextureCube:
- return "TextureCube";
- case EOT_TextureCubeArray:
- return "TextureCubeArray";
- case EOT_RWTexture1D:
- case EOT_RWTexture1DArray:
- return "RWTexture1D";
- case EOT_RWTexture2D:
- case EOT_RWTexture2DArray:
- return "RWTexture2D";
- case EOT_RWTexture3D:
- return "RWTexture3D";
- case EOT_RWBuffer:
- return "RWBuffer";
- case EOT_ByteAddressBuffer:
- return "ByteAddressBuffer";
- case EOT_RWByteAddressBuffer:
- return "RWByteAddressBuffer";
- case EOT_StructuredBuffer:
- return "StructuredBuffe";
- case EOT_RWStructuredBuffer:
- return "RWStructuredBuffer";
- case EOT_RWStructuredBufferAlloc:
- return "RWStructuredBufferAlloc";
- case EOT_RWStructuredBufferConsume:
- return "RWStructuredBufferConsume";
- case EOT_AppendStructuredBuffer:
- return "AppendStructuredBuffer";
- case EOT_ConsumeStructuredBuffer:
- return "ConsumeStructuredBuffer";
- }
- return "<unknown texture format>";
-}
-
-static LPCSTR GetResourceDimensionNameFromEnum(_In_ D3D11_RESOURCE_DIMENSION ResourceDimension)
-{
- switch (ResourceDimension)
- {
- case D3D11_RESOURCE_DIMENSION_BUFFER:
- return "Buffer";
- case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
- return "Texture1D";
- case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
- return "Texture2D";
- case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
- return "Texture3D";
- }
- return "<unknown texture format>";
-}
-
-static LPCSTR GetSRVDimensionNameFromEnum(_In_ D3D11_SRV_DIMENSION ViewDimension)
-{
- switch (ViewDimension)
- {
- case D3D11_SRV_DIMENSION_BUFFER:
- case D3D11_SRV_DIMENSION_BUFFEREX:
- return "Buffer";
- case D3D11_SRV_DIMENSION_TEXTURE1D:
- return "Texture1D";
- case D3D11_SRV_DIMENSION_TEXTURE1DARRAY:
- return "Texture1DArray";
- case D3D11_SRV_DIMENSION_TEXTURE2D:
- return "Texture2D";
- case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
- return "Texture2DArray";
- case D3D11_SRV_DIMENSION_TEXTURE2DMS:
- return "Texture2DMS";
- case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY:
- return "Texture2DMSArray";
- case D3D11_SRV_DIMENSION_TEXTURE3D:
- return "Texture3D";
- case D3D11_SRV_DIMENSION_TEXTURECUBE:
- return "TextureCube";
- }
- return "<unknown texture format>";
-}
-
-static LPCSTR GetUAVDimensionNameFromEnum(_In_ D3D11_UAV_DIMENSION ViewDimension)
-{
- switch (ViewDimension)
- {
- case D3D11_UAV_DIMENSION_BUFFER:
- return "Buffer";
- case D3D11_UAV_DIMENSION_TEXTURE1D:
- return "RWTexture1D";
- case D3D11_UAV_DIMENSION_TEXTURE1DARRAY:
- return "RWTexture1DArray";
- case D3D11_UAV_DIMENSION_TEXTURE2D:
- return "RWTexture2D";
- case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
- return "RWTexture2DArray";
- case D3D11_UAV_DIMENSION_TEXTURE3D:
- return "RWTexture3D";
- }
- return "<unknown texture format>";
-}
-
-static LPCSTR GetRTVDimensionNameFromEnum(_In_ D3D11_RTV_DIMENSION ViewDimension)
-{
- switch (ViewDimension)
- {
- case D3D11_RTV_DIMENSION_BUFFER:
- return "Buffer";
- case D3D11_RTV_DIMENSION_TEXTURE1D:
- return "Texture1D";
- case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
- return "Texture1DArray";
- case D3D11_RTV_DIMENSION_TEXTURE2D:
- return "Texture2D";
- case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
- return "Texture2DArray";
- case D3D11_RTV_DIMENSION_TEXTURE2DMS:
- return "Texture2DMS";
- case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
- return "Texture2DMSArray";
- case D3D11_RTV_DIMENSION_TEXTURE3D:
- return "Texture3D";
- }
- return "<unknown texture format>";
-}
-
-static LPCSTR GetDSVDimensionNameFromEnum(_In_ D3D11_DSV_DIMENSION ViewDimension)
-{
- switch (ViewDimension)
- {
- case D3D11_DSV_DIMENSION_TEXTURE1D:
- return "Texture1D";
- case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
- return "Texture1DArray";
- case D3D11_DSV_DIMENSION_TEXTURE2D:
- return "Texture2D";
- case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
- return "Texture2DArray";
- case D3D11_DSV_DIMENSION_TEXTURE2DMS:
- return "Texture2DMS";
- case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
- return "Texture2DMSArray";
- }
- return "<unknown texture format>";
-}
-
-static HRESULT ValidateTextureType(_In_ ID3D11ShaderResourceView *pView, _In_ EObjectType ObjectType, _In_z_ LPCSTR pFuncName)
-{
- if (nullptr != pView)
- {
- D3D11_SHADER_RESOURCE_VIEW_DESC desc;
- pView->GetDesc(&desc);
- switch (ObjectType)
- {
- case EOT_Texture:
- if (desc.ViewDimension != D3D11_SRV_DIMENSION_BUFFER && desc.ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX)
- return S_OK;
- break;
- case EOT_Buffer:
- if (desc.ViewDimension != D3D11_SRV_DIMENSION_BUFFER && desc.ViewDimension != D3D11_SRV_DIMENSION_BUFFEREX)
- break;
- if (desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX && (desc.BufferEx.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW))
- {
- DPF(0, "%s: Resource type mismatch; %s expected, ByteAddressBuffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
- return E_INVALIDARG;
- }
- else
- {
- ID3D11Buffer* pBuffer = nullptr;
- pView->GetResource( (ID3D11Resource**)&pBuffer );
- assert( pBuffer != nullptr );
- D3D11_BUFFER_DESC BufDesc;
- pBuffer->GetDesc( &BufDesc );
- SAFE_RELEASE( pBuffer );
- if( BufDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED )
- {
- DPF(0, "%s: Resource type mismatch; %s expected, StructuredBuffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
- return E_INVALIDARG;
- }
- else
- {
- return S_OK;
- }
- }
- break;
- case EOT_Texture1D:
- case EOT_Texture1DArray:
- if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1D ||
- desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY)
- return S_OK;
- break;
- case EOT_Texture2D:
- case EOT_Texture2DArray:
- if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2D ||
- desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DARRAY)
- return S_OK;
- break;
- case EOT_Texture2DMS:
- case EOT_Texture2DMSArray:
- if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS ||
- desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY)
- return S_OK;
- break;
- case EOT_Texture3D:
- if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D)
- return S_OK;
- break;
- case EOT_TextureCube:
- case EOT_TextureCubeArray:
- if (desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBE ||
- desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY)
- return S_OK;
- break;
- case EOT_ByteAddressBuffer:
- if (desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX && (desc.BufferEx.Flags & D3D11_BUFFEREX_SRV_FLAG_RAW))
- return S_OK;
- break;
- case EOT_StructuredBuffer:
- if (desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX || desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER)
- {
- ID3D11Buffer* pBuffer = nullptr;
- pView->GetResource( (ID3D11Resource**)&pBuffer );
- assert( pBuffer != nullptr );
- D3D11_BUFFER_DESC BufDesc;
- pBuffer->GetDesc( &BufDesc );
- SAFE_RELEASE( pBuffer );
- if( BufDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED )
- {
- return S_OK;
- }
- else
- {
- DPF(0, "%s: Resource type mismatch; %s expected, non-structured Buffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
- return E_INVALIDARG;
- }
- }
- break;
- default:
- assert(0); // internal error, should never get here
- return E_FAIL;
- }
-
-
- DPF(0, "%s: Resource type mismatch; %s expected, %s provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType), GetSRVDimensionNameFromEnum(desc.ViewDimension));
- return E_INVALIDARG;
- }
- return S_OK;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderResourceVariable<IBaseInterface>::SetResource(ID3D11ShaderResourceView *pResource)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectShaderResourceVariable::SetResource";
-
- VH(ValidateTextureType(pResource, pType->ObjectType, pFuncName));
-#endif
-
- // Texture variables don't need to be dirtied.
- SAFE_ADDREF(pResource);
- SAFE_RELEASE(Data.pShaderResource->pShaderResource);
- Data.pShaderResource->pShaderResource = pResource;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderResourceVariable<IBaseInterface>::GetResource(ID3D11ShaderResourceView **ppResource)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectShaderResourceVariable::GetResource";
-
- VERIFYPARAMETER(ppResource);
-#endif
-
- assert(Data.pShaderResource != 0 && Data.pShaderResource->pShaderResource != 0);
- _Analysis_assume_(Data.pShaderResource != 0 && Data.pShaderResource->pShaderResource != 0);
- *ppResource = Data.pShaderResource->pShaderResource;
- SAFE_ADDREF(*ppResource);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderResourceVariable<IBaseInterface>::SetResourceArray(ID3D11ShaderResourceView **ppResources, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderResourceVariable::SetResourceArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
-
-#ifdef _DEBUG
- for (size_t i = 0; i < Count; ++ i)
- {
- VH(ValidateTextureType(ppResources[i], pType->ObjectType, pFuncName));
- }
-#endif
-
- // Texture variables don't need to be dirtied.
- for (size_t i = 0; i < Count; ++ i)
- {
- SShaderResource *pResourceBlock = Data.pShaderResource + Offset + i;
- SAFE_ADDREF(ppResources[i]);
- SAFE_RELEASE(pResourceBlock->pShaderResource);
- pResourceBlock->pShaderResource = ppResources[i];
- }
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderResourceVariable<IBaseInterface>::GetResourceArray(ID3D11ShaderResourceView **ppResources, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderResourceVariable::GetResourceArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
-
- for (size_t i = 0; i < Count; ++ i)
- {
- ppResources[i] = (Data.pShaderResource + Offset + i)->pShaderResource;
- SAFE_ADDREF(ppResources[i]);
- }
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectUnorderedAccessViewVariable (TUnorderedAccessViewVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TUnorderedAccessViewVariable : public IBaseInterface
-{
- STDMETHOD(SetUnorderedAccessView)(_In_ ID3D11UnorderedAccessView *pResource) override;
- STDMETHOD(GetUnorderedAccessView)(_Outptr_ ID3D11UnorderedAccessView **ppResource) override;
-
- STDMETHOD(SetUnorderedAccessViewArray)(_In_reads_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetUnorderedAccessViewArray)(_Out_writes_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-static HRESULT ValidateTextureType(_In_ ID3D11UnorderedAccessView *pView, _In_ EObjectType ObjectType, _In_z_ LPCSTR pFuncName)
-{
- if (nullptr != pView)
- {
- D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
- pView->GetDesc(&desc);
- switch (ObjectType)
- {
- case EOT_RWBuffer:
- if (desc.ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
- break;
- if (desc.Buffer.Flags & D3D11_BUFFER_UAV_FLAG_RAW)
- {
- DPF(0, "%s: Resource type mismatch; %s expected, RWByteAddressBuffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
- return E_INVALIDARG;
- }
- else
- {
- ID3D11Buffer* pBuffer = nullptr;
- pView->GetResource( (ID3D11Resource**)&pBuffer );
- assert( pBuffer != nullptr );
- D3D11_BUFFER_DESC BufDesc;
- pBuffer->GetDesc( &BufDesc );
- SAFE_RELEASE( pBuffer );
- if( BufDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED )
- {
- DPF(0, "%s: Resource type mismatch; %s expected, an RWStructuredBuffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
- return E_INVALIDARG;
- }
- else
- {
- return S_OK;
- }
- }
- break;
- case EOT_RWTexture1D:
- case EOT_RWTexture1DArray:
- if (desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D ||
- desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY)
- return S_OK;
- break;
- case EOT_RWTexture2D:
- case EOT_RWTexture2DArray:
- if (desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D ||
- desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY)
- return S_OK;
- break;
- case EOT_RWTexture3D:
- if (desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D)
- return S_OK;
- break;
- case EOT_RWByteAddressBuffer:
- if (desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && (desc.Buffer.Flags & D3D11_BUFFER_UAV_FLAG_RAW))
- return S_OK;
- break;
- case EOT_RWStructuredBuffer:
- if (desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER)
- {
- ID3D11Buffer* pBuffer = nullptr;
- pView->GetResource( (ID3D11Resource**)&pBuffer );
- assert( pBuffer != nullptr );
- D3D11_BUFFER_DESC BufDesc;
- pBuffer->GetDesc( &BufDesc );
- SAFE_RELEASE( pBuffer );
- if( BufDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED )
- {
- return S_OK;
- }
- else
- {
- DPF(0, "%s: Resource type mismatch; %s expected, non-structured Buffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
- return E_INVALIDARG;
- }
- }
- break;
- case EOT_RWStructuredBufferAlloc:
- case EOT_RWStructuredBufferConsume:
- if (desc.ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
- break;
- if (desc.Buffer.Flags & D3D11_BUFFER_UAV_FLAG_COUNTER)
- {
- return S_OK;
- }
- else
- {
- DPF(0, "%s: Resource type mismatch; %s expected, non-Counter buffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
- return E_INVALIDARG;
- }
- break;
- case EOT_AppendStructuredBuffer:
- case EOT_ConsumeStructuredBuffer:
- if (desc.ViewDimension != D3D11_UAV_DIMENSION_BUFFER)
- break;
- if (desc.Buffer.Flags & D3D11_BUFFER_UAV_FLAG_APPEND)
- {
- return S_OK;
- }
- else
- {
- DPF(0, "%s: Resource type mismatch; %s expected, non-Append buffer provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType));
- return E_INVALIDARG;
- }
- break;
- default:
- assert(0); // internal error, should never get here
- return E_FAIL;
- }
-
-
- DPF(0, "%s: Resource type mismatch; %s expected, %s provided.", pFuncName, GetTextureTypeNameFromEnum(ObjectType), GetUAVDimensionNameFromEnum(desc.ViewDimension));
- return E_INVALIDARG;
- }
- return S_OK;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TUnorderedAccessViewVariable<IBaseInterface>::SetUnorderedAccessView(ID3D11UnorderedAccessView *pResource)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectUnorderedAccessViewVariable::SetUnorderedAccessView";
-
- VH(ValidateTextureType(pResource, pType->ObjectType, pFuncName));
-#endif
-
- // UAV variables don't need to be dirtied.
- SAFE_ADDREF(pResource);
- SAFE_RELEASE(Data.pUnorderedAccessView->pUnorderedAccessView);
- Data.pUnorderedAccessView->pUnorderedAccessView = pResource;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TUnorderedAccessViewVariable<IBaseInterface>::GetUnorderedAccessView(ID3D11UnorderedAccessView **ppResource)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectUnorderedAccessViewVariable::GetUnorderedAccessView";
-
- VERIFYPARAMETER(ppResource);
-#endif
-
- assert(Data.pUnorderedAccessView != 0 && Data.pUnorderedAccessView->pUnorderedAccessView != 0);
- _Analysis_assume_(Data.pUnorderedAccessView != 0 && Data.pUnorderedAccessView->pUnorderedAccessView != 0);
- *ppResource = Data.pUnorderedAccessView->pUnorderedAccessView;
- SAFE_ADDREF(*ppResource);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TUnorderedAccessViewVariable<IBaseInterface>::SetUnorderedAccessViewArray(ID3D11UnorderedAccessView **ppResources, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectUnorderedAccessViewVariable::SetUnorderedAccessViewArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
-
-#ifdef _DEBUG
- for (size_t i = 0; i < Count; ++ i)
- {
- VH(ValidateTextureType(ppResources[i], pType->ObjectType, pFuncName));
- }
-#endif
-
- // Texture variables don't need to be dirtied.
- for (size_t i = 0; i < Count; ++ i)
- {
- SUnorderedAccessView *pResourceBlock = Data.pUnorderedAccessView + Offset + i;
- SAFE_ADDREF(ppResources[i]);
- SAFE_RELEASE(pResourceBlock->pUnorderedAccessView);
- pResourceBlock->pUnorderedAccessView = ppResources[i];
- }
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TUnorderedAccessViewVariable<IBaseInterface>::GetUnorderedAccessViewArray(ID3D11UnorderedAccessView **ppResources, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectUnorderedAccessViewVariable::GetUnorderedAccessViewArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
-
- for (size_t i = 0; i < Count; ++ i)
- {
- ppResources[i] = (Data.pUnorderedAccessView + Offset + i)->pUnorderedAccessView;
- SAFE_ADDREF(ppResources[i]);
- }
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectRenderTargetViewVariable (TRenderTargetViewVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TRenderTargetViewVariable : public IBaseInterface
-{
- STDMETHOD(SetRenderTarget)(_In_ ID3D11RenderTargetView *pResource) override;
- STDMETHOD(GetRenderTarget)(_Outptr_ ID3D11RenderTargetView **ppResource) override;
-
- STDMETHOD(SetRenderTargetArray)(_In_reads_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetRenderTargetArray)(_Out_writes_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TRenderTargetViewVariable<IBaseInterface>::SetRenderTarget(ID3D11RenderTargetView *pResource)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3DX11EffectRenderTargetVariable::SetRenderTarget";
-#endif
-
- // Texture variables don't need to be dirtied.
- SAFE_ADDREF(pResource);
- SAFE_RELEASE(Data.pRenderTargetView->pRenderTargetView);
- Data.pRenderTargetView->pRenderTargetView = pResource;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TRenderTargetViewVariable<IBaseInterface>::GetRenderTarget(ID3D11RenderTargetView **ppResource)
-{
- HRESULT hr = S_OK;
-
- assert(Data.pRenderTargetView->pRenderTargetView != 0);
- _Analysis_assume_(Data.pRenderTargetView->pRenderTargetView != 0);
- *ppResource = Data.pRenderTargetView->pRenderTargetView;
- SAFE_ADDREF(*ppResource);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TRenderTargetViewVariable<IBaseInterface>::SetRenderTargetArray(ID3D11RenderTargetView **ppResources, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectRenderTargetVariable::SetRenderTargetArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
-
- // Texture variables don't need to be dirtied.
- for (size_t i = 0; i < Count; ++ i)
- {
- SRenderTargetView *pResourceBlock = Data.pRenderTargetView + Offset + i;
- SAFE_ADDREF(ppResources[i]);
- SAFE_RELEASE(pResourceBlock->pRenderTargetView);
- pResourceBlock->pRenderTargetView = ppResources[i];
- }
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TRenderTargetViewVariable<IBaseInterface>::GetRenderTargetArray(ID3D11RenderTargetView **ppResources, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3DX11EffectRenderTargetVariable::GetRenderTargetArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
-
- for (size_t i = 0; i < Count; ++ i)
- {
- ppResources[i] = (Data.pRenderTargetView + Offset + i)->pRenderTargetView;
- SAFE_ADDREF(ppResources[i]);
- }
-
-lExit:
- return hr;
-}
-
-//////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectDepthStencilViewVariable (TDepthStencilViewVariable implementation)
-//////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TDepthStencilViewVariable : public IBaseInterface
-{
- STDMETHOD(SetDepthStencil)(_In_ ID3D11DepthStencilView *pResource) override;
- STDMETHOD(GetDepthStencil)(_Outptr_ ID3D11DepthStencilView **ppResource) override;
-
- STDMETHOD(SetDepthStencilArray)(_In_reads_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
- STDMETHOD(GetDepthStencilArray)(_Out_writes_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) override;
-};
-
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TDepthStencilViewVariable<IBaseInterface>::SetDepthStencil(ID3D11DepthStencilView *pResource)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3D11DepthStencilViewVariable::SetDepthStencil";
-
-#endif
-
- // Texture variables don't need to be dirtied.
- SAFE_ADDREF(pResource);
- SAFE_RELEASE(Data.pDepthStencilView->pDepthStencilView);
- Data.pDepthStencilView->pDepthStencilView = pResource;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TDepthStencilViewVariable<IBaseInterface>::GetDepthStencil(ID3D11DepthStencilView **ppResource)
-{
- HRESULT hr = S_OK;
-
-#ifdef _DEBUG
- static LPCSTR pFuncName = "ID3D11DepthStencilViewVariable::GetDepthStencil";
-
- VERIFYPARAMETER(ppResource);
-#endif
-
- assert(Data.pDepthStencilView->pDepthStencilView != 0);
- _Analysis_assume_(Data.pDepthStencilView->pDepthStencilView != 0);
- *ppResource = Data.pDepthStencilView->pDepthStencilView;
- SAFE_ADDREF(*ppResource);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TDepthStencilViewVariable<IBaseInterface>::SetDepthStencilArray(ID3D11DepthStencilView **ppResources, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3D11DepthStencilViewVariable::SetDepthStencilArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
-
- // Texture variables don't need to be dirtied.
- for (size_t i = 0; i < Count; ++ i)
- {
- SDepthStencilView *pResourceBlock = Data.pDepthStencilView + Offset + i;
- SAFE_ADDREF(ppResources[i]);
- SAFE_RELEASE(pResourceBlock->pDepthStencilView);
- pResourceBlock->pDepthStencilView = ppResources[i];
- }
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TDepthStencilViewVariable<IBaseInterface>::GetDepthStencilArray(ID3D11DepthStencilView **ppResources, uint32_t Offset, uint32_t Count)
-{
- static LPCSTR pFuncName = "ID3D11DepthStencilViewVariable::GetDepthStencilArray";
-
- CHECK_OBJECT_ARRAY_BOUNDS(Offset, Count, ppResources);
-
- for (size_t i = 0; i < Count; ++ i)
- {
- ppResources[i] = (Data.pDepthStencilView + Offset + i)->pDepthStencilView;
- SAFE_ADDREF(ppResources[i]);
- }
-
-lExit:
- return hr;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectShaderVariable (TShaderVariable implementation)
-////////////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TShaderVariable : public IBaseInterface
-{
- STDMETHOD(GetShaderDesc)(_In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc) override;
-
- STDMETHOD(GetVertexShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11VertexShader **ppVS) override;
- STDMETHOD(GetGeometryShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11GeometryShader **ppGS) override;
- STDMETHOD(GetPixelShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11PixelShader **ppPS) override;
- STDMETHOD(GetHullShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11HullShader **ppHS) override;
- STDMETHOD(GetDomainShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11DomainShader **ppDS) override;
- STDMETHOD(GetComputeShader)(_In_ uint32_t ShaderIndex, _Outptr_ ID3D11ComputeShader **ppCS) override;
-
- STDMETHOD(GetInputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
- STDMETHOD(GetOutputSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
- STDMETHOD(GetPatchConstantSignatureElementDesc)(_In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) override;
-
- STDMETHOD_(bool, IsValid)();
-};
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetShaderDesc(uint32_t ShaderIndex, D3DX11_EFFECT_SHADER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetShaderDesc";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, pDesc);
-
- hr = Data.pShader[ShaderIndex].GetShaderDesc(pDesc, false);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetVertexShader(uint32_t ShaderIndex, ID3D11VertexShader **ppVS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetVertexShader";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppVS);
-
- VH( Data.pShader[ShaderIndex].GetVertexShader(ppVS) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetGeometryShader(uint32_t ShaderIndex, ID3D11GeometryShader **ppGS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetGeometryShader";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppGS);
-
- VH( Data.pShader[ShaderIndex].GetGeometryShader(ppGS) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetPixelShader(uint32_t ShaderIndex, ID3D11PixelShader **ppPS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetPixelShader";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppPS);
-
- VH( Data.pShader[ShaderIndex].GetPixelShader(ppPS) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetHullShader(uint32_t ShaderIndex, ID3D11HullShader **ppHS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetHullShader";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppHS);
-
- VH( Data.pShader[ShaderIndex].GetHullShader(ppHS) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetDomainShader(uint32_t ShaderIndex, ID3D11DomainShader **ppDS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetDomainShader";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppDS);
-
- VH( Data.pShader[ShaderIndex].GetDomainShader(ppDS) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetComputeShader(uint32_t ShaderIndex, ID3D11ComputeShader **ppCS)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetComputeShader";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, ppCS);
-
- VH( Data.pShader[ShaderIndex].GetComputeShader(ppCS) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetInputSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetInputSignatureElementDesc";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, pDesc);
-
- VH( Data.pShader[ShaderIndex].GetSignatureElementDesc(SShaderBlock::ST_Input, Element, pDesc) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetOutputSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetOutputSignatureElementDesc";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, pDesc);
-
- VH( Data.pShader[ShaderIndex].GetSignatureElementDesc(SShaderBlock::ST_Output, Element, pDesc) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TShaderVariable<IBaseInterface>::GetPatchConstantSignatureElementDesc(uint32_t ShaderIndex, uint32_t Element, D3D11_SIGNATURE_PARAMETER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectShaderVariable::GetPatchConstantSignatureElementDesc";
-
- CHECK_OBJECT_SCALAR_BOUNDS(ShaderIndex, pDesc);
-
- VH( Data.pShader[ShaderIndex].GetSignatureElementDesc(SShaderBlock::ST_PatchConstant, Element, pDesc) );
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-bool TShaderVariable<IBaseInterface>::IsValid()
-{
- uint32_t numElements = IsArray()? pType->Elements : 1;
- bool valid = true;
- while( numElements > 0 && ( valid = Data.pShader[ numElements-1 ].IsValid ) )
- numElements--;
- return valid;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectBlendVariable (TBlendVariable implementation)
-////////////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TBlendVariable : public IBaseInterface
-{
-public:
- STDMETHOD(GetBlendState)(_In_ uint32_t Index, _Outptr_ ID3D11BlendState **ppState) override;
- STDMETHOD(SetBlendState)(_In_ uint32_t Index, _In_ ID3D11BlendState *pState) override;
- STDMETHOD(UndoSetBlendState)(_In_ uint32_t Index) override;
- STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_BLEND_DESC *pDesc) override;
- STDMETHOD_(bool, IsValid)() override;
-};
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TBlendVariable<IBaseInterface>::GetBlendState(uint32_t Index, ID3D11BlendState **ppState)
-{
- static LPCSTR pFuncName = "ID3DX11EffectBlendVariable::GetBlendState";
-
- CHECK_OBJECT_SCALAR_BOUNDS(Index, ppState);
-
- assert(Data.pBlend[Index].pBlendObject != 0);
- _Analysis_assume_(Data.pBlend[Index].pBlendObject != 0);
- *ppState = Data.pBlend[Index].pBlendObject;
- SAFE_ADDREF(*ppState);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TBlendVariable<IBaseInterface>::SetBlendState(uint32_t Index, ID3D11BlendState *pState)
-{
- static LPCSTR pFuncName = "ID3DX11EffectBlendState::SetBlendState";
-
- CHECK_SCALAR_BOUNDS(Index);
-
- if( !Data.pBlend[Index].IsUserManaged )
- {
- // Save original state object in case we UndoSet
- assert( pMemberData[Index].Type == MDT_BlendState );
- VB( pMemberData[Index].Data.pD3DEffectsManagedBlendState == nullptr );
- pMemberData[Index].Data.pD3DEffectsManagedBlendState = Data.pBlend[Index].pBlendObject;
- Data.pBlend[Index].pBlendObject = nullptr;
- Data.pBlend[Index].IsUserManaged = true;
- }
-
- SAFE_ADDREF( pState );
- SAFE_RELEASE( Data.pBlend[Index].pBlendObject );
- Data.pBlend[Index].pBlendObject = pState;
- Data.pBlend[Index].IsValid = true;
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TBlendVariable<IBaseInterface>::UndoSetBlendState(uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectBlendState::UndoSetBlendState";
-
- CHECK_SCALAR_BOUNDS(Index);
-
- if( !Data.pBlend[Index].IsUserManaged )
- {
- return S_FALSE;
- }
-
- // Revert to original state object
- SAFE_RELEASE( Data.pBlend[Index].pBlendObject );
- Data.pBlend[Index].pBlendObject = pMemberData[Index].Data.pD3DEffectsManagedBlendState;
- pMemberData[Index].Data.pD3DEffectsManagedBlendState = nullptr;
- Data.pBlend[Index].IsUserManaged = false;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TBlendVariable<IBaseInterface>::GetBackingStore(uint32_t Index, D3D11_BLEND_DESC *pBlendDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectBlendVariable::GetBackingStore";
-
- CHECK_OBJECT_SCALAR_BOUNDS(Index, pBlendDesc);
-
- if( Data.pBlend[Index].IsUserManaged )
- {
- if( Data.pBlend[Index].pBlendObject )
- {
- Data.pBlend[Index].pBlendObject->GetDesc( pBlendDesc );
- }
- else
- {
- *pBlendDesc = CD3D11_BLEND_DESC( D3D11_DEFAULT );
- }
- }
- else
- {
- SBlendBlock *pBlock = Data.pBlend + Index;
- if (pBlock->ApplyAssignments(GetTopLevelEntity()->pEffect))
- {
- pBlock->pAssignments[0].LastRecomputedTime = 0; // Force a recreate of this block the next time ApplyRenderStateBlock is called
- }
-
- memcpy( pBlendDesc, &pBlock->BackingStore, sizeof(D3D11_BLEND_DESC) );
- }
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-bool TBlendVariable<IBaseInterface>::IsValid()
-{
- uint32_t numElements = IsArray()? pType->Elements : 1;
- bool valid = true;
- while( numElements > 0 && ( valid = Data.pBlend[ numElements-1 ].IsValid ) )
- numElements--;
- return valid;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectDepthStencilVariable (TDepthStencilVariable implementation)
-////////////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TDepthStencilVariable : public IBaseInterface
-{
-public:
- STDMETHOD(GetDepthStencilState)(_In_ uint32_t Index, _Outptr_ ID3D11DepthStencilState **ppState) override;
- STDMETHOD(SetDepthStencilState)(_In_ uint32_t Index, _In_ ID3D11DepthStencilState *pState) override;
- STDMETHOD(UndoSetDepthStencilState)(_In_ uint32_t Index) override;
- STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_DEPTH_STENCIL_DESC *pDesc) override;
- STDMETHOD_(bool, IsValid)() override;
-};
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TDepthStencilVariable<IBaseInterface>::GetDepthStencilState(uint32_t Index, ID3D11DepthStencilState **ppState)
-{
- static LPCSTR pFuncName = "ID3DX11EffectDepthStencilVariable::GetDepthStencilState";
-
- CHECK_OBJECT_SCALAR_BOUNDS(Index, ppState);
-
- assert(Data.pDepthStencil[Index].pDSObject != 0);
- _Analysis_assume_(Data.pDepthStencil[Index].pDSObject != 0);
- *ppState = Data.pDepthStencil[Index].pDSObject;
- SAFE_ADDREF(*ppState);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TDepthStencilVariable<IBaseInterface>::SetDepthStencilState(uint32_t Index, ID3D11DepthStencilState *pState)
-{
- static LPCSTR pFuncName = "ID3DX11EffectDepthStencilState::SetDepthStencilState";
-
- CHECK_SCALAR_BOUNDS(Index);
-
- if( !Data.pDepthStencil[Index].IsUserManaged )
- {
- // Save original state object in case we UndoSet
- assert( pMemberData[Index].Type == MDT_DepthStencilState );
- VB( pMemberData[Index].Data.pD3DEffectsManagedDepthStencilState == nullptr );
- pMemberData[Index].Data.pD3DEffectsManagedDepthStencilState = Data.pDepthStencil[Index].pDSObject;
- Data.pDepthStencil[Index].pDSObject = nullptr;
- Data.pDepthStencil[Index].IsUserManaged = true;
- }
-
- SAFE_ADDREF( pState );
- SAFE_RELEASE( Data.pDepthStencil[Index].pDSObject );
- Data.pDepthStencil[Index].pDSObject = pState;
- Data.pDepthStencil[Index].IsValid = true;
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-HRESULT TDepthStencilVariable<IBaseInterface>::UndoSetDepthStencilState(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectDepthStencilState::UndoSetDepthStencilState";
-
- CHECK_SCALAR_BOUNDS(Index);
-
- if( !Data.pDepthStencil[Index].IsUserManaged )
- {
- return S_FALSE;
- }
-
- // Revert to original state object
- SAFE_RELEASE( Data.pDepthStencil[Index].pDSObject );
- Data.pDepthStencil[Index].pDSObject = pMemberData[Index].Data.pD3DEffectsManagedDepthStencilState;
- pMemberData[Index].Data.pD3DEffectsManagedDepthStencilState = nullptr;
- Data.pDepthStencil[Index].IsUserManaged = false;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TDepthStencilVariable<IBaseInterface>::GetBackingStore(uint32_t Index, D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectDepthStencilVariable::GetBackingStore";
-
- CHECK_OBJECT_SCALAR_BOUNDS(Index, pDepthStencilDesc);
-
- if( Data.pDepthStencil[Index].IsUserManaged )
- {
- if( Data.pDepthStencil[Index].pDSObject )
- {
- Data.pDepthStencil[Index].pDSObject->GetDesc( pDepthStencilDesc );
- }
- else
- {
- *pDepthStencilDesc = CD3D11_DEPTH_STENCIL_DESC( D3D11_DEFAULT );
- }
- }
- else
- {
- SDepthStencilBlock *pBlock = Data.pDepthStencil + Index;
- if (pBlock->ApplyAssignments(GetTopLevelEntity()->pEffect))
- {
- pBlock->pAssignments[0].LastRecomputedTime = 0; // Force a recreate of this block the next time ApplyRenderStateBlock is called
- }
-
- memcpy(pDepthStencilDesc, &pBlock->BackingStore, sizeof(D3D11_DEPTH_STENCIL_DESC));
- }
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-bool TDepthStencilVariable<IBaseInterface>::IsValid()
-{
- uint32_t numElements = IsArray()? pType->Elements : 1;
- bool valid = true;
- while( numElements > 0 && ( valid = Data.pDepthStencil[ numElements-1 ].IsValid ) )
- numElements--;
- return valid;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectRasterizerVariable (TRasterizerVariable implementation)
-////////////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TRasterizerVariable : public IBaseInterface
-{
-public:
-
- STDMETHOD(GetRasterizerState)(_In_ uint32_t Index, _Outptr_ ID3D11RasterizerState **ppState) override;
- STDMETHOD(SetRasterizerState)(_In_ uint32_t Index, _In_ ID3D11RasterizerState *pState) override;
- STDMETHOD(UndoSetRasterizerState)(_In_ uint32_t Index) override;
- STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_RASTERIZER_DESC *pDesc) override;
- STDMETHOD_(bool, IsValid)() override;
-};
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TRasterizerVariable<IBaseInterface>::GetRasterizerState(uint32_t Index, ID3D11RasterizerState **ppState)
-{
- static LPCSTR pFuncName = "ID3DX11EffectRasterizerVariable::GetRasterizerState";
-
- CHECK_OBJECT_SCALAR_BOUNDS(Index, ppState);
-
- assert(Data.pRasterizer[Index].pRasterizerObject != 0);
- _Analysis_assume_(Data.pRasterizer[Index].pRasterizerObject != 0);
- *ppState = Data.pRasterizer[Index].pRasterizerObject;
- SAFE_ADDREF(*ppState);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TRasterizerVariable<IBaseInterface>::SetRasterizerState(uint32_t Index, ID3D11RasterizerState *pState)
-{
- static LPCSTR pFuncName = "ID3DX11EffectRasterizerState::SetRasterizerState";
-
- CHECK_SCALAR_BOUNDS(Index);
-
- if( !Data.pRasterizer[Index].IsUserManaged )
- {
- // Save original state object in case we UndoSet
- assert( pMemberData[Index].Type == MDT_RasterizerState );
- VB( pMemberData[Index].Data.pD3DEffectsManagedRasterizerState == nullptr );
- pMemberData[Index].Data.pD3DEffectsManagedRasterizerState = Data.pRasterizer[Index].pRasterizerObject;
- Data.pRasterizer[Index].pRasterizerObject = nullptr;
- Data.pRasterizer[Index].IsUserManaged = true;
- }
-
- SAFE_ADDREF( pState );
- SAFE_RELEASE( Data.pRasterizer[Index].pRasterizerObject );
- Data.pRasterizer[Index].pRasterizerObject = pState;
- Data.pRasterizer[Index].IsValid = true;
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TRasterizerVariable<IBaseInterface>::UndoSetRasterizerState(uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectRasterizerState::UndoSetRasterizerState";
-
- CHECK_SCALAR_BOUNDS(Index);
-
- if( !Data.pRasterizer[Index].IsUserManaged )
- {
- return S_FALSE;
- }
-
- // Revert to original state object
- SAFE_RELEASE( Data.pRasterizer[Index].pRasterizerObject );
- Data.pRasterizer[Index].pRasterizerObject = pMemberData[Index].Data.pD3DEffectsManagedRasterizerState;
- pMemberData[Index].Data.pD3DEffectsManagedRasterizerState = nullptr;
- Data.pRasterizer[Index].IsUserManaged = false;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TRasterizerVariable<IBaseInterface>::GetBackingStore(uint32_t Index, D3D11_RASTERIZER_DESC *pRasterizerDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectRasterizerVariable::GetBackingStore";
-
- CHECK_OBJECT_SCALAR_BOUNDS(Index, pRasterizerDesc);
-
- if( Data.pRasterizer[Index].IsUserManaged )
- {
- if( Data.pRasterizer[Index].pRasterizerObject )
- {
- Data.pRasterizer[Index].pRasterizerObject->GetDesc( pRasterizerDesc );
- }
- else
- {
- *pRasterizerDesc = CD3D11_RASTERIZER_DESC( D3D11_DEFAULT );
- }
- }
- else
- {
- SRasterizerBlock *pBlock = Data.pRasterizer + Index;
- if (pBlock->ApplyAssignments(GetTopLevelEntity()->pEffect))
- {
- pBlock->pAssignments[0].LastRecomputedTime = 0; // Force a recreate of this block the next time ApplyRenderStateBlock is called
- }
-
- memcpy(pRasterizerDesc, &pBlock->BackingStore, sizeof(D3D11_RASTERIZER_DESC));
- }
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-bool TRasterizerVariable<IBaseInterface>::IsValid()
-{
- uint32_t numElements = IsArray()? pType->Elements : 1;
- bool valid = true;
- while( numElements > 0 && ( valid = Data.pRasterizer[ numElements-1 ].IsValid ) )
- numElements--;
- return valid;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectSamplerVariable (TSamplerVariable implementation)
-////////////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TSamplerVariable : public IBaseInterface
-{
-public:
-
- STDMETHOD(GetSampler)(_In_ uint32_t Index, _Outptr_ ID3D11SamplerState **ppSampler) override;
- STDMETHOD(SetSampler)(_In_ uint32_t Index, _In_ ID3D11SamplerState *pSampler) override;
- STDMETHOD(UndoSetSampler)(_In_ uint32_t Index) override;
- STDMETHOD(GetBackingStore)(_In_ uint32_t Index, _Out_ D3D11_SAMPLER_DESC *pDesc) override;
-};
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TSamplerVariable<IBaseInterface>::GetSampler(uint32_t Index, ID3D11SamplerState **ppSampler)
-{
- static LPCSTR pFuncName = "ID3DX11EffectSamplerVariable::GetSampler";
-
- CHECK_OBJECT_SCALAR_BOUNDS(Index, ppSampler);
-
- _Analysis_assume_( Data.pSampler[Index].pD3DObject != 0 );
- *ppSampler = Data.pSampler[Index].pD3DObject;
- SAFE_ADDREF(*ppSampler);
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TSamplerVariable<IBaseInterface>::SetSampler(uint32_t Index, ID3D11SamplerState *pSampler)
-{
- static LPCSTR pFuncName = "ID3DX11EffectSamplerState::SetSampler";
-
- CHECK_SCALAR_BOUNDS(Index);
-
- // Replace all references to the old shader block with this one
- GetEffect()->ReplaceSamplerReference(&Data.pSampler[Index], pSampler);
-
- if( !Data.pSampler[Index].IsUserManaged )
- {
- // Save original state object in case we UndoSet
- assert( pMemberData[Index].Type == MDT_SamplerState );
- VB( pMemberData[Index].Data.pD3DEffectsManagedSamplerState == nullptr );
- pMemberData[Index].Data.pD3DEffectsManagedSamplerState = Data.pSampler[Index].pD3DObject;
- Data.pSampler[Index].pD3DObject = nullptr;
- Data.pSampler[Index].IsUserManaged = true;
- }
-
- SAFE_ADDREF( pSampler );
- SAFE_RELEASE( Data.pSampler[Index].pD3DObject );
- Data.pSampler[Index].pD3DObject = pSampler;
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-HRESULT TSamplerVariable<IBaseInterface>::UndoSetSampler(_In_ uint32_t Index)
-{
- static LPCSTR pFuncName = "ID3DX11EffectSamplerState::UndoSetSampler";
-
- CHECK_SCALAR_BOUNDS(Index);
-
- if( !Data.pSampler[Index].IsUserManaged )
- {
- return S_FALSE;
- }
-
- // Replace all references to the old shader block with this one
- GetEffect()->ReplaceSamplerReference(&Data.pSampler[Index], pMemberData[Index].Data.pD3DEffectsManagedSamplerState);
-
- // Revert to original state object
- SAFE_RELEASE( Data.pSampler[Index].pD3DObject );
- Data.pSampler[Index].pD3DObject = pMemberData[Index].Data.pD3DEffectsManagedSamplerState;
- pMemberData[Index].Data.pD3DEffectsManagedSamplerState = nullptr;
- Data.pSampler[Index].IsUserManaged = false;
-
-lExit:
- return hr;
-}
-
-template<typename IBaseInterface>
-_Use_decl_annotations_
-HRESULT TSamplerVariable<IBaseInterface>::GetBackingStore(uint32_t Index, D3D11_SAMPLER_DESC *pDesc)
-{
- static LPCSTR pFuncName = "ID3DX11EffectSamplerVariable::GetBackingStore";
-
- CHECK_OBJECT_SCALAR_BOUNDS(Index, pDesc);
-
- if( Data.pSampler[Index].IsUserManaged )
- {
- if( Data.pSampler[Index].pD3DObject )
- {
- Data.pSampler[Index].pD3DObject->GetDesc( pDesc );
- }
- else
- {
- *pDesc = CD3D11_SAMPLER_DESC( D3D11_DEFAULT );
- }
- }
- else
- {
- SSamplerBlock *pBlock = Data.pSampler + Index;
- if (pBlock->ApplyAssignments(GetTopLevelEntity()->pEffect))
- {
- pBlock->pAssignments[0].LastRecomputedTime = 0; // Force a recreate of this block the next time ApplyRenderStateBlock is called
- }
-
- memcpy(pDesc, &pBlock->BackingStore.SamplerDesc, sizeof(D3D11_SAMPLER_DESC));
- }
-
-lExit:
- return hr;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TUncastableVariable
-////////////////////////////////////////////////////////////////////////////////
-
-template<typename IBaseInterface>
-struct TUncastableVariable : public IBaseInterface
-{
- STDMETHOD_(ID3DX11EffectScalarVariable*, AsScalar)() override;
- STDMETHOD_(ID3DX11EffectVectorVariable*, AsVector)() override;
- STDMETHOD_(ID3DX11EffectMatrixVariable*, AsMatrix)() override;
- STDMETHOD_(ID3DX11EffectStringVariable*, AsString)() override;
- STDMETHOD_(ID3DX11EffectClassInstanceVariable*, AsClassInstance)() override;
- STDMETHOD_(ID3DX11EffectInterfaceVariable*, AsInterface)() override;
- STDMETHOD_(ID3DX11EffectShaderResourceVariable*, AsShaderResource)() override;
- STDMETHOD_(ID3DX11EffectUnorderedAccessViewVariable*, AsUnorderedAccessView)() override;
- STDMETHOD_(ID3DX11EffectRenderTargetViewVariable*, AsRenderTargetView)() override;
- STDMETHOD_(ID3DX11EffectDepthStencilViewVariable*, AsDepthStencilView)() override;
- STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)() override;
- STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)() override;
- STDMETHOD_(ID3DX11EffectBlendVariable*, AsBlend)() override;
- STDMETHOD_(ID3DX11EffectDepthStencilVariable*, AsDepthStencil)() override;
- STDMETHOD_(ID3DX11EffectRasterizerVariable*, AsRasterizer)() override;
- STDMETHOD_(ID3DX11EffectSamplerVariable*, AsSampler)() override;
-};
-
-template<typename IBaseInterface>
-ID3DX11EffectScalarVariable * TUncastableVariable<IBaseInterface>::AsScalar()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsScalar";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidScalarVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectVectorVariable * TUncastableVariable<IBaseInterface>::AsVector()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsVector";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidVectorVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectMatrixVariable * TUncastableVariable<IBaseInterface>::AsMatrix()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsMatrix";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidMatrixVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectStringVariable * TUncastableVariable<IBaseInterface>::AsString()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsString";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidStringVariable;
-}
-
-template<typename IBaseClassInstance>
-ID3DX11EffectClassInstanceVariable * TUncastableVariable<IBaseClassInstance>::AsClassInstance()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsClassInstance";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidClassInstanceVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectInterfaceVariable * TUncastableVariable<IBaseInterface>::AsInterface()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsInterface";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidInterfaceVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectShaderResourceVariable * TUncastableVariable<IBaseInterface>::AsShaderResource()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsShaderResource";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidShaderResourceVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectUnorderedAccessViewVariable * TUncastableVariable<IBaseInterface>::AsUnorderedAccessView()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsUnorderedAccessView";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidUnorderedAccessViewVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectRenderTargetViewVariable * TUncastableVariable<IBaseInterface>::AsRenderTargetView()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsRenderTargetView";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidRenderTargetViewVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectDepthStencilViewVariable * TUncastableVariable<IBaseInterface>::AsDepthStencilView()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsDepthStencilView";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidDepthStencilViewVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectConstantBuffer * TUncastableVariable<IBaseInterface>::AsConstantBuffer()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsConstantBuffer";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidConstantBuffer;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectShaderVariable * TUncastableVariable<IBaseInterface>::AsShader()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsShader";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidShaderVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectBlendVariable * TUncastableVariable<IBaseInterface>::AsBlend()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsBlend";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidBlendVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectDepthStencilVariable * TUncastableVariable<IBaseInterface>::AsDepthStencil()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsDepthStencil";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidDepthStencilVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectRasterizerVariable * TUncastableVariable<IBaseInterface>::AsRasterizer()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsRasterizer";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidRasterizerVariable;
-}
-
-template<typename IBaseInterface>
-ID3DX11EffectSamplerVariable * TUncastableVariable<IBaseInterface>::AsSampler()
-{
- static LPCSTR pFuncName = "ID3DX11EffectVariable::AsSampler";
- DPF(0, "%s: Invalid typecast", pFuncName);
- return &g_InvalidSamplerVariable;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Macros to instantiate the myriad templates
-////////////////////////////////////////////////////////////////////////////////
-
-// generates a global variable, annotation, global variable member, and annotation member of each struct type
-#define GenerateReflectionClasses(Type, BaseInterface) \
-struct S##Type##GlobalVariable : public T##Type##Variable<TGlobalVariable<BaseInterface>, false> { IUNKNOWN_IMP(S##Type##GlobalVariable, BaseInterface, ID3DX11EffectVariable); }; \
-struct S##Type##Annotation : public T##Type##Variable<TAnnotation<BaseInterface>, true> { IUNKNOWN_IMP(S##Type##Annotation, BaseInterface, ID3DX11EffectVariable);}; \
-struct S##Type##GlobalVariableMember : public T##Type##Variable<TVariable<TMember<BaseInterface> >, false> { IUNKNOWN_IMP(S##Type##GlobalVariableMember, BaseInterface, ID3DX11EffectVariable); }; \
-struct S##Type##AnnotationMember : public T##Type##Variable<TVariable<TMember<BaseInterface> >, true> { IUNKNOWN_IMP(S##Type##AnnotationMember, BaseInterface, ID3DX11EffectVariable); };
-
-#define GenerateVectorReflectionClasses(Type, BaseType, BaseInterface) \
-struct S##Type##GlobalVariable : public TVectorVariable<TGlobalVariable<BaseInterface>, false, BaseType> { IUNKNOWN_IMP(S##Type##GlobalVariable, BaseInterface, ID3DX11EffectVariable); }; \
-struct S##Type##Annotation : public TVectorVariable<TAnnotation<BaseInterface>, true, BaseType> { IUNKNOWN_IMP(S##Type##Annotation, BaseInterface, ID3DX11EffectVariable);}; \
-struct S##Type##GlobalVariableMember : public TVectorVariable<TVariable<TMember<BaseInterface> >, false, BaseType> { IUNKNOWN_IMP(S##Type##GlobalVariableMember, BaseInterface, ID3DX11EffectVariable);}; \
-struct S##Type##AnnotationMember : public TVectorVariable<TVariable<TMember<BaseInterface> >, true, BaseType> { IUNKNOWN_IMP(S##Type##AnnotationMember, BaseInterface, ID3DX11EffectVariable);};
-
-#define GenerateReflectionGlobalOnlyClasses(Type) \
-struct S##Type##GlobalVariable : public T##Type##Variable<TGlobalVariable<ID3DX11Effect##Type##Variable> > { IUNKNOWN_IMP(S##Type##GlobalVariable, ID3DX11Effect##Type##Variable, ID3DX11EffectVariable); }; \
-struct S##Type##GlobalVariableMember : public T##Type##Variable<TVariable<TMember<ID3DX11Effect##Type##Variable> > > { IUNKNOWN_IMP(S##Type##GlobalVariableMember, ID3DX11Effect##Type##Variable, ID3DX11EffectVariable); }; \
-
-GenerateReflectionClasses(Numeric, ID3DX11EffectVariable);
-GenerateReflectionClasses(FloatScalar, ID3DX11EffectScalarVariable);
-GenerateReflectionClasses(IntScalar, ID3DX11EffectScalarVariable);
-GenerateReflectionClasses(BoolScalar, ID3DX11EffectScalarVariable);
-GenerateVectorReflectionClasses(FloatVector, ETVT_Float, ID3DX11EffectVectorVariable);
-GenerateVectorReflectionClasses(BoolVector, ETVT_Bool, ID3DX11EffectVectorVariable);
-GenerateVectorReflectionClasses(IntVector, ETVT_Int, ID3DX11EffectVectorVariable);
-GenerateReflectionClasses(Matrix, ID3DX11EffectMatrixVariable);
-GenerateReflectionClasses(String, ID3DX11EffectStringVariable);
-GenerateReflectionGlobalOnlyClasses(ClassInstance);
-GenerateReflectionGlobalOnlyClasses(Interface);
-GenerateReflectionGlobalOnlyClasses(ShaderResource);
-GenerateReflectionGlobalOnlyClasses(UnorderedAccessView);
-GenerateReflectionGlobalOnlyClasses(RenderTargetView);
-GenerateReflectionGlobalOnlyClasses(DepthStencilView);
-GenerateReflectionGlobalOnlyClasses(Shader);
-GenerateReflectionGlobalOnlyClasses(Blend);
-GenerateReflectionGlobalOnlyClasses(DepthStencil);
-GenerateReflectionGlobalOnlyClasses(Rasterizer);
-GenerateReflectionGlobalOnlyClasses(Sampler);
-
-// Optimized matrix classes
-struct SMatrix4x4ColumnMajorGlobalVariable : public TMatrix4x4Variable<TGlobalVariable<ID3DX11EffectMatrixVariable>, true> { IUNKNOWN_IMP(SMatrix4x4ColumnMajorGlobalVariable, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable); };
-struct SMatrix4x4RowMajorGlobalVariable : public TMatrix4x4Variable<TGlobalVariable<ID3DX11EffectMatrixVariable>, false> { IUNKNOWN_IMP(SMatrix4x4RowMajorGlobalVariable, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable); };
-
-struct SMatrix4x4ColumnMajorGlobalVariableMember : public TMatrix4x4Variable<TVariable<TMember<ID3DX11EffectMatrixVariable> >, true> { IUNKNOWN_IMP(SMatrix4x4ColumnMajorGlobalVariableMember, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable); };
-struct SMatrix4x4RowMajorGlobalVariableMember : public TMatrix4x4Variable<TVariable<TMember<ID3DX11EffectMatrixVariable> >, false> { IUNKNOWN_IMP(SMatrix4x4RowMajorGlobalVariableMember, ID3DX11EffectMatrixVariable, ID3DX11EffectVariable); };
-
-// Optimized vector classes
-struct SFloatVector4GlobalVariable : public TVector4Variable<TGlobalVariable<ID3DX11EffectVectorVariable> > { IUNKNOWN_IMP(SFloatVector4GlobalVariable, ID3DX11EffectVectorVariable, ID3DX11EffectVariable); };
-struct SFloatVector4GlobalVariableMember : public TVector4Variable<TVariable<TMember<ID3DX11EffectVectorVariable> > > { IUNKNOWN_IMP(SFloatVector4GlobalVariableMember, ID3DX11EffectVectorVariable, ID3DX11EffectVariable); };
-
-// These 3 classes should never be used directly
-
-// The "base" global variable struct (all global variables should be the same size in bytes,
-// but we pick this as the default).
-struct SGlobalVariable : public TGlobalVariable<ID3DX11EffectVariable>
-{
-
-};
-
-// The "base" annotation struct (all annotations should be the same size in bytes,
-// but we pick this as the default).
-struct SAnnotation : public TAnnotation<ID3DX11EffectVariable>
-{
-
-};
-
-// The "base" variable member struct (all annotation/global variable members should be the
-// same size in bytes, but we pick this as the default).
-struct SMember : public TVariable<TMember<ID3DX11EffectVariable> >
-{
-
-};
-
-// creates a new variable of the appropriate polymorphic type where pVar was
-HRESULT PlacementNewVariable(_In_ void *pVar, _In_ SType *pType, _In_ bool IsAnnotation);
-SMember * CreateNewMember(_In_ SType *pType, _In_ bool IsAnnotation);
-
-#pragma warning(pop)
diff --git a/lib/win32/Effects11/HISTORY.md b/lib/win32/Effects11/HISTORY.md
deleted file mode 100644
index a637df49d0..0000000000
--- a/lib/win32/Effects11/HISTORY.md
+++ /dev/null
@@ -1,131 +0,0 @@
-# Effects for Direct3D 11 (FX11)
-
-http://go.microsoft.com/fwlink/?LinkId=271568
-
-## Release History
-
-## August 17, 2022 (11.28)
-* CMake and MSBuild project updates
-
-## May 23, 2022 (11.27)
-* Add VS 2022 projects, retired VS 2017 projects
-* Update build switches for SDL recommendations
-* CMake project cleanup, added CMakePresets.json
-
-## December 2, 2021
-* Minor project cleanup
-
-## February 7, 2021
-* Added CMake project
-* Removed Windows Vista support
-* No code changes
-
-## June 1, 2020
-* Minor update to VS 2019 project
-* Retired VS 2015 projects
-* No code changes
-
-### April 26, 2019 (11.26)
-* Added VS 2019 desktop projects
-* VS 2017 updated for Windows 10 October 2018 Update SDK (17763)
-* Minor code cleanup
-
-### July 12, 2018 (11.25)
-* Added ``D3DX11DebugMute`` function
-* Minor project and code cleanup
-
-### May 31, 2018 (11.24)
-* VS 2017 updated for Windows 10 April 2018 Update SDK (17134)
-
-### May 11, 2018 (11.23)
-* Retired VS 2013 projects
-* Code cleanup
-
-### February 27, 2018 (11.22)
-* Minor code update
-
-### November 2, 2017 (11.21)
-* VS 2017 updated for Windows 10 Fall Creators Update SDK (16299)
-
-### October 13, 2017 (11.20)
-* Updated for VS 2017 update 15.1 - 15.3 and Windows 10 SDK (15063)
-
-### March 10, 2017 (11.19)
-* Add VS 2017 projects
-* Minor code cleanup
-
-### September 15, 2016 (11.18)
-* Minor code cleanup
-
-### August 2, 2016 (11.17)
-* Updated for VS 2015 Update 3 and Windows 10 SDK (14393)
-* Added 'D' suffix to debug libraries per request
-
-### April 26, 2016 (11.16)
-* Retired VS 2012 projects
-* Minor code and project file cleanup
-
-### November 30, 2015 (11.15)
-* Updated for VS 2015 Update 1 and Windows 10 SDK (10586)
-
-### July 29, 2015 (11.14)
-* Updated for VS 2015 and Windows 10 SDK RTM
-* Retired VS 2010 projects
-
-### June 17, 2015 (11.13)
-* Fix for Get/SetFloatVectorArray with an offset
-
-### April 14, 2015 (11.12)
-* More updates for VS 2015
-
-### November 24, 2014 (11.11)
-* Updates for Visual Studio 2015 Technical Preview
-
-### July 15, 2014 (11.10)
-* Minor code review fixes
-
-### January 24, 2014 (11.09)
-* VS 2010 projects now require Windows 8.1 SDK
-* Added pragma for needed libs to public header
-* Minor code cleanup
-
-### October 21, 2013 (11.08)
-* Updated for Visual Studio 2013 and Windows 8.1 SDK RTM
-
-### July 16, 2013 (11.07)
-* Added VS 2013 Preview project files
-* Cleaned up project files
-* Fixed a number of /analyze issues
-
-### June 13, 2013 (11.06)
-* Added ``GetMatrixPointerArray``, ``GetMatrixTransposePointerArray``, ``SetMatrixPointerArray``, ``SetMatrixTransposePointerArray`` methods
-* Reverted back to ``BOOL`` in some cases because sizeof(bool)==1, sizeof(BOOL)==4
-* Some code-cleanup: minor SAL fix, removed bad assert, and added use of override keyword
-
-### February 22, 2013 (11.05)
-* Cleaned up some warning level 4 warnings
-
-### November 6, 2012 (11.04)
-* Added ``IUnknown`` as a base class for all Effects 11 interfaces to simplify use in managed interop sceanrios, although the lifetime for these objects is still based on the lifetime of the parent ID3DX11Effect object. Therefore reference counting is ignored for these interfaces.
- + ID3DX11EffectType, ID3DX11EffectVariable and derived classes, ID3DX11EffectPass, ID3DX11EffectTechnique, and ID3DX11EffectGroup
-
-### October 24, 2012 (11.03)
-* Removed the dependency on the D3DX11 headers, so FX11 no longer requires the legacy DirectX SDK to build.
-* It does require the d3dcompiler.h header from either the Windows 8.0 SDK or from the legacy DirectX SDK
-* Removed references to D3D10 constants and interfaces
-* Deleted the d3dx11dbg.cpp and d3dx11dbg.h files
-* Deleted the ``D3DX11_EFFECT_PASS`` flags which were never implemented
-* General C++ code cleanups (nullptr, C++ style casting, stdint.h types, Safer CRT, etc.) which are compatible with Visual C++ 2010 and 2012
-* SAL2 annotation and /analyze cleanup
-* Added population of Direct3D debug names for object naming support in PIX and the SDK debug layer
-* Added additional optional parameter to D3DX11CreateEffectFromMemory to provide a debug name
-* Added ``D3DX11CreateEffectFromFile``,``D3DX11CompileEffectFromMemory``, and ``D3DX11CompileEffectFromFile``
-
-### June 2010 (11.02)
-The DirectX SDK (June 2010) included an update with some minor additional bug fixes. This also included the Effects 11-based sample DynamicShaderLinkageFX11. This is the last version to support Visual Studio 2008. The source code is located in ``Samples\C++\Effects11``.
-
-### February 2010 (11.01)
-An update was shipped with the DirectX SDK (February 2010). This fixed a problem with the library which prevented it from working correctly on 9.x and 10.x feature levels. This is the last version to support Visual Studio 2005. The source code is located in ``Samples\C++\Effects11``.
-
-### August 2009 (11.00)
-The initial release of Effects 11 (FX11) was in the DirectX SDK (August 2009). The source code is located in ``Utilities\Source\Effects11``. This is essentially the Effects 10 (FX10) system ported to Direct3D 11.0 with support for effects pools removed and support for groups added.
diff --git a/lib/win32/Effects11/IUnknownImp.h b/lib/win32/Effects11/IUnknownImp.h
deleted file mode 100644
index ed3be4111f..0000000000
--- a/lib/win32/Effects11/IUnknownImp.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: IUnknownImp.h
-//
-// Direct3D 11 Effects Helper for COM interop
-//
-// Lifetime for most Effects objects is based on the the lifetime of the master
-// effect, so the reference count is not used.
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-#define IUNKNOWN_IMP(Class, Interface, BaseInterface) \
- \
-HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, _COM_Outptr_ LPVOID *ppv) override \
-{ \
- if( !ppv ) \
- return E_INVALIDARG; \
- \
- *ppv = nullptr; \
- if(IsEqualIID(iid, IID_IUnknown)) \
- { \
- *ppv = (IUnknown*)((Interface*)this); \
- } \
- else if(IsEqualIID(iid, IID_##Interface)) \
- { \
- *ppv = (Interface *)this; \
- } \
- else if(IsEqualIID(iid, IID_##BaseInterface)) \
- { \
- *ppv = (BaseInterface *)this; \
- } \
- else \
- { \
- return E_NOINTERFACE; \
- } \
- \
- return S_OK; \
-} \
- \
-ULONG STDMETHODCALLTYPE AddRef() override \
-{ \
- return 1; \
-} \
- \
-ULONG STDMETHODCALLTYPE Release() override \
-{ \
- return 0; \
-}
diff --git a/lib/win32/Effects11/LICENSE b/lib/win32/Effects11/LICENSE
deleted file mode 100644
index 38e78017b8..0000000000
--- a/lib/win32/Effects11/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
- The MIT License (MIT)
-
-Copyright (c) 2009-2022 Microsoft Corp
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this
-software and associated documentation files (the "Software"), to deal in the Software
-without restriction, including without limitation the rights to use, copy, modify,
-merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be included in all copies
-or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
-OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/lib/win32/Effects11/README.md b/lib/win32/Effects11/README.md
deleted file mode 100644
index 84e3621923..0000000000
--- a/lib/win32/Effects11/README.md
+++ /dev/null
@@ -1,66 +0,0 @@
-![DirectX Logo](https://raw.githubusercontent.com/wiki/Microsoft/FX11/Dx_logo.GIF)
-
-# Effects for Direct3D 11 (FX11)
-
-http://go.microsoft.com/fwlink/?LinkId=271568
-
-Copyright (c) Microsoft Corporation. All rights reserved.
-
-**August 17, 2022**
-
-Effects for Direct3D 11 (FX11) is a management runtime for authoring HLSL shaders, render state, and runtime variables together.
-
-This code is designed to build with Visual Studio 2019 (16.11 or later) or Visual Studio 2022. Use of the Windows 10 May 2020 Update SDK ([19041](https://walbourn.github.io/windows-10-may-2020-update-sdk/)) or later is required.
-
-These components are designed to work without requiring any content from the legacy DirectX SDK. For details, see [Where is the DirectX SDK?](https://aka.ms/dxsdk).
-
-*This project is 'archived'. It is still available for use for legacy projects or when using older developer education materials, but use of it for new projects is not recommended.*
-
-## Disclaimer
-
-Effects 11 is being provided as a porting aid for older code that makes use of the Effects 10 (FX10) API or Effects 9 (FX9)
-API in the deprecated D3DX9 library. See [Microsoft Docs](https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d11-graphics-programming-guide-effects-differences) for a list of differences compared to the Effects 10 (FX10) library.
-
-The Effects 11 library is for use in Win32 desktop applications. FX11 requires the D3DCompiler API be available at runtime
-to provide shader reflection functionality, and this API is not deployable for Windows Store apps on Windows 8.0, Windows RT,
-or Windows phone 8.0.
-
-The fx_5_0 profile support in the HLSL compiler is deprecated, and does not fully support DirectX 11.1 HLSL features
-such as minimum precision types. It is supported in the Windows 8.1 SDK version of the HLSL compiler (FXC.EXE) and
-D3DCompile API (46), is supported but generates a deprecation warning with D3DCompile API (47). The fx profiles
-are not supported by the DXIL (DXC.EXE) compiler.
-
-## Documentation
-
-Documentation is available on the [GitHub wiki](https://github.com/Microsoft/FX11/wiki).
-
-## Notices
-
-All content and source code for this package are subject to the terms of the [MIT License](https://github.com/microsoft/FX11/blob/main/LICENSE).
-
-## Support
-
-For questions, consider using [Stack Overflow](https://stackoverflow.com/questions/tagged/d3dx) with the *d3dx* tag.
-
-## Contributing
-
-This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
-
-## Trademarks
-
-This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.
-
-## Credits
-
-The Effects library for Direct3D 9 (FX9) was the work of Loren McQuade with contributions from Relja Markovic.
-
-The Effects library for Direct3D 10 (FX10) was the work of John Rapp and Kutta Srinivasan as a rewrite of the FX9 library with contributions from Anuj Gosalia, Kev Gee, Sam Glassenberg, Relja Markovic, and Ian McIntyre.
-
-The Effects library for Direct3D 11 (FX11) is the work of Ian McIntyre based on FX10 with contributions from Michael Oneppo and Chuck Walbourn.
-
-## Samples
-
-* Direct3D Tutorial 11-14
-* BasicHLSLFX11, DynamicShaderLinkageFX11, FixedFuncEMUFX11, InstancingFX11
-
-These are hosted on [GitHub](https://github.com/walbourn/directx-sdk-samples)
diff --git a/lib/win32/Effects11/SECURITY.md b/lib/win32/Effects11/SECURITY.md
deleted file mode 100644
index 869fdfe2b2..0000000000
--- a/lib/win32/Effects11/SECURITY.md
+++ /dev/null
@@ -1,41 +0,0 @@
-<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->
-
-## Security
-
-Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
-
-If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
-
-## Reporting Security Issues
-
-**Please do not report security vulnerabilities through public GitHub issues.**
-
-Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
-
-If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
-
-You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
-
-Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
-
- * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
- * Full paths of source file(s) related to the manifestation of the issue
- * The location of the affected source code (tag/branch/commit or direct URL)
- * Any special configuration required to reproduce the issue
- * Step-by-step instructions to reproduce the issue
- * Proof-of-concept or exploit code (if possible)
- * Impact of the issue, including how an attacker might exploit the issue
-
-This information will help us triage your report more quickly.
-
-If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
-
-## Preferred Languages
-
-We prefer all communications to be in English.
-
-## Policy
-
-Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
-
-<!-- END MICROSOFT SECURITY.MD BLOCK -->
diff --git a/lib/win32/Effects11/d3dxGlobal.cpp b/lib/win32/Effects11/d3dxGlobal.cpp
deleted file mode 100644
index 6e22e48b3a..0000000000
--- a/lib/win32/Effects11/d3dxGlobal.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: d3dxGlobal.cpp
-//
-// Direct3D 11 Effects implementation for helper data structures
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#include "pchfx.h"
-
-#include <intsafe.h>
-
-#include <stdio.h>
-#include <stdarg.h>
-
-namespace D3DX11Core
-{
-
-//////////////////////////////////////////////////////////////////////////
-// CMemoryStream - A class to simplify reading binary data
-//////////////////////////////////////////////////////////////////////////
-
-CMemoryStream::CMemoryStream() noexcept :
- m_pData(nullptr),
- m_cbData(0),
- m_readPtr(0)
-{
-}
-
-CMemoryStream::~CMemoryStream()
-{
-}
-
-_Use_decl_annotations_
-HRESULT CMemoryStream::SetData(const void *pData, size_t size)
-{
- m_pData = (uint8_t*) pData;
- m_cbData = size;
- m_readPtr = 0;
-
- return S_OK;
-}
-
-_Use_decl_annotations_
-HRESULT CMemoryStream::ReadAtOffset(size_t offset, size_t size, void **ppData)
-{
- if (offset >= m_cbData)
- return E_FAIL;
-
- m_readPtr = offset;
- return Read(ppData, size);
-}
-
-_Use_decl_annotations_
-HRESULT CMemoryStream::ReadAtOffset(size_t offset, LPCSTR *ppString)
-{
- if (offset >= m_cbData)
- return E_FAIL;
-
- m_readPtr = offset;
- return Read(ppString);
-}
-
-_Use_decl_annotations_
-HRESULT CMemoryStream::Read(void **ppData, size_t size)
-{
- size_t temp = m_readPtr + size;
-
- if (temp < m_readPtr || temp > m_cbData)
- return E_FAIL;
-
- *ppData = m_pData + m_readPtr;
- m_readPtr = temp;
- return S_OK;
-}
-
-_Use_decl_annotations_
-HRESULT CMemoryStream::Read(uint32_t *pDword)
-{
- uint32_t *pTempDword;
- HRESULT hr;
-
- hr = Read((void**) &pTempDword, sizeof(uint32_t));
- if (FAILED(hr))
- return E_FAIL;
-
- *pDword = *pTempDword;
- return S_OK;
-}
-
-_Use_decl_annotations_
-HRESULT CMemoryStream::Read(LPCSTR *ppString)
-{
- size_t iChar=m_readPtr;
- for(; m_pData[iChar]; iChar++)
- {
- if (iChar > m_cbData)
- return E_FAIL;
- }
-
- *ppString = (LPCSTR) (m_pData + m_readPtr);
- m_readPtr = iChar;
-
- return S_OK;
-}
-
-size_t CMemoryStream::GetPosition()
-{
- return m_readPtr;
-}
-
-HRESULT CMemoryStream::Seek(_In_ size_t offset)
-{
- if (offset > m_cbData)
- return E_FAIL;
-
- m_readPtr = offset;
- return S_OK;
-}
-
-}
-
-//////////////////////////////////////////////////////////////////////////
-// CDataBlock - used to dynamically build up the effect file in memory
-//////////////////////////////////////////////////////////////////////////
-
-CDataBlock::CDataBlock() noexcept :
- m_size(0),
- m_maxSize(0),
- m_pData(nullptr),
- m_pNext(nullptr),
- m_IsAligned(false)
-{
-}
-
-CDataBlock::~CDataBlock()
-{
- SAFE_DELETE_ARRAY(m_pData);
- SAFE_DELETE(m_pNext);
-}
-
-void CDataBlock::EnableAlignment()
-{
- m_IsAligned = true;
-}
-
-_Use_decl_annotations_
-HRESULT CDataBlock::AddData(const void *pvNewData, uint32_t bufferSize, CDataBlock **ppBlock)
-{
- HRESULT hr = S_OK;
- uint32_t bytesToCopy;
- const uint8_t *pNewData = (const uint8_t*) pvNewData;
-
- if (m_maxSize == 0)
- {
- // This is a brand new DataBlock, fill it up
- m_maxSize = std::max<uint32_t>(8192, bufferSize);
-
- VN( m_pData = new uint8_t[m_maxSize] );
- }
-
- assert(m_pData == AlignToPowerOf2(m_pData, c_DataAlignment));
-
- bytesToCopy = std::min(m_maxSize - m_size, bufferSize);
- memcpy(m_pData + m_size, pNewData, bytesToCopy);
- pNewData += bytesToCopy;
-
- if (m_IsAligned)
- {
- assert(m_size == AlignToPowerOf2(m_size, c_DataAlignment));
- m_size += AlignToPowerOf2(bytesToCopy, c_DataAlignment);
- }
- else
- {
- m_size += bytesToCopy;
- }
-
- bufferSize -= bytesToCopy;
- *ppBlock = this;
-
- if (bufferSize != 0)
- {
- assert(nullptr == m_pNext); // make sure we're not overwriting anything
-
- // Couldn't fit all data into this block, spill over into next
- VN( m_pNext = new CDataBlock() );
- if (m_IsAligned)
- {
- m_pNext->EnableAlignment();
- }
- VH( m_pNext->AddData(pNewData, bufferSize, ppBlock) );
- }
-
-lExit:
- return hr;
-}
-
-_Use_decl_annotations_
-void* CDataBlock::Allocate(uint32_t bufferSize, CDataBlock **ppBlock)
-{
- void *pRetValue;
- uint32_t temp = m_size + bufferSize;
-
- if (temp < m_size)
- return nullptr;
-
- *ppBlock = this;
-
- if (m_maxSize == 0)
- {
- // This is a brand new DataBlock, fill it up
- m_maxSize = std::max<uint32_t>(8192, bufferSize);
-
- m_pData = new uint8_t[m_maxSize];
- if (!m_pData)
- return nullptr;
- memset(m_pData, 0xDD, m_maxSize);
- }
- else if (temp > m_maxSize)
- {
- assert(nullptr == m_pNext); // make sure we're not overwriting anything
-
- // Couldn't fit data into this block, spill over into next
- m_pNext = new CDataBlock();
- if (!m_pNext)
- return nullptr;
- if (m_IsAligned)
- {
- m_pNext->EnableAlignment();
- }
-
- return m_pNext->Allocate(bufferSize, ppBlock);
- }
-
- assert(m_pData == AlignToPowerOf2(m_pData, c_DataAlignment));
-
- pRetValue = m_pData + m_size;
- if (m_IsAligned)
- {
- assert(m_size == AlignToPowerOf2(m_size, c_DataAlignment));
- m_size = AlignToPowerOf2(temp, c_DataAlignment);
- }
- else
- {
- m_size = temp;
- }
-
- return pRetValue;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-
-CDataBlockStore::CDataBlockStore() noexcept :
- m_pFirst(nullptr),
- m_pLast(nullptr),
- m_Size(0),
- m_Offset(0),
- m_IsAligned(false)
-{
-#ifdef _DEBUG
- m_cAllocations = 0;
-#endif
-}
-
-CDataBlockStore::~CDataBlockStore()
-{
- // Can't just do SAFE_DELETE(m_pFirst) since it blows the stack when deleting long chains of data
- CDataBlock* pData = m_pFirst;
- while(pData)
- {
- CDataBlock* pCurrent = pData;
- pData = pData->m_pNext;
- pCurrent->m_pNext = nullptr;
- delete pCurrent;
- }
-
- // m_pLast will be deleted automatically
-}
-
-void CDataBlockStore::EnableAlignment()
-{
- m_IsAligned = true;
-}
-
-_Use_decl_annotations_
-HRESULT CDataBlockStore::AddString(LPCSTR pString, uint32_t *pOffset)
-{
- size_t strSize = strlen(pString) + 1;
- assert( strSize <= 0xffffffff );
- return AddData(pString, (uint32_t)strSize, pOffset);
-}
-
-_Use_decl_annotations_
-HRESULT CDataBlockStore::AddData(const void *pNewData, uint32_t bufferSize, uint32_t *pCurOffset)
-{
- HRESULT hr = S_OK;
-
- if (bufferSize == 0)
- {
- if (pCurOffset)
- {
- *pCurOffset = 0;
- }
- goto lExit;
- }
-
- if (!m_pFirst)
- {
- VN( m_pFirst = new CDataBlock() );
- if (m_IsAligned)
- {
- m_pFirst->EnableAlignment();
- }
- m_pLast = m_pFirst;
- }
-
- if (pCurOffset)
- *pCurOffset = m_Size + m_Offset;
-
- VH( m_pLast->AddData(pNewData, bufferSize, &m_pLast) );
- m_Size += bufferSize;
-
-lExit:
- return hr;
-}
-
-void* CDataBlockStore::Allocate(_In_ uint32_t bufferSize)
-{
- void *pRetValue = nullptr;
-
-#ifdef _DEBUG
- m_cAllocations++;
-#endif
-
- if (!m_pFirst)
- {
- m_pFirst = new CDataBlock();
- if (!m_pFirst)
- return nullptr;
-
- if (m_IsAligned)
- {
- m_pFirst->EnableAlignment();
- }
- m_pLast = m_pFirst;
- }
-
- if (FAILED(UIntAdd(m_Size, bufferSize, &m_Size)))
- return nullptr;
-
- pRetValue = m_pLast->Allocate(bufferSize, &m_pLast);
- if (!pRetValue)
- return nullptr;
-
- return pRetValue;
-}
-
-uint32_t CDataBlockStore::GetSize()
-{
- return m_Size;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-
-static bool s_mute = false;
-
-bool D3DX11DebugMute(bool mute)
-{
- bool previous = s_mute;
- s_mute = mute;
- return previous;
-}
-
-#ifdef _DEBUG
-_Use_decl_annotations_
-void __cdecl D3DXDebugPrintf(UINT lvl, LPCSTR szFormat, ...)
-{
- if (s_mute)
- return;
-
- UNREFERENCED_PARAMETER(lvl);
-
- char strA[4096] = {};
- char strB[4096] = {};
-
- va_list ap;
- va_start(ap, szFormat);
- vsprintf_s(strA, sizeof(strA), szFormat, ap);
- strA[4095] = '\0';
- va_end(ap);
-
- sprintf_s(strB, sizeof(strB), "Effects11: %s\r\n", strA);
-
- strB[4095] = '\0';
-
- OutputDebugStringA(strB);
-}
-#endif // _DEBUG
diff --git a/lib/win32/Effects11/inc/d3dx11effect.h b/lib/win32/Effects11/inc/d3dx11effect.h
deleted file mode 100644
index 04a17da1ff..0000000000
--- a/lib/win32/Effects11/inc/d3dx11effect.h
+++ /dev/null
@@ -1,1212 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: D3DX11Effect.h
-//
-// Direct3D 11 Effect Types & APIs Header
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-#define D3DX11_EFFECTS_VERSION 1128
-
-#if defined(_XBOX_ONE) && defined(_TITLE)
-#include <d3d11_x.h>
-#define NO_D3D11_DEBUG_NAME
-#else
-#include <d3d11_1.h>
-#include <d3d11shader.h>
-#endif
-
-#pragma comment( lib, "d3dcompiler.lib" )
-#pragma comment( lib, "dxguid.lib" )
-
-#include <stdint.h>
-
-//////////////////////////////////////////////////////////////////////////////
-// File contents:
-//
-// 1) Stateblock enums, structs, interfaces, flat APIs
-// 2) Effect enums, structs, interfaces, flat APIs
-//////////////////////////////////////////////////////////////////////////////
-
-#ifndef D3DX11_BYTES_FROM_BITS
-#define D3DX11_BYTES_FROM_BITS(x) (((x) + 7) / 8)
-#endif // D3DX11_BYTES_FROM_BITS
-
-#ifndef D3DERR_INVALIDCALL
-#define D3DERR_INVALIDCALL MAKE_HRESULT( 1, 0x876, 2156 )
-#endif
-
-struct D3DX11_STATE_BLOCK_MASK
-{
- uint8_t VS;
- uint8_t VSSamplers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT)];
- uint8_t VSShaderResources[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)];
- uint8_t VSConstantBuffers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)];
- uint8_t VSInterfaces[D3DX11_BYTES_FROM_BITS(D3D11_SHADER_MAX_INTERFACES)];
-
- uint8_t HS;
- uint8_t HSSamplers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT)];
- uint8_t HSShaderResources[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)];
- uint8_t HSConstantBuffers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)];
- uint8_t HSInterfaces[D3DX11_BYTES_FROM_BITS(D3D11_SHADER_MAX_INTERFACES)];
-
- uint8_t DS;
- uint8_t DSSamplers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT)];
- uint8_t DSShaderResources[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)];
- uint8_t DSConstantBuffers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)];
- uint8_t DSInterfaces[D3DX11_BYTES_FROM_BITS(D3D11_SHADER_MAX_INTERFACES)];
-
- uint8_t GS;
- uint8_t GSSamplers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT)];
- uint8_t GSShaderResources[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)];
- uint8_t GSConstantBuffers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)];
- uint8_t GSInterfaces[D3DX11_BYTES_FROM_BITS(D3D11_SHADER_MAX_INTERFACES)];
-
- uint8_t PS;
- uint8_t PSSamplers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT)];
- uint8_t PSShaderResources[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)];
- uint8_t PSConstantBuffers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)];
- uint8_t PSInterfaces[D3DX11_BYTES_FROM_BITS(D3D11_SHADER_MAX_INTERFACES)];
- uint8_t PSUnorderedAccessViews;
-
- uint8_t CS;
- uint8_t CSSamplers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT)];
- uint8_t CSShaderResources[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT)];
- uint8_t CSConstantBuffers[D3DX11_BYTES_FROM_BITS(D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT)];
- uint8_t CSInterfaces[D3DX11_BYTES_FROM_BITS(D3D11_SHADER_MAX_INTERFACES)];
- uint8_t CSUnorderedAccessViews;
-
- uint8_t IAVertexBuffers[D3DX11_BYTES_FROM_BITS(D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT)];
- uint8_t IAIndexBuffer;
- uint8_t IAInputLayout;
- uint8_t IAPrimitiveTopology;
-
- uint8_t OMRenderTargets;
- uint8_t OMDepthStencilState;
- uint8_t OMBlendState;
-
- uint8_t RSViewports;
- uint8_t RSScissorRects;
- uint8_t RSRasterizerState;
-
- uint8_t SOBuffers;
-
- uint8_t Predication;
-};
-
-//----------------------------------------------------------------------------
-// D3DX11_EFFECT flags:
-// -------------------------------------
-//
-// These flags are passed in when creating an effect, and affect
-// the runtime effect behavior:
-//
-// (Currently none)
-//
-//
-// These flags are set by the effect runtime:
-//
-// D3DX11_EFFECT_OPTIMIZED
-// This effect has been optimized. Reflection functions that rely on
-// names/semantics/strings should fail. This is set when Optimize() is
-// called, but CEffect::IsOptimized() should be used to test for this.
-//
-// D3DX11_EFFECT_CLONE
-// This effect is a clone of another effect. Single CBs will never be
-// updated when internal variable values are changed.
-// This flag is not set when the D3DX11_EFFECT_CLONE_FORCE_NONSINGLE flag
-// is used in cloning.
-//
-//----------------------------------------------------------------------------
-
-#define D3DX11_EFFECT_OPTIMIZED (1 << 21)
-#define D3DX11_EFFECT_CLONE (1 << 22)
-
-// Mask of valid D3DCOMPILE_EFFECT flags for D3DX11CreateEffect*
-#define D3DX11_EFFECT_RUNTIME_VALID_FLAGS (0)
-
-//----------------------------------------------------------------------------
-// D3DX11_EFFECT_VARIABLE flags:
-// ----------------------------
-//
-// These flags describe an effect variable (global or annotation),
-// and are returned in D3DX11_EFFECT_VARIABLE_DESC::Flags.
-//
-// D3DX11_EFFECT_VARIABLE_ANNOTATION
-// Indicates that this is an annotation on a technique, pass, or global
-// variable. Otherwise, this is a global variable. Annotations cannot
-// be shared.
-//
-// D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT
-// Indicates that the variable has been explicitly bound using the
-// register keyword.
-//----------------------------------------------------------------------------
-
-#define D3DX11_EFFECT_VARIABLE_ANNOTATION (1 << 1)
-#define D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT (1 << 2)
-
-//----------------------------------------------------------------------------
-// D3DX11_EFFECT_CLONE flags:
-// ----------------------------
-//
-// These flags modify the effect cloning process and are passed into Clone.
-//
-// D3DX11_EFFECT_CLONE_FORCE_NONSINGLE
-// Ignore all "single" qualifiers on cbuffers. All cbuffers will have their
-// own ID3D11Buffer's created in the cloned effect.
-//----------------------------------------------------------------------------
-
-#define D3DX11_EFFECT_CLONE_FORCE_NONSINGLE (1 << 0)
-
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectType //////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-//----------------------------------------------------------------------------
-// D3DX11_EFFECT_TYPE_DESC:
-//
-// Retrieved by ID3DX11EffectType::GetDesc()
-//----------------------------------------------------------------------------
-
-struct D3DX11_EFFECT_TYPE_DESC
-{
- LPCSTR TypeName; // Name of the type
- // (e.g. "float4" or "MyStruct")
-
- D3D_SHADER_VARIABLE_CLASS Class; // (e.g. scalar, vector, object, etc.)
- D3D_SHADER_VARIABLE_TYPE Type; // (e.g. float, texture, vertexshader, etc.)
-
- uint32_t Elements; // Number of elements in this type
- // (0 if not an array)
- uint32_t Members; // Number of members
- // (0 if not a structure)
- uint32_t Rows; // Number of rows in this type
- // (0 if not a numeric primitive)
- uint32_t Columns; // Number of columns in this type
- // (0 if not a numeric primitive)
-
- uint32_t PackedSize; // Number of bytes required to represent
- // this data type, when tightly packed
- uint32_t UnpackedSize; // Number of bytes occupied by this data
- // type, when laid out in a constant buffer
- uint32_t Stride; // Number of bytes to seek between elements,
- // when laid out in a constant buffer
-};
-
-typedef interface ID3DX11EffectType ID3DX11EffectType;
-typedef interface ID3DX11EffectType *LPD3D11EFFECTTYPE;
-
-// {4250D721-D5E5-491F-B62B-587C43186285}
-DEFINE_GUID(IID_ID3DX11EffectType,
- 0x4250d721, 0xd5e5, 0x491f, 0xb6, 0x2b, 0x58, 0x7c, 0x43, 0x18, 0x62, 0x85);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectType
-
-DECLARE_INTERFACE_(ID3DX11EffectType, IUnknown)
-{
- // IUnknown
-
- // ID3DX11EffectType
- STDMETHOD_(bool, IsValid)(THIS) PURE;
- STDMETHOD(GetDesc)(THIS_ _Out_ D3DX11_EFFECT_TYPE_DESC *pDesc) PURE;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeByName)(THIS_ _In_z_ LPCSTR Name) PURE;
- STDMETHOD_(ID3DX11EffectType*, GetMemberTypeBySemantic)(THIS_ _In_z_ LPCSTR Semantic) PURE;
- STDMETHOD_(LPCSTR, GetMemberName)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(LPCSTR, GetMemberSemantic)(THIS_ _In_ uint32_t Index) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectVariable //////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-//----------------------------------------------------------------------------
-// D3DX11_EFFECT_VARIABLE_DESC:
-//
-// Retrieved by ID3DX11EffectVariable::GetDesc()
-//----------------------------------------------------------------------------
-
-struct D3DX11_EFFECT_VARIABLE_DESC
-{
- LPCSTR Name; // Name of this variable, annotation,
- // or structure member
- LPCSTR Semantic; // Semantic string of this variable
- // or structure member (nullptr for
- // annotations or if not present)
-
- uint32_t Flags; // D3DX11_EFFECT_VARIABLE_* flags
- uint32_t Annotations; // Number of annotations on this variable
- // (always 0 for annotations)
-
- uint32_t BufferOffset; // Offset into containing cbuffer or tbuffer
- // (always 0 for annotations or variables
- // not in constant buffers)
-
- uint32_t ExplicitBindPoint; // Used if the variable has been explicitly bound
- // using the register keyword. Check Flags for
- // D3DX11_EFFECT_VARIABLE_EXPLICIT_BIND_POINT;
-};
-
-typedef interface ID3DX11EffectVariable ID3DX11EffectVariable;
-typedef interface ID3DX11EffectVariable *LPD3D11EFFECTVARIABLE;
-
-// {036A777D-B56E-4B25-B313-CC3DDAB71873}
-DEFINE_GUID(IID_ID3DX11EffectVariable,
- 0x036a777d, 0xb56e, 0x4b25, 0xb3, 0x13, 0xcc, 0x3d, 0xda, 0xb7, 0x18, 0x73);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectVariable
-
-// Forward defines
-typedef interface ID3DX11EffectScalarVariable ID3DX11EffectScalarVariable;
-typedef interface ID3DX11EffectVectorVariable ID3DX11EffectVectorVariable;
-typedef interface ID3DX11EffectMatrixVariable ID3DX11EffectMatrixVariable;
-typedef interface ID3DX11EffectStringVariable ID3DX11EffectStringVariable;
-typedef interface ID3DX11EffectClassInstanceVariable ID3DX11EffectClassInstanceVariable;
-typedef interface ID3DX11EffectInterfaceVariable ID3DX11EffectInterfaceVariable;
-typedef interface ID3DX11EffectShaderResourceVariable ID3DX11EffectShaderResourceVariable;
-typedef interface ID3DX11EffectUnorderedAccessViewVariable ID3DX11EffectUnorderedAccessViewVariable;
-typedef interface ID3DX11EffectRenderTargetViewVariable ID3DX11EffectRenderTargetViewVariable;
-typedef interface ID3DX11EffectDepthStencilViewVariable ID3DX11EffectDepthStencilViewVariable;
-typedef interface ID3DX11EffectConstantBuffer ID3DX11EffectConstantBuffer;
-typedef interface ID3DX11EffectShaderVariable ID3DX11EffectShaderVariable;
-typedef interface ID3DX11EffectBlendVariable ID3DX11EffectBlendVariable;
-typedef interface ID3DX11EffectDepthStencilVariable ID3DX11EffectDepthStencilVariable;
-typedef interface ID3DX11EffectRasterizerVariable ID3DX11EffectRasterizerVariable;
-typedef interface ID3DX11EffectSamplerVariable ID3DX11EffectSamplerVariable;
-
-DECLARE_INTERFACE_(ID3DX11EffectVariable, IUnknown)
-{
- // IUnknown
-
- // ID3DX11EffectVariable
- STDMETHOD_(bool, IsValid)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectType*, GetType)(THIS) PURE;
- STDMETHOD(GetDesc)(THIS_ _Out_ D3DX11_EFFECT_VARIABLE_DESC *pDesc) PURE;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberByName)(THIS_ _In_z_ LPCSTR Name) PURE;
- STDMETHOD_(ID3DX11EffectVariable*, GetMemberBySemantic)(THIS_ _In_z_ LPCSTR Semantic) PURE;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetElement)(THIS_ _In_ uint32_t Index) PURE;
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetParentConstantBuffer)(THIS) PURE;
-
- STDMETHOD_(ID3DX11EffectScalarVariable*, AsScalar)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectVectorVariable*, AsVector)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectMatrixVariable*, AsMatrix)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectStringVariable*, AsString)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectClassInstanceVariable*, AsClassInstance)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectInterfaceVariable*, AsInterface)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectShaderResourceVariable*, AsShaderResource)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectUnorderedAccessViewVariable*, AsUnorderedAccessView)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectRenderTargetViewVariable*, AsRenderTargetView)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectDepthStencilViewVariable*, AsDepthStencilView)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectConstantBuffer*, AsConstantBuffer)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectShaderVariable*, AsShader)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectBlendVariable*, AsBlend)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectDepthStencilVariable*, AsDepthStencil)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectRasterizerVariable*, AsRasterizer)(THIS) PURE;
- STDMETHOD_(ID3DX11EffectSamplerVariable*, AsSampler)(THIS) PURE;
-
- STDMETHOD(SetRawValue)(THIS_ _In_reads_bytes_(ByteCount) const void *pData, _In_ uint32_t ByteOffset, _In_ uint32_t ByteCount) PURE;
- STDMETHOD(GetRawValue)(THIS_ _Out_writes_bytes_(ByteCount) void *pData, _In_ uint32_t ByteOffset, _In_ uint32_t ByteCount) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectScalarVariable ////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectScalarVariable ID3DX11EffectScalarVariable;
-typedef interface ID3DX11EffectScalarVariable *LPD3D11EFFECTSCALARVARIABLE;
-
-// {921EF2E5-A65D-4E92-9FC6-4E9CC09A4ADE}
-DEFINE_GUID(IID_ID3DX11EffectScalarVariable,
- 0x921ef2e5, 0xa65d, 0x4e92, 0x9f, 0xc6, 0x4e, 0x9c, 0xc0, 0x9a, 0x4a, 0xde);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectScalarVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectScalarVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectScalarVariable
- STDMETHOD(SetFloat)(THIS_ _In_ const float Value) PURE;
- STDMETHOD(GetFloat)(THIS_ _Out_ float *pValue) PURE;
-
- STDMETHOD(SetFloatArray)(THIS_ _In_reads_(Count) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetFloatArray)(THIS_ _Out_writes_(Count) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-
- STDMETHOD(SetInt)(THIS_ _In_ const int Value) PURE;
- STDMETHOD(GetInt)(THIS_ _Out_ int *pValue) PURE;
-
- STDMETHOD(SetIntArray)(THIS_ _In_reads_(Count) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetIntArray)(THIS_ _Out_writes_(Count) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-
- STDMETHOD(SetBool)(THIS_ _In_ const bool Value) PURE;
- STDMETHOD(GetBool)(THIS_ _Out_ bool *pValue) PURE;
-
- STDMETHOD(SetBoolArray)(THIS_ _In_reads_(Count) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetBoolArray)(THIS_ _Out_writes_(Count) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectVectorVariable ////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectVectorVariable ID3DX11EffectVectorVariable;
-typedef interface ID3DX11EffectVectorVariable *LPD3D11EFFECTVECTORVARIABLE;
-
-// {5E785D4A-D87B-48D8-B6E6-0F8CA7E7467A}
-DEFINE_GUID(IID_ID3DX11EffectVectorVariable,
- 0x5e785d4a, 0xd87b, 0x48d8, 0xb6, 0xe6, 0x0f, 0x8c, 0xa7, 0xe7, 0x46, 0x7a);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectVectorVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectVectorVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectVectorVariable
- STDMETHOD(SetBoolVector) (THIS_ _In_reads_(4) const bool *pData) PURE;
- STDMETHOD(SetIntVector) (THIS_ _In_reads_(4) const int *pData) PURE;
- STDMETHOD(SetFloatVector)(THIS_ _In_reads_(4) const float *pData) PURE;
-
- STDMETHOD(GetBoolVector) (THIS_ _Out_writes_(4) bool *pData) PURE;
- STDMETHOD(GetIntVector) (THIS_ _Out_writes_(4) int *pData) PURE;
- STDMETHOD(GetFloatVector)(THIS_ _Out_writes_(4) float *pData) PURE;
-
- STDMETHOD(SetBoolVectorArray) (THIS_ _In_reads_(Count*4) const bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(SetIntVectorArray) (THIS_ _In_reads_(Count*4) const int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(SetFloatVectorArray)(THIS_ _In_reads_(Count*4) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-
- STDMETHOD(GetBoolVectorArray) (THIS_ _Out_writes_(Count*4) bool *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetIntVectorArray) (THIS_ _Out_writes_(Count*4) int *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetFloatVectorArray)(THIS_ _Out_writes_(Count*4) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectMatrixVariable ////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectMatrixVariable ID3DX11EffectMatrixVariable;
-typedef interface ID3DX11EffectMatrixVariable *LPD3D11EFFECTMATRIXVARIABLE;
-
-// {E1096CF4-C027-419A-8D86-D29173DC803E}
-DEFINE_GUID(IID_ID3DX11EffectMatrixVariable,
- 0xe1096cf4, 0xc027, 0x419a, 0x8d, 0x86, 0xd2, 0x91, 0x73, 0xdc, 0x80, 0x3e);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectMatrixVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectMatrixVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectMatrixVariable
- STDMETHOD(SetMatrix)(THIS_ _In_reads_(16) const float *pData) PURE;
- STDMETHOD(GetMatrix)(THIS_ _Out_writes_(16) float *pData) PURE;
-
- STDMETHOD(SetMatrixArray)(THIS_ _In_reads_(Count*16) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetMatrixArray)(THIS_ _Out_writes_(Count*16) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-
- STDMETHOD(SetMatrixPointerArray)(_In_reads_(Count*16) const float **ppData, uint32_t Offset, uint32_t Count) PURE;
- STDMETHOD(GetMatrixPointerArray)(_Out_writes_(Count*16) float **ppData, uint32_t Offset, uint32_t Count) PURE;
-
- STDMETHOD(SetMatrixTranspose)(THIS_ _In_reads_(16) const float *pData) PURE;
- STDMETHOD(GetMatrixTranspose)(THIS_ _Out_writes_(16) float *pData) PURE;
-
- STDMETHOD(SetMatrixTransposeArray)(THIS_ _In_reads_(Count*16) const float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetMatrixTransposeArray)(THIS_ _Out_writes_(Count*16) float *pData, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-
- STDMETHOD(SetMatrixTransposePointerArray)(_In_reads_(Count*16) const float **ppData, uint32_t Offset, uint32_t Count) PURE;
- STDMETHOD(GetMatrixTransposePointerArray)(_Out_writes_(Count*16) float **ppData, uint32_t Offset, uint32_t Count) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectStringVariable ////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectStringVariable ID3DX11EffectStringVariable;
-typedef interface ID3DX11EffectStringVariable *LPD3D11EFFECTSTRINGVARIABLE;
-
-// {F355C818-01BE-4653-A7CC-60FFFEDDC76D}
-DEFINE_GUID(IID_ID3DX11EffectStringVariable,
- 0xf355c818, 0x01be, 0x4653, 0xa7, 0xcc, 0x60, 0xff, 0xfe, 0xdd, 0xc7, 0x6d);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectStringVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectStringVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectStringVariable
- STDMETHOD(GetString)(THIS_ _Outptr_result_z_ LPCSTR *ppString) PURE;
- STDMETHOD(GetStringArray)(THIS_ _Out_writes_(Count) LPCSTR *ppStrings, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectClassInstanceVariable ////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectClassInstanceVariable ID3DX11EffectClassInstanceVariable;
-typedef interface ID3DX11EffectClassInstanceVariable *LPD3D11EFFECTCLASSINSTANCEVARIABLE;
-
-// {926A8053-2A39-4DB4-9BDE-CF649ADEBDC1}
-DEFINE_GUID(IID_ID3DX11EffectClassInstanceVariable,
- 0x926a8053, 0x2a39, 0x4db4, 0x9b, 0xde, 0xcf, 0x64, 0x9a, 0xde, 0xbd, 0xc1);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectClassInstanceVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectClassInstanceVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectClassInstanceVariable
- STDMETHOD(GetClassInstance)(_Outptr_ ID3D11ClassInstance** ppClassInstance) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectInterfaceVariable ////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectInterfaceVariable ID3DX11EffectInterfaceVariable;
-typedef interface ID3DX11EffectInterfaceVariable *LPD3D11EFFECTINTERFACEVARIABLE;
-
-// {516C8CD8-1C80-40A4-B19B-0688792F11A5}
-DEFINE_GUID(IID_ID3DX11EffectInterfaceVariable,
- 0x516c8cd8, 0x1c80, 0x40a4, 0xb1, 0x9b, 0x06, 0x88, 0x79, 0x2f, 0x11, 0xa5);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectInterfaceVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectInterfaceVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectInterfaceVariable
- STDMETHOD(SetClassInstance)(_In_ ID3DX11EffectClassInstanceVariable *pEffectClassInstance) PURE;
- STDMETHOD(GetClassInstance)(_Outptr_ ID3DX11EffectClassInstanceVariable **ppEffectClassInstance) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectShaderResourceVariable ////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectShaderResourceVariable ID3DX11EffectShaderResourceVariable;
-typedef interface ID3DX11EffectShaderResourceVariable *LPD3D11EFFECTSHADERRESOURCEVARIABLE;
-
-// {350DB233-BBE0-485C-9BFE-C0026B844F89}
-DEFINE_GUID(IID_ID3DX11EffectShaderResourceVariable,
- 0x350db233, 0xbbe0, 0x485c, 0x9b, 0xfe, 0xc0, 0x02, 0x6b, 0x84, 0x4f, 0x89);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectShaderResourceVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectShaderResourceVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectShaderResourceVariable
- STDMETHOD(SetResource)(THIS_ _In_ ID3D11ShaderResourceView *pResource) PURE;
- STDMETHOD(GetResource)(THIS_ _Outptr_ ID3D11ShaderResourceView **ppResource) PURE;
-
- STDMETHOD(SetResourceArray)(THIS_ _In_reads_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetResourceArray)(THIS_ _Out_writes_(Count) ID3D11ShaderResourceView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectUnorderedAccessViewVariable ////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectUnorderedAccessViewVariable ID3DX11EffectUnorderedAccessViewVariable;
-typedef interface ID3DX11EffectUnorderedAccessViewVariable *LPD3D11EFFECTUNORDEREDACCESSVIEWVARIABLE;
-
-// {79B4AC8C-870A-47D2-B05A-8BD5CC3EE6C9}
-DEFINE_GUID(IID_ID3DX11EffectUnorderedAccessViewVariable,
- 0x79b4ac8c, 0x870a, 0x47d2, 0xb0, 0x5a, 0x8b, 0xd5, 0xcc, 0x3e, 0xe6, 0xc9);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectUnorderedAccessViewVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectUnorderedAccessViewVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectUnorderedAccessViewVariable
- STDMETHOD(SetUnorderedAccessView)(THIS_ _In_ ID3D11UnorderedAccessView *pResource) PURE;
- STDMETHOD(GetUnorderedAccessView)(THIS_ _Outptr_ ID3D11UnorderedAccessView **ppResource) PURE;
-
- STDMETHOD(SetUnorderedAccessViewArray)(THIS_ _In_reads_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetUnorderedAccessViewArray)(THIS_ _Out_writes_(Count) ID3D11UnorderedAccessView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectRenderTargetViewVariable //////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectRenderTargetViewVariable ID3DX11EffectRenderTargetViewVariable;
-typedef interface ID3DX11EffectRenderTargetViewVariable *LPD3D11EFFECTRENDERTARGETVIEWVARIABLE;
-
-// {D5066909-F40C-43F8-9DB5-057C2A208552}
-DEFINE_GUID(IID_ID3DX11EffectRenderTargetViewVariable,
- 0xd5066909, 0xf40c, 0x43f8, 0x9d, 0xb5, 0x05, 0x7c, 0x2a, 0x20, 0x85, 0x52);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectRenderTargetViewVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectRenderTargetViewVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectRenderTargetViewVariable
- STDMETHOD(SetRenderTarget)(THIS_ _In_ ID3D11RenderTargetView *pResource) PURE;
- STDMETHOD(GetRenderTarget)(THIS_ _Outptr_ ID3D11RenderTargetView **ppResource) PURE;
-
- STDMETHOD(SetRenderTargetArray)(THIS_ _In_reads_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetRenderTargetArray)(THIS_ _Out_writes_(Count) ID3D11RenderTargetView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectDepthStencilViewVariable //////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectDepthStencilViewVariable ID3DX11EffectDepthStencilViewVariable;
-typedef interface ID3DX11EffectDepthStencilViewVariable *LPD3D11EFFECTDEPTHSTENCILVIEWVARIABLE;
-
-// {33C648AC-2E9E-4A2E-9CD6-DE31ACC5B347}
-DEFINE_GUID(IID_ID3DX11EffectDepthStencilViewVariable,
- 0x33c648ac, 0x2e9e, 0x4a2e, 0x9c, 0xd6, 0xde, 0x31, 0xac, 0xc5, 0xb3, 0x47);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectDepthStencilViewVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectDepthStencilViewVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectDepthStencilViewVariable
- STDMETHOD(SetDepthStencil)(THIS_ _In_ ID3D11DepthStencilView *pResource) PURE;
- STDMETHOD(GetDepthStencil)(THIS_ _Outptr_ ID3D11DepthStencilView **ppResource) PURE;
-
- STDMETHOD(SetDepthStencilArray)(THIS_ _In_reads_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
- STDMETHOD(GetDepthStencilArray)(THIS_ _Out_writes_(Count) ID3D11DepthStencilView **ppResources, _In_ uint32_t Offset, _In_ uint32_t Count) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectConstantBuffer ////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectConstantBuffer ID3DX11EffectConstantBuffer;
-typedef interface ID3DX11EffectConstantBuffer *LPD3D11EFFECTCONSTANTBUFFER;
-
-// {2CB6C733-82D2-4000-B3DA-6219D9A99BF2}
-DEFINE_GUID(IID_ID3DX11EffectConstantBuffer,
- 0x2cb6c733, 0x82d2, 0x4000, 0xb3, 0xda, 0x62, 0x19, 0xd9, 0xa9, 0x9b, 0xf2);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectConstantBuffer
-
-DECLARE_INTERFACE_(ID3DX11EffectConstantBuffer, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectConstantBuffer
- STDMETHOD(SetConstantBuffer)(THIS_ _In_ ID3D11Buffer *pConstantBuffer) PURE;
- STDMETHOD(UndoSetConstantBuffer)(THIS) PURE;
- STDMETHOD(GetConstantBuffer)(THIS_ _Outptr_ ID3D11Buffer **ppConstantBuffer) PURE;
-
- STDMETHOD(SetTextureBuffer)(THIS_ _In_ ID3D11ShaderResourceView *pTextureBuffer) PURE;
- STDMETHOD(UndoSetTextureBuffer)(THIS) PURE;
- STDMETHOD(GetTextureBuffer)(THIS_ _Outptr_ ID3D11ShaderResourceView **ppTextureBuffer) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectShaderVariable ////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-//----------------------------------------------------------------------------
-// D3DX11_EFFECT_SHADER_DESC:
-//
-// Retrieved by ID3DX11EffectShaderVariable::GetShaderDesc()
-//----------------------------------------------------------------------------
-
-struct D3DX11_EFFECT_SHADER_DESC
-{
- const uint8_t *pInputSignature; // Passed into CreateInputLayout,
- // valid on VS and GS only
-
- bool IsInline; // Is this an anonymous shader variable
- // resulting from an inline shader assignment?
-
-
- // -- The following fields are not valid after Optimize() --
- const uint8_t *pBytecode; // Shader bytecode
- uint32_t BytecodeLength;
-
- LPCSTR SODecls[D3D11_SO_STREAM_COUNT]; // Stream out declaration string (for GS with SO)
- uint32_t RasterizedStream;
-
- uint32_t NumInputSignatureEntries; // Number of entries in the input signature
- uint32_t NumOutputSignatureEntries; // Number of entries in the output signature
- uint32_t NumPatchConstantSignatureEntries; // Number of entries in the patch constant signature
-};
-
-
-typedef interface ID3DX11EffectShaderVariable ID3DX11EffectShaderVariable;
-typedef interface ID3DX11EffectShaderVariable *LPD3D11EFFECTSHADERVARIABLE;
-
-// {7508B344-020A-4EC7-9118-62CDD36C88D7}
-DEFINE_GUID(IID_ID3DX11EffectShaderVariable,
- 0x7508b344, 0x020a, 0x4ec7, 0x91, 0x18, 0x62, 0xcd, 0xd3, 0x6c, 0x88, 0xd7);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectShaderVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectShaderVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectShaderVariable
- STDMETHOD(GetShaderDesc)(THIS_ _In_ uint32_t ShaderIndex, _Out_ D3DX11_EFFECT_SHADER_DESC *pDesc) PURE;
-
- STDMETHOD(GetVertexShader)(THIS_ _In_ uint32_t ShaderIndex, _Outptr_ ID3D11VertexShader **ppVS) PURE;
- STDMETHOD(GetGeometryShader)(THIS_ _In_ uint32_t ShaderIndex, _Outptr_ ID3D11GeometryShader **ppGS) PURE;
- STDMETHOD(GetPixelShader)(THIS_ _In_ uint32_t ShaderIndex, _Outptr_ ID3D11PixelShader **ppPS) PURE;
- STDMETHOD(GetHullShader)(THIS_ _In_ uint32_t ShaderIndex, _Outptr_ ID3D11HullShader **ppHS) PURE;
- STDMETHOD(GetDomainShader)(THIS_ _In_ uint32_t ShaderIndex, _Outptr_ ID3D11DomainShader **ppDS) PURE;
- STDMETHOD(GetComputeShader)(THIS_ _In_ uint32_t ShaderIndex, _Outptr_ ID3D11ComputeShader **ppCS) PURE;
-
- STDMETHOD(GetInputSignatureElementDesc)(THIS_ _In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
- STDMETHOD(GetOutputSignatureElementDesc)(THIS_ _In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
- STDMETHOD(GetPatchConstantSignatureElementDesc)(THIS_ _In_ uint32_t ShaderIndex, _In_ uint32_t Element, _Out_ D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectBlendVariable /////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectBlendVariable ID3DX11EffectBlendVariable;
-typedef interface ID3DX11EffectBlendVariable *LPD3D11EFFECTBLENDVARIABLE;
-
-// {D664F4D7-3B81-4805-B277-C1DF58C39F53}
-DEFINE_GUID(IID_ID3DX11EffectBlendVariable,
- 0xd664f4d7, 0x3b81, 0x4805, 0xb2, 0x77, 0xc1, 0xdf, 0x58, 0xc3, 0x9f, 0x53);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectBlendVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectBlendVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectBlendVariable
- STDMETHOD(GetBlendState)(THIS_ _In_ uint32_t Index, _Outptr_ ID3D11BlendState **ppState) PURE;
- STDMETHOD(SetBlendState)(THIS_ _In_ uint32_t Index, _In_ ID3D11BlendState *pState) PURE;
- STDMETHOD(UndoSetBlendState)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD(GetBackingStore)(THIS_ _In_ uint32_t Index, _Out_ D3D11_BLEND_DESC *pDesc) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectDepthStencilVariable //////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectDepthStencilVariable ID3DX11EffectDepthStencilVariable;
-typedef interface ID3DX11EffectDepthStencilVariable *LPD3D11EFFECTDEPTHSTENCILVARIABLE;
-
-// {69B5751B-61A5-48E5-BD41-D93988111563}
-DEFINE_GUID(IID_ID3DX11EffectDepthStencilVariable,
- 0x69b5751b, 0x61a5, 0x48e5, 0xbd, 0x41, 0xd9, 0x39, 0x88, 0x11, 0x15, 0x63);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectDepthStencilVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectDepthStencilVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectDepthStencilVariable
- STDMETHOD(GetDepthStencilState)(THIS_ _In_ uint32_t Index, _Outptr_ ID3D11DepthStencilState **ppState) PURE;
- STDMETHOD(SetDepthStencilState)(THIS_ _In_ uint32_t Index, _In_ ID3D11DepthStencilState *pState) PURE;
- STDMETHOD(UndoSetDepthStencilState)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD(GetBackingStore)(THIS_ _In_ uint32_t Index, _Out_ D3D11_DEPTH_STENCIL_DESC *pDesc) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectRasterizerVariable ////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectRasterizerVariable ID3DX11EffectRasterizerVariable;
-typedef interface ID3DX11EffectRasterizerVariable *LPD3D11EFFECTRASTERIZERVARIABLE;
-
-// {53A262F6-5F74-4151-A132-E3DD19A62C9D}
-DEFINE_GUID(IID_ID3DX11EffectRasterizerVariable,
- 0x53a262f6, 0x5f74, 0x4151, 0xa1, 0x32, 0xe3, 0xdd, 0x19, 0xa6, 0x2c, 0x9d);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectRasterizerVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectRasterizerVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectRasterizerVariable
- STDMETHOD(GetRasterizerState)(THIS_ _In_ uint32_t Index, _Outptr_ ID3D11RasterizerState **ppState) PURE;
- STDMETHOD(SetRasterizerState)(THIS_ _In_ uint32_t Index, _In_ ID3D11RasterizerState *pState) PURE;
- STDMETHOD(UndoSetRasterizerState)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD(GetBackingStore)(THIS_ _In_ uint32_t Index, _Out_ D3D11_RASTERIZER_DESC *pDesc) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectSamplerVariable ///////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-typedef interface ID3DX11EffectSamplerVariable ID3DX11EffectSamplerVariable;
-typedef interface ID3DX11EffectSamplerVariable *LPD3D11EFFECTSAMPLERVARIABLE;
-
-// {C6402E55-1095-4D95-8931-F92660513DD9}
-DEFINE_GUID(IID_ID3DX11EffectSamplerVariable,
- 0xc6402e55, 0x1095, 0x4d95, 0x89, 0x31, 0xf9, 0x26, 0x60, 0x51, 0x3d, 0xd9);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectSamplerVariable
-
-DECLARE_INTERFACE_(ID3DX11EffectSamplerVariable, ID3DX11EffectVariable)
-{
- // IUnknown
- // ID3DX11EffectVariable
-
- // ID3DX11EffectSamplerVariable
- STDMETHOD(GetSampler)(THIS_ _In_ uint32_t Index, _Outptr_ ID3D11SamplerState **ppSampler) PURE;
- STDMETHOD(SetSampler)(THIS_ _In_ uint32_t Index, _In_ ID3D11SamplerState *pSampler) PURE;
- STDMETHOD(UndoSetSampler)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD(GetBackingStore)(THIS_ _In_ uint32_t Index, _Out_ D3D11_SAMPLER_DESC *pDesc) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectPass //////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-//----------------------------------------------------------------------------
-// D3DX11_PASS_DESC:
-//
-// Retrieved by ID3DX11EffectPass::GetDesc()
-//----------------------------------------------------------------------------
-
-struct D3DX11_PASS_DESC
-{
- LPCSTR Name; // Name of this pass (nullptr if not anonymous)
- uint32_t Annotations; // Number of annotations on this pass
-
- uint8_t *pIAInputSignature; // Signature from VS or GS (if there is no VS)
- // or nullptr if neither exists
- size_t IAInputSignatureSize; // Singature size in bytes
-
- uint32_t StencilRef; // Specified in SetDepthStencilState()
- uint32_t SampleMask; // Specified in SetBlendState()
- FLOAT BlendFactor[4]; // Specified in SetBlendState()
-};
-
-//----------------------------------------------------------------------------
-// D3DX11_PASS_SHADER_DESC:
-//
-// Retrieved by ID3DX11EffectPass::Get**ShaderDesc()
-//----------------------------------------------------------------------------
-
-struct D3DX11_PASS_SHADER_DESC
-{
- ID3DX11EffectShaderVariable *pShaderVariable; // The variable that this shader came from.
- // If this is an inline shader assignment,
- // the returned interface will be an
- // anonymous shader variable, which is
- // not retrievable any other way. It's
- // name in the variable description will
- // be "$Anonymous".
- // If there is no assignment of this type in
- // the pass block, pShaderVariable != nullptr,
- // but pShaderVariable->IsValid() == false.
-
- uint32_t ShaderIndex; // The element of pShaderVariable (if an array)
- // or 0 if not applicable
-};
-
-typedef interface ID3DX11EffectPass ID3DX11EffectPass;
-typedef interface ID3DX11EffectPass *LPD3D11EFFECTPASS;
-
-// {3437CEC4-4AC1-4D87-8916-F4BD5A41380C}
-DEFINE_GUID(IID_ID3DX11EffectPass,
- 0x3437cec4, 0x4ac1, 0x4d87, 0x89, 0x16, 0xf4, 0xbd, 0x5a, 0x41, 0x38, 0x0c);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectPass
-
-DECLARE_INTERFACE_(ID3DX11EffectPass, IUnknown)
-{
- // IUnknown
-
- // ID3DX11EffectPass
- STDMETHOD_(bool, IsValid)(THIS) PURE;
- STDMETHOD(GetDesc)(THIS_ _Out_ D3DX11_PASS_DESC *pDesc) PURE;
-
- STDMETHOD(GetVertexShaderDesc)(THIS_ _Out_ D3DX11_PASS_SHADER_DESC *pDesc) PURE;
- STDMETHOD(GetGeometryShaderDesc)(THIS_ _Out_ D3DX11_PASS_SHADER_DESC *pDesc) PURE;
- STDMETHOD(GetPixelShaderDesc)(THIS_ _Out_ D3DX11_PASS_SHADER_DESC *pDesc) PURE;
- STDMETHOD(GetHullShaderDesc)(THIS_ _Out_ D3DX11_PASS_SHADER_DESC *pDesc) PURE;
- STDMETHOD(GetDomainShaderDesc)(THIS_ _Out_ D3DX11_PASS_SHADER_DESC *pDesc) PURE;
- STDMETHOD(GetComputeShaderDesc)(THIS_ _Out_ D3DX11_PASS_SHADER_DESC *pDesc) PURE;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-
- STDMETHOD(Apply)(THIS_ _In_ uint32_t Flags, _In_ ID3D11DeviceContext* pContext) PURE;
-
- STDMETHOD(ComputeStateBlockMask)(THIS_ _Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectTechnique /////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-//----------------------------------------------------------------------------
-// D3DX11_TECHNIQUE_DESC:
-//
-// Retrieved by ID3DX11EffectTechnique::GetDesc()
-//----------------------------------------------------------------------------
-
-struct D3DX11_TECHNIQUE_DESC
-{
- LPCSTR Name; // Name of this technique (nullptr if not anonymous)
- uint32_t Passes; // Number of passes contained within
- uint32_t Annotations; // Number of annotations on this technique
-};
-
-typedef interface ID3DX11EffectTechnique ID3DX11EffectTechnique;
-typedef interface ID3DX11EffectTechnique *LPD3D11EFFECTTECHNIQUE;
-
-// {51198831-1F1D-4F47-BD76-41CB0835B1DE}
-DEFINE_GUID(IID_ID3DX11EffectTechnique,
- 0x51198831, 0x1f1d, 0x4f47, 0xbd, 0x76, 0x41, 0xcb, 0x08, 0x35, 0xb1, 0xde);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectTechnique
-
-DECLARE_INTERFACE_(ID3DX11EffectTechnique, IUnknown)
-{
- // IUnknown
-
- // ID3DX11EffectTechnique
- STDMETHOD_(bool, IsValid)(THIS) PURE;
- STDMETHOD(GetDesc)(THIS_ _Out_ D3DX11_TECHNIQUE_DESC *pDesc) PURE;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-
- STDMETHOD_(ID3DX11EffectPass*, GetPassByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectPass*, GetPassByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-
- STDMETHOD(ComputeStateBlockMask)(THIS_ _Inout_ D3DX11_STATE_BLOCK_MASK *pStateBlockMask) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11EffectTechnique /////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-//----------------------------------------------------------------------------
-// D3DX11_GROUP_DESC:
-//
-// Retrieved by ID3DX11EffectTechnique::GetDesc()
-//----------------------------------------------------------------------------
-
-struct D3DX11_GROUP_DESC
-{
- LPCSTR Name; // Name of this group (only nullptr if global)
- uint32_t Techniques; // Number of techniques contained within
- uint32_t Annotations; // Number of annotations on this group
-};
-
-typedef interface ID3DX11EffectGroup ID3DX11EffectGroup;
-typedef interface ID3DX11EffectGroup *LPD3D11EFFECTGROUP;
-
-// {03074acf-97de-485f-b201-cb775264afd6}
-DEFINE_GUID(IID_ID3DX11EffectGroup,
- 0x03074acf, 0x97de, 0x485f, 0xb2, 0x01, 0xcb, 0x77, 0x52, 0x64, 0xaf, 0xd6);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11EffectGroup
-
-DECLARE_INTERFACE_(ID3DX11EffectGroup, IUnknown)
-{
- // IUnknown
-
- // ID3DX11EffectGroup
- STDMETHOD_(bool, IsValid)(THIS) PURE;
- STDMETHOD(GetDesc)(THIS_ _Out_ D3DX11_GROUP_DESC *pDesc) PURE;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectVariable*, GetAnnotationByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// ID3DX11Effect //////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-//----------------------------------------------------------------------------
-// D3DX11_EFFECT_DESC:
-//
-// Retrieved by ID3DX11Effect::GetDesc()
-//----------------------------------------------------------------------------
-
-struct D3DX11_EFFECT_DESC
-{
- uint32_t ConstantBuffers; // Number of constant buffers in this effect
- uint32_t GlobalVariables; // Number of global variables in this effect
- uint32_t InterfaceVariables; // Number of global interfaces in this effect
- uint32_t Techniques; // Number of techniques in this effect
- uint32_t Groups; // Number of groups in this effect
-};
-
-typedef interface ID3DX11Effect ID3DX11Effect;
-typedef interface ID3DX11Effect *LPD3D11EFFECT;
-
-// {FA61CA24-E4BA-4262-9DB8-B132E8CAE319}
-DEFINE_GUID(IID_ID3DX11Effect,
- 0xfa61ca24, 0xe4ba, 0x4262, 0x9d, 0xb8, 0xb1, 0x32, 0xe8, 0xca, 0xe3, 0x19);
-
-#undef INTERFACE
-#define INTERFACE ID3DX11Effect
-
-DECLARE_INTERFACE_(ID3DX11Effect, IUnknown)
-{
- // IUnknown
-
- // ID3DX11Effect
- STDMETHOD_(bool, IsValid)(THIS) PURE;
-
- STDMETHOD(GetDevice)(THIS_ _Outptr_ ID3D11Device** ppDevice) PURE;
-
- STDMETHOD(GetDesc)(THIS_ _Out_ D3DX11_EFFECT_DESC *pDesc) PURE;
-
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetConstantBufferByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectConstantBuffer*, GetConstantBufferByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-
- STDMETHOD_(ID3DX11EffectVariable*, GetVariableByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectVariable*, GetVariableByName)(THIS_ _In_z_ LPCSTR Name) PURE;
- STDMETHOD_(ID3DX11EffectVariable*, GetVariableBySemantic)(THIS_ _In_z_ LPCSTR Semantic) PURE;
-
- STDMETHOD_(ID3DX11EffectGroup*, GetGroupByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectGroup*, GetGroupByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByIndex)(THIS_ _In_ uint32_t Index) PURE;
- STDMETHOD_(ID3DX11EffectTechnique*, GetTechniqueByName)(THIS_ _In_z_ LPCSTR Name) PURE;
-
- STDMETHOD_(ID3D11ClassLinkage*, GetClassLinkage)(THIS) PURE;
-
- STDMETHOD(CloneEffect)(THIS_ _In_ uint32_t Flags, _Outptr_ ID3DX11Effect** ppClonedEffect ) PURE;
- STDMETHOD(Optimize)(THIS) PURE;
- STDMETHOD_(bool, IsOptimized)(THIS) PURE;
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// APIs //////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-#ifdef __cplusplus
-extern "C" {
-#endif //__cplusplus
-
-//----------------------------------------------------------------------------
-// D3DX11CreateEffectFromMemory
-//
-// Creates an effect instance from a compiled effect in memory
-//
-// Parameters:
-//
-// [in]
-//
-// pData
-// Blob of compiled effect data
-// DataLength
-// Length of the data blob
-// FXFlags
-// Flags pertaining to Effect creation
-// pDevice
-// Pointer to the D3D11 device on which to create Effect resources
-// srcName [optional]
-// ASCII string to use for debug object naming
-//
-// [out]
-//
-// ppEffect
-// Address of the newly created Effect interface
-//
-//----------------------------------------------------------------------------
-
-HRESULT WINAPI D3DX11CreateEffectFromMemory( _In_reads_bytes_(DataLength) LPCVOID pData,
- _In_ SIZE_T DataLength,
- _In_ UINT FXFlags,
- _In_ ID3D11Device *pDevice,
- _Outptr_ ID3DX11Effect **ppEffect,
- _In_opt_z_ LPCSTR srcName = nullptr );
-
-//----------------------------------------------------------------------------
-// D3DX11CreateEffectFromFile
-//
-// Creates an effect instance from a compiled effect data file
-//
-// Parameters:
-//
-// [in]
-//
-// pFileName
-// Compiled effect file
-// FXFlags
-// Flags pertaining to Effect creation
-// pDevice
-// Pointer to the D3D11 device on which to create Effect resources
-//
-// [out]
-//
-// ppEffect
-// Address of the newly created Effect interface
-//
-//----------------------------------------------------------------------------
-
-HRESULT WINAPI D3DX11CreateEffectFromFile( _In_z_ LPCWSTR pFileName,
- _In_ UINT FXFlags,
- _In_ ID3D11Device *pDevice,
- _Outptr_ ID3DX11Effect **ppEffect );
-
-//----------------------------------------------------------------------------
-// D3DX11CompileEffectFromMemory
-//
-// Complies an effect shader source file in memory and then creates an effect instance
-//
-// Parameters:
-//
-// [in]
-//
-// pData
-// Pointer to FX shader as an ASCII string
-// DataLength
-// Length of the FX shader ASCII string
-// srcName [optional]
-// ASCII string to use for debug object naming
-// pDefines [optional]
-// A NULL-terminated array of shader macros
-// pInclude [optional]
-// A pointer to an include interface
-// HLSLFlags
-// HLSL compile options (see D3DCOMPILE flags)
-// FXFlags
-// Flags pertaining to Effect compilation (see D3DCOMPILE_EFFECT flags)
-// pDevice
-// Pointer to the D3D11 device on which to create Effect resources
-//
-// [out]
-//
-// ppEffect
-// Address of the newly created Effect interface
-//
-//----------------------------------------------------------------------------
-
-HRESULT D3DX11CompileEffectFromMemory( _In_reads_bytes_(DataLength) LPCVOID pData,
- _In_ SIZE_T DataLength,
- _In_opt_z_ LPCSTR srcName,
- _In_opt_ const D3D_SHADER_MACRO *pDefines,
- _In_opt_ ID3DInclude *pInclude,
- _In_ UINT HLSLFlags,
- _In_ UINT FXFlags,
- _In_ ID3D11Device *pDevice,
- _Out_ ID3DX11Effect **ppEffect,
- _Outptr_opt_result_maybenull_ ID3DBlob **ppErrors );
-
-//----------------------------------------------------------------------------
-// D3DX11CompileEffectFromFile
-//
-// Complies an effect shader source file and then creates an effect instance
-//
-// Parameters:
-//
-// [in]
-//
-// pFileName
-// FX shader source file
-// pDefines [optional]
-// A NULL-terminated array of shader macros
-// pInclude [optional]
-// A pointer to an include interface
-// HLSLFlags
-// HLSL compile options (see D3DCOMPILE flags)
-// FXFlags
-// Flags pertaining to Effect compilation (see D3DCOMPILE_EFFECT flags)
-// pDevice
-// Pointer to the D3D11 device on which to create Effect resources
-//
-// [out]
-//
-// ppEffect
-// Address of the newly created Effect interface
-//
-//----------------------------------------------------------------------------
-
-HRESULT D3DX11CompileEffectFromFile( _In_z_ LPCWSTR pFileName,
- _In_opt_ const D3D_SHADER_MACRO *pDefines,
- _In_opt_ ID3DInclude *pInclude,
- _In_ UINT HLSLFlags,
- _In_ UINT FXFlags,
- _In_ ID3D11Device *pDevice,
- _Out_ ID3DX11Effect **ppEffect,
- _Outptr_opt_result_maybenull_ ID3DBlob **ppErrors );
-
-
-//----------------------------------------------------------------------------
-// D3DX11DebugMute
-//
-// Controls the output of diagnostic information in DEBUG builds. No effect
-// in RELEASE builds.
-//
-// Returns the previous state so you can do temporary suppression like:
-//
-// bool oldmute = D3DX11DebugMute(true);
-// ...
-// D3DX11DebugMute(oldmute);
-//
-//----------------------------------------------------------------------------
-
-bool D3DX11DebugMute(bool mute);
-
-#ifdef __cplusplus
-}
-#endif //__cplusplus
diff --git a/lib/win32/Effects11/inc/d3dxGlobal.h b/lib/win32/Effects11/inc/d3dxGlobal.h
deleted file mode 100644
index 2018c1951b..0000000000
--- a/lib/win32/Effects11/inc/d3dxGlobal.h
+++ /dev/null
@@ -1,1290 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: D3DXGlobal.h
-//
-// Direct3D 11 Effects helper defines and data structures
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-#include <assert.h>
-#include <string.h>
-
-namespace D3DX11Debug
-{
- // Helper sets a D3D resource name string (used by PIX and debug layer leak reporting).
- inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const char *name )
- {
- #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
- resource->SetPrivateData( WKPDID_D3DDebugObjectName, static_cast<UINT>(strlen(name)), name );
- #else
- UNREFERENCED_PARAMETER(resource);
- UNREFERENCED_PARAMETER(name);
- #endif
- }
-
- template<UINT TNameLength>
- inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_z_ const char (&name)[TNameLength])
- {
- #if !defined(NO_D3D11_DEBUG_NAME) && ( defined(_DEBUG) || defined(PROFILE) )
- resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name);
- #else
- UNREFERENCED_PARAMETER(resource);
- UNREFERENCED_PARAMETER(name);
- #endif
- }
-}
-
-using namespace D3DX11Debug;
-
-#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p) = nullptr; } }
-#define SAFE_ADDREF(p) { if (p) { (p)->AddRef(); } }
-
-#define SAFE_DELETE_ARRAY(p) { delete [](p); p = nullptr; }
-#define SAFE_DELETE(p) { delete (p); p = nullptr; }
-
-#if FXDEBUG
-#define __BREAK_ON_FAIL { __debugbreak(); }
-#else
-#define __BREAK_ON_FAIL
-#endif
-
-#define VA(x, action) { hr = (x); if (FAILED(hr)) { action; __BREAK_ON_FAIL; return hr; } }
-#define VNA(x,action) { if (!(x)) { action; __BREAK_ON_FAIL; hr = E_OUTOFMEMORY; goto lExit; } }
-#define VBA(x,action) { if (!(x)) { action; __BREAK_ON_FAIL; hr = E_FAIL; goto lExit; } }
-#define VHA(x,action) { hr = (x); if (FAILED(hr)) { action; __BREAK_ON_FAIL; goto lExit; } }
-
-#define V(x) { VA (x, 0) }
-#define VN(x) { VNA(x, 0) }
-#define VB(x) { VBA(x, 0) }
-#define VH(x) { VHA(x, 0) }
-
-#define VBD(x,str) { VBA(x, DPF(1,str)) }
-#define VHD(x,str) { VHA(x, DPF(1,str)) }
-
-#define VEASSERT(x) { hr = (x); if (FAILED(hr)) { __BREAK_ON_FAIL; assert(!#x); goto lExit; } }
-#define VNASSERT(x) { if (!(x)) { __BREAK_ON_FAIL; assert(!#x); hr = E_OUTOFMEMORY; goto lExit; } }
-
-#define D3DX11FLTASSIGN(a,b) { *reinterpret_cast< UINT32* >(&(a)) = *reinterpret_cast< UINT32* >(&(b)); }
-
-// Preferred data alignment -- must be a power of 2!
-static const uint32_t c_DataAlignment = sizeof(UINT_PTR);
-
-inline uint32_t AlignToPowerOf2(uint32_t Value, uint32_t Alignment)
-{
- assert((Alignment & (Alignment - 1)) == 0);
- // to align to 2^N, add 2^N - 1 and AND with all but lowest N bits set
- _Analysis_assume_(Alignment > 0 && Value < MAXDWORD - Alignment);
- return (Value + Alignment - 1) & (~(Alignment - 1));
-}
-
-inline void * AlignToPowerOf2(void *pValue, UINT_PTR Alignment)
-{
- assert((Alignment & (Alignment - 1)) == 0);
- // to align to 2^N, add 2^N - 1 and AND with all but lowest N bits set
- return (void *)(((UINT_PTR)pValue + Alignment - 1) & (~((UINT_PTR)Alignment - 1)));
-}
-
-namespace D3DX11Core
-{
-
-//////////////////////////////////////////////////////////////////////////
-// CMemoryStream - A class to simplify reading binary data
-//////////////////////////////////////////////////////////////////////////
-class CMemoryStream
-{
- uint8_t *m_pData;
- size_t m_cbData;
- size_t m_readPtr;
-
-public:
- HRESULT SetData(_In_reads_bytes_(size) const void *pData, _In_ size_t size);
-
- HRESULT Read(_Out_ uint32_t *pUint);
- HRESULT Read(_Outptr_result_buffer_(size) void **ppData, _In_ size_t size);
- HRESULT Read(_Outptr_ LPCSTR *ppString);
-
- HRESULT ReadAtOffset(_In_ size_t offset, _In_ size_t size, _Outptr_result_buffer_(size) void **ppData);
- HRESULT ReadAtOffset(_In_ size_t offset, _Outptr_result_z_ LPCSTR *ppString);
-
- size_t GetPosition();
- HRESULT Seek(_In_ size_t offset);
-
- CMemoryStream() noexcept;
- ~CMemoryStream();
-};
-
-}
-
-#if defined(_DEBUG) && !defined(_M_X64) && !defined(_M_ARM64)
-
-namespace D3DX11Debug
-{
-
-// This variable indicates how many ticks to go before rolling over
-// all of the timer variables in the FX system.
-// It is read from the system registry in debug builds; in retail the high bit is simply tested.
-
-_declspec(selectany) unsigned int g_TimerRolloverCount = 0x80000000;
-}
-
-#endif // _DEBUG && !_M_X64
-
-
-//////////////////////////////////////////////////////////////////////////
-// CEffectVector - A vector implementation
-//////////////////////////////////////////////////////////////////////////
-
-template<class T> class CEffectVector
-{
-protected:
-#if _DEBUG
- T *m_pCastData; // makes debugging easier to have a casted version of the data
-#endif // _DEBUG
-
- uint8_t *m_pData;
- uint32_t m_MaxSize;
- uint32_t m_CurSize;
-
- HRESULT Grow()
- {
- return Reserve(m_CurSize + 1);
- }
-
- HRESULT Reserve(_In_ uint32_t DesiredSize)
- {
- if (DesiredSize > m_MaxSize)
- {
- uint8_t *pNewData;
- uint32_t newSize = std::max(m_MaxSize * 2, DesiredSize);
-
- if (newSize < 16)
- newSize = 16;
-
- if ((newSize < m_MaxSize) || (newSize < m_CurSize) || (newSize >= UINT_MAX / sizeof(T)))
- {
- m_hLastError = E_OUTOFMEMORY;
- return m_hLastError;
- }
-
- pNewData = new uint8_t[newSize * sizeof(T)];
- if (pNewData == nullptr)
- {
- m_hLastError = E_OUTOFMEMORY;
- return m_hLastError;
- }
-
- if (m_pData)
- {
- memcpy(pNewData, m_pData, m_CurSize * sizeof(T));
- delete []m_pData;
- }
-
- m_pData = pNewData;
- m_MaxSize = newSize;
- }
-#if _DEBUG
- m_pCastData = (T*) m_pData;
-#endif // _DEBUG
- return S_OK;
- }
-
-public:
- HRESULT m_hLastError;
-
- CEffectVector<T>() noexcept :
-#if _DEBUG
- m_pCastData(nullptr),
-#endif
- m_pData(nullptr),
- m_CurSize(0),
- m_MaxSize(0),
- m_hLastError(S_OK)
- {
- }
-
- ~CEffectVector<T>()
- {
- Clear();
- }
-
- // cleanly swaps two vectors -- useful for when you want
- // to reallocate a vector and copy data over, then swap them back
- void SwapVector(_Out_ CEffectVector<T> &vOther)
- {
- uint8_t tempData[sizeof(*this)];
-
- memcpy(tempData, this, sizeof(*this));
- memcpy(this, &vOther, sizeof(*this));
- memcpy(&vOther, tempData, sizeof(*this));
- }
-
- HRESULT CopyFrom(_In_ const CEffectVector<T> &vOther)
- {
- HRESULT hr = S_OK;
- Clear();
- VN( m_pData = new uint8_t[vOther.m_MaxSize * sizeof(T)] );
-
- m_CurSize = vOther.m_CurSize;
- m_MaxSize = vOther.m_MaxSize;
- m_hLastError = vOther.m_hLastError;
-
- for (size_t i = 0; i < m_CurSize; ++ i)
- {
- ((T*)m_pData)[i] = ((T*)vOther.m_pData)[i];
- }
-
-lExit:
-
-#if _DEBUG
- m_pCastData = (T*) m_pData;
-#endif // _DEBUG
-
- return hr;
- }
-
- void Clear()
- {
- Empty();
- SAFE_DELETE_ARRAY(m_pData);
- m_MaxSize = 0;
-#if _DEBUG
- m_pCastData = nullptr;
-#endif // _DEBUG
- }
-
- void ClearWithoutDestructor()
- {
- m_CurSize = 0;
- m_hLastError = S_OK;
- SAFE_DELETE_ARRAY(m_pData);
- m_MaxSize = 0;
-
-#if _DEBUG
- m_pCastData = nullptr;
-#endif // _DEBUG
- }
-
- void Empty()
- {
-
- // manually invoke destructor on all elements
- for (size_t i = 0; i < m_CurSize; ++ i)
- {
- ((T*)m_pData + i)->~T();
- }
- m_CurSize = 0;
- m_hLastError = S_OK;
- }
-
- T* Add()
- {
- if (FAILED(Grow()))
- return nullptr;
-
- // placement new
- return new((T*)m_pData + (m_CurSize ++)) T;
- }
-
- T* AddRange(_In_ uint32_t count)
- {
- if (m_CurSize + count < m_CurSize)
- {
- m_hLastError = E_OUTOFMEMORY;
- return nullptr;
- }
-
- if (FAILED(Reserve(m_CurSize + count)))
- return nullptr;
-
- T *pData = (T*)m_pData + m_CurSize;
- for (size_t i = 0; i < count; ++ i)
- {
- new(pData + i) T;
- }
- m_CurSize += count;
- return pData;
- }
-
- HRESULT Add(_In_ const T& var)
- {
- if (FAILED(Grow()))
- return m_hLastError;
-
- memcpy((T*)m_pData + m_CurSize, &var, sizeof(T));
- m_CurSize++;
-
- return S_OK;
- }
-
- HRESULT AddRange(_In_reads_(count) const T *pVar, _In_ uint32_t count)
- {
- if (m_CurSize + count < m_CurSize)
- {
- m_hLastError = E_OUTOFMEMORY;
- return m_hLastError;
- }
-
- if (FAILED(Reserve(m_CurSize + count)))
- return m_hLastError;
-
- memcpy((T*)m_pData + m_CurSize, pVar, count * sizeof(T));
- m_CurSize += count;
-
- return S_OK;
- }
-
- HRESULT Insert(_In_ const T& var, _In_ uint32_t index)
- {
- assert(index < m_CurSize);
-
- if (FAILED(Grow()))
- return m_hLastError;
-
- memmove((T*)m_pData + index + 1, (T*)m_pData + index, (m_CurSize - index) * sizeof(T));
- memcpy((T*)m_pData + index, &var, sizeof(T));
- m_CurSize++;
-
- return S_OK;
- }
-
- HRESULT InsertRange(_In_reads_(count) const T *pVar, _In_ uint32_t index, _In_ uint32_t count)
- {
- assert(index < m_CurSize);
-
- if (m_CurSize + count < m_CurSize)
- {
- m_hLastError = E_OUTOFMEMORY;
- return m_hLastError;
- }
-
- if (FAILED(Reserve(m_CurSize + count)))
- return m_hLastError;
-
- memmove((T*)m_pData + index + count, (T*)m_pData + index, (m_CurSize - index) * sizeof(T));
- memcpy((T*)m_pData + index, pVar, count * sizeof(T));
- m_CurSize += count;
-
- return S_OK;
- }
-
- inline T& operator[](_In_ size_t index)
- {
- assert(index < m_CurSize);
- return ((T*)m_pData)[index];
- }
-
- // Deletes element at index and shifts all other values down
- void Delete(_In_ uint32_t index)
- {
- assert(index < m_CurSize);
-
- -- m_CurSize;
- memmove((T*)m_pData + index, (T*)m_pData + index + 1, (m_CurSize - index) * sizeof(T));
- }
-
- // Deletes element at index and moves the last element into its place
- void QuickDelete(_In_ uint32_t index)
- {
- assert(index < m_CurSize);
-
- -- m_CurSize;
- memcpy((T*)m_pData + index, (T*)m_pData + m_CurSize, sizeof(T));
- }
-
- inline uint32_t GetSize() const
- {
- return m_CurSize;
- }
-
- inline T* GetData() const
- {
- return (T*)m_pData;
- }
-
- uint32_t FindIndexOf(_In_ const void *pEntry) const
- {
- for (size_t i = 0; i < m_CurSize; ++ i)
- {
- if (((T*)m_pData + i) == pEntry)
- return i;
- }
-
- return -1;
- }
-
- void Sort(int (__cdecl *pfnCompare)(const void *pElem1, const void *pElem2))
- {
- qsort(m_pData, m_CurSize, sizeof(T), pfnCompare);
- }
-};
-
-//////////////////////////////////////////////////////////////////////////
-// CEffectVectorOwner - implements a vector of ptrs to objects. The vector owns the objects.
-//////////////////////////////////////////////////////////////////////////
-template<class T> class CEffectVectorOwner : public CEffectVector<T*>
-{
-public:
- ~CEffectVectorOwner<T>()
- {
- Clear();
-
- for (size_t i=0; i<m_CurSize; i++)
- SAFE_DELETE(((T**)m_pData)[i]);
-
- SAFE_DELETE_ARRAY(m_pData);
- }
-
- void Clear()
- {
- Empty();
- SAFE_DELETE_ARRAY(m_pData);
- m_MaxSize = 0;
- }
-
- void Empty()
- {
- // manually invoke destructor on all elements
- for (size_t i = 0; i < m_CurSize; ++ i)
- {
- SAFE_DELETE(((T**)m_pData)[i]);
- }
- m_CurSize = 0;
- m_hLastError = S_OK;
- }
-
- void Delete(_In_ uint32_t index)
- {
- assert(index < m_CurSize);
-
- SAFE_DELETE(((T**)m_pData)[index]);
-
- CEffectVector<T*>::Delete(index);
- }
-};
-
-//////////////////////////////////////////////////////////////////////////
-// Checked uint32_t, uint64_t
-// Use CheckedNumber only with uint32_t and uint64_t
-//////////////////////////////////////////////////////////////////////////
-template <class T, T MaxValue> class CheckedNumber
-{
- T m_Value;
- bool m_bValid;
-
-public:
- CheckedNumber<T, MaxValue>() noexcept :
- m_Value(0),
- m_bValid(true)
- {
- }
-
- CheckedNumber<T, MaxValue>(const T &value) : m_Value(value), m_bValid(true)
- {
- }
-
- CheckedNumber<T, MaxValue>(const CheckedNumber<T, MaxValue> &value) : m_bValid(value.m_bValid), m_Value(value.m_Value)
- {
- }
-
- CheckedNumber<T, MaxValue> &operator+(const CheckedNumber<T, MaxValue> &other)
- {
- CheckedNumber<T, MaxValue> Res(*this);
- return Res+=other;
- }
-
- CheckedNumber<T, MaxValue> &operator+=(const CheckedNumber<T, MaxValue> &other)
- {
- if (!other.m_bValid)
- {
- m_bValid = false;
- }
- else
- {
- m_Value += other.m_Value;
-
- if (m_Value < other.m_Value)
- m_bValid = false;
- }
-
- return *this;
- }
-
- CheckedNumber<T, MaxValue> &operator*(const CheckedNumber<T, MaxValue> &other)
- {
- CheckedNumber<T, MaxValue> Res(*this);
- return Res*=other;
- }
-
- CheckedNumber<T, MaxValue> &operator*=(const CheckedNumber<T, MaxValue> &other)
- {
- if (!other.m_bValid)
- {
- m_bValid = false;
- }
- else
- {
- if (other.m_Value != 0)
- {
- if (m_Value > MaxValue / other.m_Value)
- {
- m_bValid = false;
- }
- }
- m_Value *= other.m_Value;
- }
-
- return *this;
- }
-
- HRESULT GetValue(_Out_ T *pValue)
- {
- if (!m_bValid)
- {
- *pValue = uint32_t(-1);
- return E_FAIL;
- }
-
- *pValue = m_Value;
- return S_OK;
- }
-};
-
-typedef CheckedNumber<uint32_t, _UI32_MAX> CCheckedDword;
-typedef CheckedNumber<uint64_t, _UI64_MAX> CCheckedDword64;
-
-
-//////////////////////////////////////////////////////////////////////////
-// Data Block Store - A linked list of allocations
-//////////////////////////////////////////////////////////////////////////
-
-class CDataBlock
-{
-protected:
- uint32_t m_size;
- uint32_t m_maxSize;
- uint8_t *m_pData;
- CDataBlock *m_pNext;
-
- bool m_IsAligned; // Whether or not to align the data to c_DataAlignment
-
-public:
- // AddData appends an existing use buffer to the data block
- HRESULT AddData(_In_reads_bytes_(bufferSize) const void *pNewData, _In_ uint32_t bufferSize, _Outptr_ CDataBlock **ppBlock);
-
- // Allocate reserves bufferSize bytes of contiguous memory and returns a pointer to the user
- _Success_(return != nullptr)
- void* Allocate(_In_ uint32_t bufferSize, _Outptr_ CDataBlock **ppBlock);
-
- void EnableAlignment();
-
- CDataBlock() noexcept;
- ~CDataBlock();
-
- friend class CDataBlockStore;
-};
-
-
-class CDataBlockStore
-{
-protected:
- CDataBlock *m_pFirst;
- CDataBlock *m_pLast;
- uint32_t m_Size;
- uint32_t m_Offset; // m_Offset gets added to offsets returned from AddData & AddString. Use this to set a global for the entire string block
- bool m_IsAligned; // Whether or not to align the data to c_DataAlignment
-
-public:
-#if _DEBUG
- uint32_t m_cAllocations;
-#endif
-
-public:
- HRESULT AddString(_In_z_ LPCSTR pString, _Inout_ uint32_t *pOffset);
- // Writes a null-terminated string to buffer
-
- HRESULT AddData(_In_reads_bytes_(bufferSize) const void *pNewData, _In_ uint32_t bufferSize, _Inout_ uint32_t *pOffset);
- // Writes data block to buffer
-
- // Memory allocator support
- void* Allocate(_In_ uint32_t bufferSize);
- uint32_t GetSize();
- void EnableAlignment();
-
- CDataBlockStore() noexcept;
- ~CDataBlockStore();
-};
-
-// Custom allocator that uses CDataBlockStore
-// The trick is that we never free, so we don't have to keep as much state around
-// Use PRIVATENEW in CEffectLoader
-
-inline void* __cdecl operator new(_In_ size_t s, _In_ CDataBlockStore &pAllocator)
-{
-#ifdef _M_X64
- assert( s <= 0xffffffff );
-#endif
- return pAllocator.Allocate( (uint32_t)s );
-}
-
-inline void __cdecl operator delete(_In_opt_ void* p, _In_ CDataBlockStore &pAllocator)
-{
- UNREFERENCED_PARAMETER(p);
- UNREFERENCED_PARAMETER(pAllocator);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-// Hash table
-//////////////////////////////////////////////////////////////////////////
-
-#define HASH_MIX(a,b,c) \
-{ \
- a -= b; a -= c; a ^= (c>>13); \
- b -= c; b -= a; b ^= (a<<8); \
- c -= a; c -= b; c ^= (b>>13); \
- a -= b; a -= c; a ^= (c>>12); \
- b -= c; b -= a; b ^= (a<<16); \
- c -= a; c -= b; c ^= (b>>5); \
- a -= b; a -= c; a ^= (c>>3); \
- b -= c; b -= a; b ^= (a<<10); \
- c -= a; c -= b; c ^= (b>>15); \
-}
-
-static uint32_t ComputeHash(_In_reads_bytes_(cbToHash) const uint8_t *pb, _In_ uint32_t cbToHash)
-{
- uint32_t cbLeft = cbToHash;
-
- uint32_t a;
- uint32_t b;
- a = b = 0x9e3779b9; // the golden ratio; an arbitrary value
-
- uint32_t c = 0;
-
- while (cbLeft >= 12)
- {
- const uint32_t *pdw = reinterpret_cast<const uint32_t *>(pb);
-
- a += pdw[0];
- b += pdw[1];
- c += pdw[2];
-
- HASH_MIX(a,b,c);
- pb += 12;
- cbLeft -= 12;
- }
-
- c += cbToHash;
-
- switch(cbLeft) // all the case statements fall through
- {
- case 11: c+=((uint32_t) pb[10] << 24);
- case 10: c+=((uint32_t) pb[9] << 16);
- case 9 : c+=((uint32_t) pb[8] << 8);
- // the first byte of c is reserved for the length
- case 8 : b+=((uint32_t) pb[7] << 24);
- case 7 : b+=((uint32_t) pb[6] << 16);
- case 6 : b+=((uint32_t) pb[5] << 8);
- case 5 : b+=pb[4];
- case 4 : a+=((uint32_t) pb[3] << 24);
- case 3 : a+=((uint32_t) pb[2] << 16);
- case 2 : a+=((uint32_t) pb[1] << 8);
- case 1 : a+=pb[0];
- }
-
- HASH_MIX(a,b,c);
-
- return c;
-}
-
-static uint32_t ComputeHashLower(_In_reads_bytes_(cbToHash) const uint8_t *pb, _In_ uint32_t cbToHash)
-{
- uint32_t cbLeft = cbToHash;
-
- uint32_t a;
- uint32_t b;
- a = b = 0x9e3779b9; // the golden ratio; an arbitrary value
- uint32_t c = 0;
-
- while (cbLeft >= 12)
- {
- uint8_t pbT[12];
- for( size_t i = 0; i < 12; i++ )
- pbT[i] = (uint8_t)tolower(pb[i]);
-
- uint32_t *pdw = reinterpret_cast<uint32_t *>(pbT);
-
- a += pdw[0];
- b += pdw[1];
- c += pdw[2];
-
- HASH_MIX(a,b,c);
- pb += 12;
- cbLeft -= 12;
- }
-
- c += cbToHash;
-
- uint8_t pbT[12];
- for( size_t i = 0; i < cbLeft; i++ )
- pbT[i] = (uint8_t)tolower(pb[i]);
-
- switch(cbLeft) // all the case statements fall through
- {
- case 11: c+=((uint32_t) pbT[10] << 24);
- case 10: c+=((uint32_t) pbT[9] << 16);
- case 9 : c+=((uint32_t) pbT[8] << 8);
- // the first byte of c is reserved for the length
- case 8 : b+=((uint32_t) pbT[7] << 24);
- case 7 : b+=((uint32_t) pbT[6] << 16);
- case 6 : b+=((uint32_t) pbT[5] << 8);
- case 5 : b+=pbT[4];
- case 4 : a+=((uint32_t) pbT[3] << 24);
- case 3 : a+=((uint32_t) pbT[2] << 16);
- case 2 : a+=((uint32_t) pbT[1] << 8);
- case 1 : a+=pbT[0];
- }
-
- HASH_MIX(a,b,c);
-
- return c;
-}
-
-static uint32_t ComputeHash(_In_z_ LPCSTR pString)
-{
- return ComputeHash(reinterpret_cast<const uint8_t*>(pString), (uint32_t)strlen(pString));
-}
-
-
-// 1) these numbers are prime
-// 2) each is slightly less than double the last
-// 4) each is roughly in between two powers of 2;
-// (2^n hash table sizes are VERY BAD; they effectively truncate your
-// precision down to the n least significant bits of the hash)
-static const uint32_t c_PrimeSizes[] =
-{
- 11,
- 23,
- 53,
- 97,
- 193,
- 389,
- 769,
- 1543,
- 3079,
- 6151,
- 12289,
- 24593,
- 49157,
- 98317,
- 196613,
- 393241,
- 786433,
- 1572869,
- 3145739,
- 6291469,
- 12582917,
- 25165843,
- 50331653,
- 100663319,
- 201326611,
- 402653189,
- 805306457,
- 1610612741,
-};
-
-template<typename T, bool (*pfnIsEqual)(const T &Data1, const T &Data2)>
-class CEffectHashTable
-{
-protected:
-
- struct SHashEntry
- {
- uint32_t Hash;
- T Data;
- SHashEntry *pNext;
- };
-
- // Array of hash entries
- SHashEntry **m_rgpHashEntries;
- uint32_t m_NumHashSlots;
- uint32_t m_NumEntries;
- bool m_bOwnHashEntryArray;
-
-public:
- class CIterator
- {
- friend class CEffectHashTable;
-
- protected:
- SHashEntry **ppHashSlot;
- SHashEntry *pHashEntry;
-
- public:
- T GetData()
- {
- assert(pHashEntry != 0);
- _Analysis_assume_(pHashEntry != 0);
- return pHashEntry->Data;
- }
-
- uint32_t GetHash()
- {
- assert(pHashEntry != 0);
- _Analysis_assume_(pHashEntry != 0);
- return pHashEntry->Hash;
- }
- };
-
- CEffectHashTable() noexcept :
- m_rgpHashEntries(nullptr),
- m_NumHashSlots(0),
- m_NumEntries(0),
- m_bOwnHashEntryArray(false)
- {
- }
-
- HRESULT Initialize(_In_ const CEffectHashTable *pOther)
- {
- HRESULT hr = S_OK;
- SHashEntry **rgpNewHashEntries = nullptr;
- uint32_t valuesMigrated = 0;
- uint32_t actualSize;
-
- Cleanup();
-
- actualSize = pOther->m_NumHashSlots;
- VN( rgpNewHashEntries = new SHashEntry*[actualSize] );
-
- ZeroMemory(rgpNewHashEntries, sizeof(SHashEntry*) * actualSize);
-
- // Expensive operation: rebuild the hash table
- CIterator iter, nextIter;
- pOther->GetFirstEntry(&iter);
- while (!pOther->PastEnd(&iter))
- {
- uint32_t index = iter.GetHash() % actualSize;
-
- // we need to advance to the next element
- // before we seize control of this element and move
- // it to the new table
- nextIter = iter;
- pOther->GetNextEntry(&nextIter);
-
- // seize this hash entry, migrate it to the new table
- SHashEntry *pNewEntry;
- VN( pNewEntry = new SHashEntry );
-
- pNewEntry->pNext = rgpNewHashEntries[index];
- pNewEntry->Data = iter.pHashEntry->Data;
- pNewEntry->Hash = iter.pHashEntry->Hash;
- rgpNewHashEntries[index] = pNewEntry;
-
- iter = nextIter;
- ++ valuesMigrated;
- }
-
- assert(valuesMigrated == pOther->m_NumEntries);
-
- m_rgpHashEntries = rgpNewHashEntries;
- m_NumHashSlots = actualSize;
- m_NumEntries = pOther->m_NumEntries;
- m_bOwnHashEntryArray = true;
- rgpNewHashEntries = nullptr;
-
-lExit:
- SAFE_DELETE_ARRAY( rgpNewHashEntries );
- return hr;
- }
-
-protected:
- void CleanArray()
- {
- if (m_bOwnHashEntryArray)
- {
- SAFE_DELETE_ARRAY(m_rgpHashEntries);
- m_bOwnHashEntryArray = false;
- }
- }
-
-public:
- void Cleanup()
- {
- for (size_t i = 0; i < m_NumHashSlots; ++ i)
- {
- SHashEntry *pCurrentEntry = m_rgpHashEntries[i];
- SHashEntry *pTempEntry;
- while (nullptr != pCurrentEntry)
- {
- pTempEntry = pCurrentEntry->pNext;
- SAFE_DELETE(pCurrentEntry);
- pCurrentEntry = pTempEntry;
- -- m_NumEntries;
- }
- }
- CleanArray();
- m_NumHashSlots = 0;
- assert(m_NumEntries == 0);
- }
-
- ~CEffectHashTable()
- {
- Cleanup();
- }
-
- static uint32_t GetNextHashTableSize(_In_ uint32_t DesiredSize)
- {
- // figure out the next logical size to use
- for (size_t i = 0; i < _countof(c_PrimeSizes); ++i )
- {
- if (c_PrimeSizes[i] >= DesiredSize)
- {
- return c_PrimeSizes[i];
- }
- }
-
- return DesiredSize;
- }
-
- // O(n) function
- // Grows to the next suitable size (based off of the prime number table)
- // DesiredSize is merely a suggestion
- HRESULT Grow(_In_ uint32_t DesiredSize,
- _In_ uint32_t ProvidedArraySize = 0,
- _In_reads_opt_(ProvidedArraySize) void** ProvidedArray = nullptr,
- _In_ bool OwnProvidedArray = false)
- {
- HRESULT hr = S_OK;
- SHashEntry **rgpNewHashEntries = nullptr;
- uint32_t valuesMigrated = 0;
- uint32_t actualSize;
-
- VB( DesiredSize > m_NumHashSlots );
-
- actualSize = GetNextHashTableSize(DesiredSize);
-
- if (ProvidedArray &&
- ProvidedArraySize >= actualSize)
- {
- rgpNewHashEntries = reinterpret_cast<SHashEntry**>(ProvidedArray);
- }
- else
- {
- OwnProvidedArray = true;
-
- VN( rgpNewHashEntries = new SHashEntry*[actualSize] );
- }
-
- ZeroMemory(rgpNewHashEntries, sizeof(SHashEntry*) * actualSize);
-
- // Expensive operation: rebuild the hash table
- CIterator iter, nextIter;
- GetFirstEntry(&iter);
- while (!PastEnd(&iter))
- {
- uint32_t index = iter.GetHash() % actualSize;
-
- // we need to advance to the next element
- // before we seize control of this element and move
- // it to the new table
- nextIter = iter;
- GetNextEntry(&nextIter);
-
- // seize this hash entry, migrate it to the new table
- iter.pHashEntry->pNext = rgpNewHashEntries[index];
- rgpNewHashEntries[index] = iter.pHashEntry;
-
- iter = nextIter;
- ++ valuesMigrated;
- }
-
- assert(valuesMigrated == m_NumEntries);
-
- CleanArray();
- m_rgpHashEntries = rgpNewHashEntries;
- m_NumHashSlots = actualSize;
- m_bOwnHashEntryArray = OwnProvidedArray;
-
-lExit:
- return hr;
- }
-
- HRESULT AutoGrow()
- {
- // arbitrary heuristic -- grow if 1:1
- if (m_NumEntries >= m_NumHashSlots)
- {
- // grows this hash table so that it is roughly 50% full
- return Grow(m_NumEntries * 2 + 1);
- }
- return S_OK;
- }
-
-#if _DEBUG
- void PrintHashTableStats()
- {
- if (m_NumHashSlots == 0)
- {
- DPF(0, "Uninitialized hash table!");
- return;
- }
-
- float variance = 0.0f;
- float mean = (float)m_NumEntries / (float)m_NumHashSlots;
- uint32_t unusedSlots = 0;
-
- DPF(0, "Hash table slots: %d, Entries in table: %d", m_NumHashSlots, m_NumEntries);
-
- for (size_t i = 0; i < m_NumHashSlots; ++ i)
- {
- uint32_t entries = 0;
- SHashEntry *pCurrentEntry = m_rgpHashEntries[i];
-
- while (nullptr != pCurrentEntry)
- {
- SHashEntry *pCurrentEntry2 = m_rgpHashEntries[i];
-
- // check other hash entries in this slot for hash collisions or duplications
- while (pCurrentEntry2 != pCurrentEntry)
- {
- if (pCurrentEntry->Hash == pCurrentEntry2->Hash)
- {
- if (pfnIsEqual(pCurrentEntry->Data, pCurrentEntry2->Data))
- {
- assert(0);
- DPF(0, "Duplicate entry (identical hash, identical data) found!");
- }
- else
- {
- DPF(0, "Hash collision (hash: %d)", pCurrentEntry->Hash);
- }
- }
- pCurrentEntry2 = pCurrentEntry2->pNext;
- }
-
- pCurrentEntry = pCurrentEntry->pNext;
- ++ entries;
- }
-
- if (0 == entries)
- {
- ++ unusedSlots;
- }
-
- // mean must be greater than 0 at this point
- variance += (float)entries * (float)entries / mean;
- }
-
- variance /= std::max(1.0f, (m_NumHashSlots - 1));
- variance -= (mean * mean);
-
- DPF(0, "Mean number of entries per slot: %f, Standard deviation: %f, Unused slots; %d", mean, variance, unusedSlots);
- }
-#endif // _DEBUG
-
- // S_OK if element is found, E_FAIL otherwise
- HRESULT FindValueWithHash(_In_ T Data, _In_ uint32_t Hash, _Out_ CIterator *pIterator)
- {
- assert(m_NumHashSlots > 0);
-
- uint32_t index = Hash % m_NumHashSlots;
- SHashEntry *pEntry = m_rgpHashEntries[index];
- while (nullptr != pEntry)
- {
- if (Hash == pEntry->Hash && pfnIsEqual(pEntry->Data, Data))
- {
- pIterator->ppHashSlot = m_rgpHashEntries + index;
- pIterator->pHashEntry = pEntry;
- return S_OK;
- }
- pEntry = pEntry->pNext;
- }
- return E_FAIL;
- }
-
- // S_OK if element is found, E_FAIL otherwise
- HRESULT FindFirstMatchingValue(_In_ uint32_t Hash, _Out_ CIterator *pIterator)
- {
- assert(m_NumHashSlots > 0);
-
- uint32_t index = Hash % m_NumHashSlots;
- SHashEntry *pEntry = m_rgpHashEntries[index];
- while (nullptr != pEntry)
- {
- if (Hash == pEntry->Hash)
- {
- pIterator->ppHashSlot = m_rgpHashEntries + index;
- pIterator->pHashEntry = pEntry;
- return S_OK;
- }
- pEntry = pEntry->pNext;
- }
- return E_FAIL;
- }
-
- // Adds data at the specified hash slot without checking for existence
- HRESULT AddValueWithHash(_In_ T Data, _In_ uint32_t Hash)
- {
- HRESULT hr = S_OK;
-
- assert(m_NumHashSlots > 0);
-
- SHashEntry *pHashEntry;
- uint32_t index = Hash % m_NumHashSlots;
-
- VN( pHashEntry = new SHashEntry );
- pHashEntry->pNext = m_rgpHashEntries[index];
- pHashEntry->Data = Data;
- pHashEntry->Hash = Hash;
- m_rgpHashEntries[index] = pHashEntry;
-
- ++ m_NumEntries;
-
-lExit:
- return hr;
- }
-
- // Iterator code:
- //
- // CMyHashTable::CIterator myIt;
- // for (myTable.GetFirstEntry(&myIt); !myTable.PastEnd(&myIt); myTable.GetNextEntry(&myIt)
- // { myTable.GetData(&myIt); }
- void GetFirstEntry(_Out_ CIterator *pIterator)
- {
- SHashEntry **ppEnd = m_rgpHashEntries + m_NumHashSlots;
- pIterator->ppHashSlot = m_rgpHashEntries;
- while (pIterator->ppHashSlot < ppEnd)
- {
- if (nullptr != *(pIterator->ppHashSlot))
- {
- pIterator->pHashEntry = *(pIterator->ppHashSlot);
- return;
- }
- ++ pIterator->ppHashSlot;
- }
- }
-
- bool PastEnd(_Inout_ CIterator *pIterator)
- {
- SHashEntry **ppEnd = m_rgpHashEntries + m_NumHashSlots;
- assert(pIterator->ppHashSlot >= m_rgpHashEntries && pIterator->ppHashSlot <= ppEnd);
- return (pIterator->ppHashSlot == ppEnd);
- }
-
- void GetNextEntry(_Inout_ CIterator *pIterator)
- {
- SHashEntry **ppEnd = m_rgpHashEntries + m_NumHashSlots;
- assert(pIterator->ppHashSlot >= m_rgpHashEntries && pIterator->ppHashSlot <= ppEnd);
- assert(pIterator->pHashEntry != 0);
- _Analysis_assume_(pIterator->pHashEntry != 0);
-
- pIterator->pHashEntry = pIterator->pHashEntry->pNext;
- if (nullptr != pIterator->pHashEntry)
- {
- return;
- }
-
- ++ pIterator->ppHashSlot;
- while (pIterator->ppHashSlot < ppEnd)
- {
- pIterator->pHashEntry = *(pIterator->ppHashSlot);
- if (nullptr != pIterator->pHashEntry)
- {
- return;
- }
- ++ pIterator->ppHashSlot;
- }
- // hit the end of the list, ppHashSlot == ppEnd
- }
-
- void RemoveEntry(_Inout_ CIterator *pIterator)
- {
- SHashEntry *pTemp;
- SHashEntry **ppPrev;
- SHashEntry **ppEnd = m_rgpHashEntries + m_NumHashSlots;
-
- assert(pIterator && !PastEnd(pIterator));
- ppPrev = pIterator->ppHashSlot;
- pTemp = *ppPrev;
- while (pTemp)
- {
- if (pTemp == pIterator->pHashEntry)
- {
- *ppPrev = pTemp->pNext;
- pIterator->ppHashSlot = ppEnd;
- delete pTemp;
- return;
- }
- ppPrev = &pTemp->pNext;
- pTemp = pTemp->pNext;
- }
-
- // Should never get here
- assert(0);
- }
-
-};
-
-// Allocates the hash slots on the regular heap (since the
-// hash table can grow), but all hash entries are allocated on
-// a private heap
-
-template<typename T, bool (*pfnIsEqual)(const T &Data1, const T &Data2)>
-class CEffectHashTableWithPrivateHeap : public CEffectHashTable<T, pfnIsEqual>
-{
-protected:
- CDataBlockStore *m_pPrivateHeap;
-
-public:
- CEffectHashTableWithPrivateHeap() noexcept :
- m_pPrivateHeap(nullptr)
- {
- }
-
- void Cleanup()
- {
- CleanArray();
- m_NumHashSlots = 0;
- m_NumEntries = 0;
- }
-
- ~CEffectHashTableWithPrivateHeap()
- {
- Cleanup();
- }
-
- // Call this only once
- void SetPrivateHeap(_In_ CDataBlockStore *pPrivateHeap)
- {
- assert(nullptr == m_pPrivateHeap);
- m_pPrivateHeap = pPrivateHeap;
- }
-
- // Adds data at the specified hash slot without checking for existence
- HRESULT AddValueWithHash(_In_ T Data, _In_ uint32_t Hash)
- {
- HRESULT hr = S_OK;
-
- assert(m_pPrivateHeap);
- _Analysis_assume_(m_pPrivateHeap);
- assert(m_NumHashSlots > 0);
-
- SHashEntry *pHashEntry;
- uint32_t index = Hash % m_NumHashSlots;
-
- VN( pHashEntry = new(*m_pPrivateHeap) SHashEntry );
- pHashEntry->pNext = m_rgpHashEntries[index];
- pHashEntry->Data = Data;
- pHashEntry->Hash = Hash;
- m_rgpHashEntries[index] = pHashEntry;
-
- ++ m_NumEntries;
-
-lExit:
- return hr;
- }
-};
diff --git a/lib/win32/Effects11/pchfx.h b/lib/win32/Effects11/pchfx.h
deleted file mode 100644
index 9436a1a93f..0000000000
--- a/lib/win32/Effects11/pchfx.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//--------------------------------------------------------------------------------------
-// File: pchfx.h
-//
-// Direct3D 11 shader effects precompiled header
-//
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-//
-// http://go.microsoft.com/fwlink/p/?LinkId=271568
-//--------------------------------------------------------------------------------------
-
-#pragma once
-
-#pragma warning(disable : 4102 4127 4201 4505 4616 4706 6326)
-
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-
-#include <algorithm>
-
-#if defined(_XBOX_ONE) && defined(_TITLE)
-#include <d3d11_x.h>
-#include <D3DCompiler_x.h>
-#define DCOMMON_H_INCLUDED
-#define NO_D3D11_DEBUG_NAME
-#else
-#include <d3d11_1.h>
-#include <D3DCompiler.h>
-#endif
-
-#ifndef _WIN32_WINNT_WIN8
-#define _WIN32_WINNT_WIN8 0x0602
-#endif
-
-#undef DEFINE_GUID
-#include "INITGUID.h"
-
-#include "d3dx11effect.h"
-
-#define UNUSED -1
-
-//////////////////////////////////////////////////////////////////////////
-
-#define offsetof_fx( a, b ) (uint32_t)offsetof( a, b )
-
-#include "d3dxGlobal.h"
-
-#include <cstddef>
-#include <cstdlib>
-
-#include "Effect.h"
-#include "EffectStateBase11.h"
-#include "EffectLoad.h"
-
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-arm.list b/project/BuildDependencies/scripts/0_package.target-win10-arm.list
index a3490f9e16..04b5887b2a 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-arm.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-arm.list
@@ -6,7 +6,7 @@
; -> sqlite-3.7.12.1-arm\system\sqlite3.dll
; -> ...
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
-curl-7.67.0-win10-arm-v141-20200105.7z
+brotli-1.0.7-win10-arm-v141-20200105.7z
dav1d-1.4.1-win10-arm-v142-20240331.7z
freetype-2.10.1-win10-arm-v141-20200105.7z
fstrcmp-0.7-win10-arm-v141-20200105.7z
@@ -27,6 +27,7 @@ libxslt-1.1.34-win10-arm-v141-20200105.7z
lzo2-2.10-win10-arm-v141-20200105.7z
mariadb-connector-c-3.1.6-win10-arm-v141-20200105.7z
miniwdk-10.0.17763-20200106.7z
+nghttp2-1.40.0-win10-arm-v141-20200105.7z
openssl-1.1.1q-win10-arm-v142-20221017.7z
pillow-6.2.1-win10-arm-v142-20200803.7z
pycryptodome-3.9.4-win10-arm-v142-20200803.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-win32.list b/project/BuildDependencies/scripts/0_package.target-win10-win32.list
index fda954334d..bf72fde0c8 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-win32.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-win32.list
@@ -6,7 +6,7 @@
; -> sqlite-3.7.12.1-win32\system\sqlite3.dll
; -> ...
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
-curl-7.67.0-win10-win32-v141-20200105.7z
+brotli-1.0.7-win10-win32-v141-20200105.7z
dav1d-1.4.1-win10-win32-v142-20240331.7z
freetype-2.10.1-win10-win32-v141-20200105.7z
fstrcmp-0.7-win10-win32-v141-20200105.7z
@@ -27,6 +27,7 @@ libxslt-1.1.34-win10-win32-v141-20200105.7z
lzo2-2.10-win10-win32-v141-20200105.7z
mariadb-connector-c-3.1.6-win10-win32-v141-20200105.7z
miniwdk-10.0.17763-20200106.7z
+nghttp2-1.40.0-win10-win32-v141-20200105.7z
openssl-1.1.1q-win10-win32-v142-20221017.7z
pillow-6.2.1-win10-win32-v142-20200803.7z
pycryptodome-3.9.4-win10-win32-v142-20200803.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win10-x64.list b/project/BuildDependencies/scripts/0_package.target-win10-x64.list
index 2c2635be57..51312322d8 100644
--- a/project/BuildDependencies/scripts/0_package.target-win10-x64.list
+++ b/project/BuildDependencies/scripts/0_package.target-win10-x64.list
@@ -6,7 +6,7 @@
; -> sqlite-3.7.12.1-win32\system\sqlite3.dll
; -> ...
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
-curl-7.67.0-win10-x64-v141-20200105.7z
+brotli-1.0.7-win10-x64-v141-20200105.7z
dav1d-1.4.1-win10-x64-v142-20240331.7z
freetype-2.10.1-win10-x64-v141-20200105.7z
fstrcmp-0.7-win10-x64-v141-20200105.7z
@@ -27,6 +27,7 @@ libxslt-1.1.34-win10-x64-v141-20200105.7z
lzo2-2.10-win10-x64-v141-20200105.7z
mariadb-connector-c-3.1.6-win10-x64-v141-20200105.7z
miniwdk-10.0.17763-20200106.7z
+nghttp2-1.40.0-win10-x64-v141-20200105.7z
openssl-1.1.1q-win10-x64-v142-20221017.7z
pillow-6.2.1-win10-x64-v142-20200803.7z
pycryptodome-3.9.4-win10-x64-v142-20200803.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-win32.list b/project/BuildDependencies/scripts/0_package.target-win32.list
index b0c882344d..9ac7f69e62 100644
--- a/project/BuildDependencies/scripts/0_package.target-win32.list
+++ b/project/BuildDependencies/scripts/0_package.target-win32.list
@@ -6,7 +6,7 @@
; -> sqlite-3.7.12.1-win32\system\sqlite3.dll
; -> ...
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
-curl-7.67.0-win32-v141-20200105.7z
+brotli-1.0.7-win32-v141-20200105.7z
dav1d-1.4.1-win32-v142-20240331.7z
detours-64ec13-win32-v141-20200105.7z
dnssd-878.260.1-win32-v141-20200105.7z
@@ -33,6 +33,7 @@ libxslt-1.1.34-win32-v141-20200105.7z
lzo2-2.10-win32-v141-20200105.7z
mariadb-connector-c-3.1.6-win32-v141-20200105.7z
miniwdk-10.0.17763-20200106.7z
+nghttp2-1.40.0-win32-v141-20200105.7z
openssl-1.1.1q-win10-win32-v142-20221017.7z
pillow-6.2.1-win32-v142-20200803.7z
pycryptodome-3.9.4-win32-v142-20200803.7z
diff --git a/project/BuildDependencies/scripts/0_package.target-x64.list b/project/BuildDependencies/scripts/0_package.target-x64.list
index 7ae89f8c4c..e396e54eb6 100644
--- a/project/BuildDependencies/scripts/0_package.target-x64.list
+++ b/project/BuildDependencies/scripts/0_package.target-x64.list
@@ -6,7 +6,7 @@
; -> sqlite-3.7.12.1-win32\system\sqlite3.dll
; -> ...
;PLEASE KEEP THIS LIST IN ALPHABETICAL ORDER!
-curl-7.67.0-x64-v141-20200105.7z
+brotli-1.0.7-x64-v141-20200105.7z
dav1d-1.4.1-x64-v142-20240331.7z
detours-64ec13-x64-v141-20200105.7z
dnssd-878.260.1-x64-v141-20200105.7z
@@ -30,6 +30,7 @@ libxslt-1.1.34-x64-v141-20200105.7z
lzo2-2.10-x64-v141-20200105.7z
mariadb-connector-c-3.1.6-x64-v141-20200105.7z
miniwdk-10.0.17763-20200106.7z
+nghttp2-1.40.0-x64-v141-20200105.7z
openssl-1.1.1q-x64-v142-20221017.7z
pillow-6.2.1-x64-v142-20200803.7z
pycryptodome-3.9.4-x64-v142-20200803.7z
diff --git a/system/shaders/GL/1.2/gl_shader_vert.glsl b/system/shaders/GL/1.2/gl_shader_vert.glsl
index 7c10b5f1bf..fef2d2d94e 100644
--- a/system/shaders/GL/1.2/gl_shader_vert.glsl
+++ b/system/shaders/GL/1.2/gl_shader_vert.glsl
@@ -29,11 +29,13 @@ varying vec4 m_cord1;
varying vec4 m_colour;
uniform mat4 m_proj;
uniform mat4 m_model;
+uniform float m_depth;
void main ()
{
mat4 mvp = m_proj * m_model;
gl_Position = mvp * m_attrpos;
+ gl_Position.z = m_depth * gl_Position.w;
m_colour = m_attrcol;
m_cord0 = m_attrcord0;
m_cord1 = m_attrcord1;
diff --git a/system/shaders/GL/1.2/gl_shader_vert_clip.glsl b/system/shaders/GL/1.2/gl_shader_vert_clip.glsl
new file mode 100644
index 0000000000..959f8ad46b
--- /dev/null
+++ b/system/shaders/GL/1.2/gl_shader_vert_clip.glsl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#version 120
+
+attribute vec4 m_attrpos;
+attribute vec4 m_attrcol;
+attribute vec4 m_attrcord0;
+attribute vec4 m_attrcord1;
+varying vec4 m_cord0;
+varying vec4 m_cord1;
+varying vec4 m_colour;
+uniform mat4 m_matrix;
+uniform vec4 m_shaderClip;
+uniform vec4 m_cordStep;
+uniform float m_depth;
+
+// this shader can be used in cases where clipping via glScissor() is not
+// possible (e.g. when rotating). it can't discard triangles, but it may
+// degenerate them.
+
+void main ()
+{
+ // limit the vertices to the clipping area
+ vec4 position = m_attrpos;
+ position.xy = clamp(position.xy, m_shaderClip.xy, m_shaderClip.zw);
+ gl_Position = m_matrix * position;
+
+ // set rendering depth
+ gl_Position.z = m_depth * gl_Position.w;
+
+ // correct texture coordinates for clipped vertices
+ vec2 clipDist = m_attrpos.xy - position.xy;
+ m_cord0.xy = m_attrcord0.xy - clipDist * m_cordStep.xy;
+ m_cord1.xy = m_attrcord1.xy - clipDist * m_cordStep.zw;
+
+ m_colour = m_attrcol;
+}
diff --git a/system/shaders/GL/1.2/gl_shader_vert_default.glsl b/system/shaders/GL/1.2/gl_shader_vert_default.glsl
index 554e15c3fd..bbb06cb5fe 100644
--- a/system/shaders/GL/1.2/gl_shader_vert_default.glsl
+++ b/system/shaders/GL/1.2/gl_shader_vert_default.glsl
@@ -28,4 +28,5 @@ void main ()
{
mat4 mvp = m_proj * m_model;
gl_Position = mvp * m_attrpos;
+ gl_Position.z = -1. * gl_Position.w;
}
diff --git a/system/shaders/GL/1.2/gl_shader_vert_simple.glsl b/system/shaders/GL/1.2/gl_shader_vert_simple.glsl
new file mode 100644
index 0000000000..91fbae0b75
--- /dev/null
+++ b/system/shaders/GL/1.2/gl_shader_vert_simple.glsl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#version 120
+
+attribute vec4 m_attrpos;
+attribute vec4 m_attrcol;
+attribute vec4 m_attrcord0;
+attribute vec4 m_attrcord1;
+varying vec4 m_cord0;
+varying vec4 m_cord1;
+varying vec4 m_colour;
+uniform mat4 m_matrix;
+uniform float m_depth;
+
+void main ()
+{
+ gl_Position = m_matrix * m_attrpos;
+ gl_Position.z = m_depth * gl_Position.w;
+ m_colour = m_attrcol;
+ m_cord0 = m_attrcord0;
+ m_cord1 = m_attrcord1;
+}
diff --git a/system/shaders/GL/1.2/gl_yuv2rgb_vertex.glsl b/system/shaders/GL/1.2/gl_yuv2rgb_vertex.glsl
index cdf3c56a71..8d7e0c3530 100644
--- a/system/shaders/GL/1.2/gl_yuv2rgb_vertex.glsl
+++ b/system/shaders/GL/1.2/gl_yuv2rgb_vertex.glsl
@@ -32,6 +32,7 @@ void main ()
{
mat4 mvp = m_proj * m_model;
gl_Position = mvp * m_attrpos;
+ gl_Position.z = -1. * gl_Position.w;
m_cordY = m_attrcordY;
m_cordU = m_attrcordU;
m_cordV = m_attrcordV;
diff --git a/system/shaders/GL/1.5/gl_shader_vert.glsl b/system/shaders/GL/1.5/gl_shader_vert.glsl
index a8568310c2..c66c804788 100644
--- a/system/shaders/GL/1.5/gl_shader_vert.glsl
+++ b/system/shaders/GL/1.5/gl_shader_vert.glsl
@@ -9,11 +9,13 @@ out vec4 m_cord1;
out vec4 m_colour;
uniform mat4 m_proj;
uniform mat4 m_model;
+uniform float m_depth;
void main ()
{
mat4 mvp = m_proj * m_model;
gl_Position = mvp * m_attrpos;
+ gl_Position.z = m_depth * gl_Position.w;
m_colour = m_attrcol;
m_cord0 = m_attrcord0;
m_cord1 = m_attrcord1;
diff --git a/system/shaders/GL/1.5/gl_shader_vert_clip.glsl b/system/shaders/GL/1.5/gl_shader_vert_clip.glsl
new file mode 100644
index 0000000000..0cb2a8f1d8
--- /dev/null
+++ b/system/shaders/GL/1.5/gl_shader_vert_clip.glsl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#version 150
+
+in vec4 m_attrpos;
+in vec4 m_attrcol;
+in vec4 m_attrcord0;
+in vec4 m_attrcord1;
+out vec4 m_cord0;
+out vec4 m_cord1;
+out vec4 m_colour;
+uniform mat4 m_matrix;
+uniform vec4 m_shaderClip;
+uniform vec4 m_cordStep;
+uniform float m_depth;
+
+// this shader can be used in cases where clipping via glScissor() is not
+// possible (e.g. when rotating). it can't discard triangles, but it may
+// degenerate them.
+
+void main ()
+{
+ // limit the vertices to the clipping area
+ vec4 position = m_attrpos;
+ position.xy = clamp(position.xy, m_shaderClip.xy, m_shaderClip.zw);
+ gl_Position = m_matrix * position;
+
+ // set rendering depth
+ gl_Position.z = m_depth * gl_Position.w;
+
+ // correct texture coordinates for clipped vertices
+ vec2 clipDist = m_attrpos.xy - position.xy;
+ m_cord0.xy = m_attrcord0.xy - clipDist * m_cordStep.xy;
+ m_cord1.xy = m_attrcord1.xy - clipDist * m_cordStep.zw;
+
+ m_colour = m_attrcol;
+}
diff --git a/system/shaders/GL/1.5/gl_shader_vert_default.glsl b/system/shaders/GL/1.5/gl_shader_vert_default.glsl
index e4f2d7c9ee..b68ef12925 100644
--- a/system/shaders/GL/1.5/gl_shader_vert_default.glsl
+++ b/system/shaders/GL/1.5/gl_shader_vert_default.glsl
@@ -8,4 +8,5 @@ void main ()
{
mat4 mvp = m_proj * m_model;
gl_Position = mvp * m_attrpos;
+ gl_Position.z = -1. * gl_Position.w;
}
diff --git a/system/shaders/GL/1.5/gl_shader_vert_simple.glsl b/system/shaders/GL/1.5/gl_shader_vert_simple.glsl
new file mode 100644
index 0000000000..953cdfcf8b
--- /dev/null
+++ b/system/shaders/GL/1.5/gl_shader_vert_simple.glsl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#version 150
+
+in vec4 m_attrpos;
+in vec4 m_attrcol;
+in vec4 m_attrcord0;
+in vec4 m_attrcord1;
+out vec4 m_cord0;
+out vec4 m_cord1;
+out vec4 m_colour;
+uniform mat4 m_matrix;
+uniform float m_depth;
+
+void main ()
+{
+ gl_Position = m_matrix * m_attrpos;
+ gl_Position.z = m_depth * gl_Position.w;
+ m_colour = m_attrcol;
+ m_cord0 = m_attrcord0;
+ m_cord1 = m_attrcord1;
+}
diff --git a/system/shaders/GL/1.5/gl_yuv2rgb_vertex.glsl b/system/shaders/GL/1.5/gl_yuv2rgb_vertex.glsl
index 4772bd4172..257aacfcc2 100644
--- a/system/shaders/GL/1.5/gl_yuv2rgb_vertex.glsl
+++ b/system/shaders/GL/1.5/gl_yuv2rgb_vertex.glsl
@@ -14,6 +14,7 @@ void main ()
{
mat4 mvp = m_proj * m_model;
gl_Position = mvp * m_attrpos;
+ gl_Position.z = -1. * gl_Position.w;
m_cordY = m_attrcordY;
m_cordU = m_attrcordU;
m_cordV = m_attrcordV;
diff --git a/system/shaders/GLES/2.0/gles_shader.vert b/system/shaders/GLES/2.0/gles_shader.vert
index 890acbbb81..17b4ad7b48 100644
--- a/system/shaders/GLES/2.0/gles_shader.vert
+++ b/system/shaders/GLES/2.0/gles_shader.vert
@@ -30,11 +30,13 @@ varying lowp vec4 m_colour;
uniform mat4 m_proj;
uniform mat4 m_model;
uniform mat4 m_coord0Matrix;
+uniform float m_depth;
void main ()
{
mat4 mvp = m_proj * m_model;
gl_Position = mvp * m_attrpos;
+ gl_Position.z = m_depth * gl_Position.w;
m_colour = m_attrcol;
m_cord0 = m_coord0Matrix * m_attrcord0;
m_cord1 = m_attrcord1;
diff --git a/system/shaders/GLES/2.0/gles_shader_clip.vert b/system/shaders/GLES/2.0/gles_shader_clip.vert
new file mode 100644
index 0000000000..1b1cf3f91e
--- /dev/null
+++ b/system/shaders/GLES/2.0/gles_shader_clip.vert
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#version 100
+
+attribute vec4 m_attrpos;
+attribute vec4 m_attrcol;
+attribute vec4 m_attrcord0;
+attribute vec4 m_attrcord1;
+varying vec4 m_cord0;
+varying vec4 m_cord1;
+varying vec4 m_colour;
+uniform mat4 m_matrix;
+uniform vec4 m_shaderClip;
+uniform vec4 m_cordStep;
+uniform float m_depth;
+
+// this shader can be used in cases where clipping via glScissor() is not
+// possible (e.g. when rotating). it can't discard triangles, but it may
+// degenerate them.
+
+void main()
+{
+ // limit the vertices to the clipping area
+ vec4 position = m_attrpos;
+ position.xy = clamp(position.xy, m_shaderClip.xy, m_shaderClip.zw);
+ gl_Position = m_matrix * position;
+
+ // set rendering depth
+ gl_Position.z = m_depth * gl_Position.w;
+
+ // correct texture coordinates for clipped vertices
+ vec2 clipDist = m_attrpos.xy - position.xy;
+ m_cord0.xy = m_attrcord0.xy - clipDist * m_cordStep.xy;
+ m_cord1.xy = m_attrcord1.xy - clipDist * m_cordStep.zw;
+
+ m_colour = m_attrcol;
+}
diff --git a/system/shaders/GLES/2.0/gles_shader_simple.vert b/system/shaders/GLES/2.0/gles_shader_simple.vert
new file mode 100644
index 0000000000..2f34f8bf28
--- /dev/null
+++ b/system/shaders/GLES/2.0/gles_shader_simple.vert
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#version 100
+
+attribute vec4 m_attrpos;
+attribute vec4 m_attrcol;
+attribute vec4 m_attrcord0;
+attribute vec4 m_attrcord1;
+varying vec4 m_cord0;
+varying vec4 m_cord1;
+varying vec4 m_colour;
+uniform mat4 m_matrix;
+uniform float m_depth;
+
+void main()
+{
+ gl_Position = m_matrix * m_attrpos;
+
+ // set rendering depth
+ gl_Position.z = m_depth * gl_Position.w;
+ m_colour = m_attrcol;
+ m_cord0 = m_attrcord0;
+ m_cord1 = m_attrcord1;
+}
diff --git a/system/shaders/GLES/2.0/gles_yuv2rgb.vert b/system/shaders/GLES/2.0/gles_yuv2rgb.vert
index bc437afdc3..c96a6a9585 100644
--- a/system/shaders/GLES/2.0/gles_yuv2rgb.vert
+++ b/system/shaders/GLES/2.0/gles_yuv2rgb.vert
@@ -34,6 +34,7 @@ void main ()
{
mat4 mvp = m_proj * m_model;
gl_Position = mvp * m_attrpos;
+ gl_Position.z = -1. * gl_Position.w;
m_cordY = m_attrcordY;
m_cordU = m_attrcordU;
m_cordV = m_attrcordV;
diff --git a/tools/Linux/kodi.sh.in b/tools/Linux/kodi.sh.in
index 52d4646db5..3d86c86834 100644
--- a/tools/Linux/kodi.sh.in
+++ b/tools/Linux/kodi.sh.in
@@ -171,6 +171,7 @@ if command_exists gdb; then
fi
fi
+ENV_ARGS=
if [ -n "${KODI_AE_SINK}" ]; then
echo "KODI_AE_SINK env variable is deprecated and will be removed in the future."
@@ -197,11 +198,11 @@ if [ -n "${KODI_GL_INTERFACE}" ]; then
echo "Use the --gl-interface command line switch instead."
if [ "${KODI_GL_INTERFACE}" = "GLX" ]; then
- ENV_ARGS="--gl-interface=glx"
+ ENV_ARGS="${ENV_ARGS} --gl-interface=glx"
elif [ "${KODI_GL_INTERFACE}" = "EGL" ]; then
- ENV_ARGS="--gl-interface=egl"
+ ENV_ARGS="${ENV_ARGS} --gl-interface=egl"
elif [ "${KODI_GL_INTERFACE}" = "EGL_PB" ]; then
- ENV_ARGS="--gl-interface=egl-pb"
+ ENV_ARGS="${ENV_ARGS} --gl-interface=egl-pb"
fi
fi
diff --git a/tools/android/packaging/Makefile.in b/tools/android/packaging/Makefile.in
index 98a15226a8..ca3c5c784a 100644
--- a/tools/android/packaging/Makefile.in
+++ b/tools/android/packaging/Makefile.in
@@ -60,17 +60,10 @@ python: | xbmc/assets
cd xbmc/assets/python@PYTHON_VERSION@/lib/python@PYTHON_VERSION@/; rm -rf test config config-@PYTHON_VERSION@ lib-dynload ; find . -name "*.so" -exec rm -f {} \;
res:
- mkdir -p xbmc/res xbmc/res/values images
+ mkdir -p xbmc/res xbmc/res/values
+ cp -rfp media/mipmap-* xbmc/res/
cp -fp $(CMAKE_SOURCE_DIR)/media/applaunch_screen.png xbmc/res/drawable/
- cp -fp media/drawable-hdpi/ic_launcher.png xbmc/res/drawable-hdpi/ic_launcher.png
- cp -fp media/drawable-ldpi/ic_launcher.png xbmc/res/drawable-ldpi/ic_launcher.png
- cp -fp media/drawable-mdpi/ic_launcher.png xbmc/res/drawable-mdpi/ic_launcher.png
- cp -fp media/drawable-xhdpi/ic_launcher.png xbmc/res/drawable-xhdpi/ic_launcher.png
- cp -fp media/drawable-xxhdpi/ic_launcher.png xbmc/res/drawable-xxhdpi/ic_launcher.png
cp -fp $(CMAKE_SOURCE_DIR)/media/applaunch_screen.png xbmc/res/drawable-xxxhdpi/
- cp -fp media/drawable-xxxhdpi/ic_launcher.png xbmc/res/drawable-xxxhdpi/ic_launcher.png
- cp -fp media/drawable-xhdpi/banner.png xbmc/res/drawable-xhdpi/banner.png
- cp -fp $(CMAKE_SOURCE_DIR)/media/icon80x80.png xbmc/res/drawable/ic_recommendation_80dp.png
cp xbmc/strings.xml xbmc/res/values/
cp xbmc/colors.xml xbmc/res/values/
cp xbmc/searchable.xml xbmc/res/xml/
@@ -108,12 +101,12 @@ $(PREFIX)/lib/xbmc/lib@APP_NAME_LC@.so: $(SRCLIBS)
$(SRCLIBS):
apk-clean:
- rm -rf images
rm -rf xbmc/java
rm -rf xbmc/lib
rm -rf xbmc/assets
rm -rf xbmc/obj
rm -rf xbmc/res/values
+ rm -rf xbmc/res/mipmap-*
rm -f xbmc/res/drawable/applaunch_screen.png
rm -f xbmc/res/drawable-xxxhdpi/applaunch_screen.png
rm -rf assets
diff --git a/tools/android/packaging/media/drawable-hdpi/ic_launcher.png b/tools/android/packaging/media/mipmap-hdpi/ic_launcher.png
index 2b262791af..2b262791af 100644
--- a/tools/android/packaging/media/drawable-hdpi/ic_launcher.png
+++ b/tools/android/packaging/media/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/tools/android/packaging/media/drawable-ldpi/ic_launcher.png b/tools/android/packaging/media/mipmap-ldpi/ic_launcher.png
index 20b2344fbe..20b2344fbe 100644
--- a/tools/android/packaging/media/drawable-ldpi/ic_launcher.png
+++ b/tools/android/packaging/media/mipmap-ldpi/ic_launcher.png
Binary files differ
diff --git a/tools/android/packaging/media/drawable-mdpi/ic_launcher.png b/tools/android/packaging/media/mipmap-mdpi/ic_launcher.png
index 9a9da949f3..9a9da949f3 100644
--- a/tools/android/packaging/media/drawable-mdpi/ic_launcher.png
+++ b/tools/android/packaging/media/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/tools/android/packaging/media/drawable-xhdpi/banner.png b/tools/android/packaging/media/mipmap-xhdpi/banner.png
index 86a2eeb14f..86a2eeb14f 100644
--- a/tools/android/packaging/media/drawable-xhdpi/banner.png
+++ b/tools/android/packaging/media/mipmap-xhdpi/banner.png
Binary files differ
diff --git a/tools/android/packaging/media/drawable-xhdpi/ic_launcher.png b/tools/android/packaging/media/mipmap-xhdpi/ic_launcher.png
index c09dae212e..c09dae212e 100644
--- a/tools/android/packaging/media/drawable-xhdpi/ic_launcher.png
+++ b/tools/android/packaging/media/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tools/android/packaging/media/drawable-xxhdpi/ic_launcher.png b/tools/android/packaging/media/mipmap-xxhdpi/ic_launcher.png
index 0dc4f5eaab..0dc4f5eaab 100644
--- a/tools/android/packaging/media/drawable-xxhdpi/ic_launcher.png
+++ b/tools/android/packaging/media/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/tools/android/packaging/media/drawable-xxxhdpi/ic_launcher.png b/tools/android/packaging/media/mipmap-xxxhdpi/ic_launcher.png
index 89ce21773c..89ce21773c 100644
--- a/tools/android/packaging/media/drawable-xxxhdpi/ic_launcher.png
+++ b/tools/android/packaging/media/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/tools/android/packaging/xbmc/AndroidManifest.xml.in b/tools/android/packaging/xbmc/AndroidManifest.xml.in
index a27d2fea9e..52b28bd0dc 100644
--- a/tools/android/packaging/xbmc/AndroidManifest.xml.in
+++ b/tools/android/packaging/xbmc/AndroidManifest.xml.in
@@ -42,11 +42,11 @@
android:required="false" />
<application
- android:banner="@drawable/banner"
+ android:banner="@mipmap/banner"
android:hasCode="true"
- android:icon="@drawable/ic_launcher"
+ android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
- android:logo="@drawable/banner"
+ android:logo="@mipmap/banner"
android:requestLegacyExternalStorage="true">
<activity
android:name=".Splash"
diff --git a/tools/android/packaging/xbmc/res/layout/activity_splash.xml b/tools/android/packaging/xbmc/res/layout/activity_splash.xml
index 42e2e29333..39c2b6e30e 100644
--- a/tools/android/packaging/xbmc/res/layout/activity_splash.xml
+++ b/tools/android/packaging/xbmc/res/layout/activity_splash.xml
@@ -7,11 +7,10 @@
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_centerHorizontal="true"
android:adjustViewBounds="true"
- android:layout_alignParentTop="true"
android:scaleType="centerCrop"
- android:src="@drawable/applaunch_screen" />
+ android:src="@drawable/applaunch_screen"
+ android:contentDescription="@string/app_name" />
<RelativeLayout
android:layout_width="wrap_content"
@@ -23,8 +22,8 @@
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentRight="true"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginLeft="20dp"
@@ -41,7 +40,7 @@
android:layout_centerHorizontal="true"
android:text=""
android:textColor="@android:color/white"
- android:textSize="16dp" />
+ android:textSize="16sp" />
</RelativeLayout>
</FrameLayout>
diff --git a/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in b/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in
index 24d9239d89..9ec4a64641 100644
--- a/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in
+++ b/tools/android/packaging/xbmc/src/XBMCJsonRPC.java.in
@@ -24,15 +24,15 @@ import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;
+import @APP_PACKAGE@.content.XBMCFileContentProvider;
import @APP_PACKAGE@.model.Album;
+import @APP_PACKAGE@.model.File;
+import @APP_PACKAGE@.model.Media;
import @APP_PACKAGE@.model.Movie;
import @APP_PACKAGE@.model.MusicVideo;
import @APP_PACKAGE@.model.Song;
import @APP_PACKAGE@.model.TVEpisode;
import @APP_PACKAGE@.model.TVShow;
-import @APP_PACKAGE@.content.XBMCFileContentProvider;
-import @APP_PACKAGE@.model.File;
-import @APP_PACKAGE@.model.Media;
public class XBMCJsonRPC
{
@@ -63,6 +63,7 @@ public class XBMCJsonRPC
private String m_xbmc_web_url = "http://localhost:8080";
private HashSet<Integer> mRecomendationIds = new HashSet<Integer>();
+ private XBMCTextureCache mTextureCache = null;
private int MAX_RECOMMENDATIONS = 3;
@@ -126,6 +127,7 @@ public class XBMCJsonRPC
{
String jsonPort = XBMCProperties.getStringProperty("xbmc.jsonPort", "8080");
m_xbmc_web_url = "http://localhost:" + jsonPort;
+ mTextureCache = new XBMCTextureCache();
}
public String request_string(String jsonRequest)
@@ -864,7 +866,7 @@ public class XBMCJsonRPC
String poster = extractKeyFromArtMap(details, "poster");
if (poster != null && !poster.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString());
+ med.setCardImageUrl(getImageUrl(poster));
med.setCardImageAspectRatio("2:3");
}
// fallback to thumb
@@ -873,7 +875,7 @@ public class XBMCJsonRPC
poster = extractKeyFromArtMap(details, "thumb");
if (poster != null && !poster.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString());
+ med.setCardImageUrl(getImageUrl(poster));
med.setCardImageAspectRatio("16:9");
}
}
@@ -881,7 +883,7 @@ public class XBMCJsonRPC
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("videodb://movies/titles/" + details.get("movieid").getAsString() + "?showinfo=true");
@@ -935,7 +937,7 @@ public class XBMCJsonRPC
String poster = extractKeyFromArtMap(details, "poster");
if (poster != null && !poster.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString());
+ med.setCardImageUrl(getImageUrl(poster));
med.setCardImageAspectRatio("2:3");
}
// fallback to thumb
@@ -944,7 +946,7 @@ public class XBMCJsonRPC
poster = extractKeyFromArtMap(details, "thumb");
if (poster != null && !poster.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(poster).toString());
+ med.setCardImageUrl(getImageUrl(poster));
med.setCardImageAspectRatio("16:9");
}
}
@@ -952,7 +954,7 @@ public class XBMCJsonRPC
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("videodb://tvshows/titles/" + details.get("tvshowid").getAsInt() + "/");
med.setCategory(Media.MEDIA_TYPE_TVSHOW);
@@ -982,14 +984,14 @@ public class XBMCJsonRPC
String thumb = extractKeyFromArtMap(details, "thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("16:9");
}
// fanart
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("videodb://tvshows/titles/" + details.get("tvshowid").getAsInt() + "/" + details.get("episodeid").getAsInt() + "?showinfo=true");
@@ -1029,14 +1031,14 @@ public class XBMCJsonRPC
String thumb = extractKeyFromArtMap(details, "thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
// fanart
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("musicdb://albums/" + details.get("albumid").getAsString() + "/");
@@ -1064,7 +1066,7 @@ public class XBMCJsonRPC
String thumb = extractKeyFromArtMap(details, "album.thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
// fallback to albumartist.thumb
@@ -1073,7 +1075,7 @@ public class XBMCJsonRPC
thumb = extractKeyFromArtMap(details, "albumartist.thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
else
@@ -1082,7 +1084,7 @@ public class XBMCJsonRPC
thumb = extractKeyFromArtMap(details, "artist.thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
}
@@ -1091,14 +1093,14 @@ public class XBMCJsonRPC
String fanart = extractKeyFromArtMap(details, "albumartist.fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
else
{
fanart = extractKeyFromArtMap(details, "artist.fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
}
@@ -1145,21 +1147,21 @@ public class XBMCJsonRPC
String thumb = extractKeyFromArtMap(details, "thumb");
if (thumb != null && !thumb.isEmpty())
{
- med.setCardImageUrl(XBMCFileContentProvider.buildUri(thumb).toString());
+ med.setCardImageUrl(getImageUrl(thumb));
med.setCardImageAspectRatio("1:1");
}
// fanart
String fanart = extractKeyFromArtMap(details, "fanart");
if (fanart != null && !fanart.isEmpty())
{
- med.setBackgroundImageUrl(XBMCFileContentProvider.buildUri(fanart).toString());
+ med.setBackgroundImageUrl(getImageUrl(fanart));
}
med.setXbmcUrl("videodb://musicvideos/titles/" + details.get("musicvideoid").getAsInt());
String url = getDownloadUrl(details.get("file").getAsString());
if (url != null && !url.isEmpty())
- med.setVideoUrl(XBMCFileContentProvider.buildUri(url).toString());
+ med.setVideoUrl(getImageUrl(url));
med.setCategory(Media.MEDIA_TYPE_MUSICVIDEO);
}
@@ -1438,4 +1440,23 @@ public class XBMCJsonRPC
return String.valueOf(rating / 2.0);
}
+ private String getImageUrl(String sUrl)
+ {
+ Log.d(TAG, "getImageUrl: sUrl = " + sUrl);
+ if (sUrl.startsWith("image://video@") || sUrl.startsWith("image://music@"))
+ {
+ Log.d(TAG, "getImageUrl: " + sUrl + " is not unwrapped");
+ return XBMCFileContentProvider.buildUri(sUrl).toString();
+ }
+
+ String sUnwrapImageUrl = this.mTextureCache.unwrapImageURL(sUrl);
+ Log.d(TAG, "getImageUrl: sUnwrapImageUrl = " + sUnwrapImageUrl);
+ if (!sUnwrapImageUrl.startsWith("http"))
+ {
+ return XBMCFileContentProvider.buildUri(sUrl).toString();
+ }
+
+ return sUnwrapImageUrl;
+ }
+
}
diff --git a/tools/android/packaging/xbmc/src/XBMCTextureCache.java.in b/tools/android/packaging/xbmc/src/XBMCTextureCache.java.in
new file mode 100644
index 0000000000..09dd7265f5
--- /dev/null
+++ b/tools/android/packaging/xbmc/src/XBMCTextureCache.java.in
@@ -0,0 +1,32 @@
+package @APP_PACKAGE@;
+
+import android.util.Log;
+
+/**
+ * Created by Maven85 on 16/03/2020.
+ */
+
+public class XBMCTextureCache
+{
+ native String _unwrapImageURL(String image);
+
+ private static final String TAG = "@APP_NAME@";
+
+ public XBMCTextureCache()
+ {
+ }
+
+ public String unwrapImageURL(String image)
+ {
+ try
+ {
+ return _unwrapImageURL(image);
+ }
+ catch (Exception e)
+ {
+ Log.e(TAG, "unwrapImageURL: Exception: " + e.getMessage());
+ return null;
+ }
+ }
+
+}
diff --git a/tools/depends/configure.ac b/tools/depends/configure.ac
index 9bce943cc0..26bd6e8a5e 100644
--- a/tools/depends/configure.ac
+++ b/tools/depends/configure.ac
@@ -200,7 +200,7 @@ case $build in
# Android NDK currently only x86_64 prebuilts - Arctic Fox 2020.3.1
android_toolchain_name="darwin-x86_64"
- host_cxxflags="-std=c++17 -stdlib=libc++"
+ host_cxxflags="-std=c++17"
if test "x$prefix" = "xNONE"; then
prefix=/Users/Shared/xbmc-depends
@@ -418,7 +418,6 @@ case $host in
meson_system="darwin"
- platform_cflags="-fheinous-gnu-extensions"
platform_ldflags="-Wl,-search_paths_first"
case $use_platform in
@@ -493,8 +492,7 @@ case $host in
platform_min_version="$target_platform-version-min=$target_minver"
platform_includes="-arch $use_cpu -m$platform_min_version -isysroot $use_sdk_path"
- platform_ldflags="${platform_ldflags} $platform_includes -stdlib=libc++"
- platform_cxxflags="${platform_cxxflags} -stdlib=libc++"
+ platform_ldflags="${platform_ldflags} $platform_includes"
deps_dir="${sdk_name}_${use_cpu}-target-${build_type}"
;;
*)
diff --git a/tools/depends/native/cargo-c/CARGO-C-VERSION b/tools/depends/native/cargo-c/CARGO-C-VERSION
index b3737ba01a..16ff2b8b07 100644
--- a/tools/depends/native/cargo-c/CARGO-C-VERSION
+++ b/tools/depends/native/cargo-c/CARGO-C-VERSION
@@ -1,5 +1,4 @@
APPNAME=cargo-c
-VERSION=0.9.21
-SOURCE=$(APPNAME)-$(VERSION)
-ARCHIVE=$(SOURCE).tar.gz
-SHA512=855391c29843f8e5f204f889cab16d5d569ebb2174367a8be0d4be3d87141133f98fb7a6750ed0030783a1ff29f358d60c6ca79ed5bb65f61196c726f9c1a0ec
+VERSION=0.9.31
+ARCHIVE=$(APPNAME)-$(VERSION).tar.gz
+SHA512=12aa5fd857ca6fdba50ffb08d120084ac063b5dfad037b54caf3e28ccaa36bfd07b43e61619ccce72c081655e1759be05f455ea93caebb0e763a63dd4246d0cf
diff --git a/tools/depends/native/cargo-c/Makefile b/tools/depends/native/cargo-c/Makefile
index 3c12014999..9dc8ab7f8d 100644
--- a/tools/depends/native/cargo-c/Makefile
+++ b/tools/depends/native/cargo-c/Makefile
@@ -9,7 +9,8 @@ export PKG_CONFIG_PATH=$(PREFIX)/lib/pkgconfig
APP=$(PLATFORM)/target/release/$(APPNAME)
CARGO_ENV_VARS = RUSTUP_HOME=$(PREFIX)/.rustup \
- CARGO_HOME=$(PREFIX)/.cargo
+ CARGO_HOME=$(PREFIX)/.cargo \
+ OPENSSL_DIR=$(PREFIX)
CARGO = $(CARGO_ENV_VARS) $(PREFIX)/bin/cargo
CLEANUP_CMD = [ -e $(PREFIX)/bin/cargo ] \
diff --git a/tools/depends/native/openssl/OPENSSL-VERSION b/tools/depends/native/openssl/OPENSSL-VERSION
index 1712a0c3da..424c6d4036 100644
--- a/tools/depends/native/openssl/OPENSSL-VERSION
+++ b/tools/depends/native/openssl/OPENSSL-VERSION
@@ -1,4 +1,4 @@
LIBNAME=openssl
-VERSION=1.1.1w
+VERSION=3.0.13
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
-SHA512=b4c625fe56a4e690b57b6a011a225ad0cb3af54bd8fb67af77b5eceac55cc7191291d96a660c5b568a08a2fbf62b4612818e7cca1bb95b2b6b4fc649b0552b6d
+SHA512=22f4096781f0b075f5bf81bd39a0f97e111760dfa73b6f858f6bb54968a7847944d74969ae10f9a51cc21a2f4af20d9a4c463649dc824f5e439e196d6764c4f9
diff --git a/tools/depends/native/rustup/Makefile b/tools/depends/native/rustup/Makefile
index c9f1c07570..83f993c158 100644
--- a/tools/depends/native/rustup/Makefile
+++ b/tools/depends/native/rustup/Makefile
@@ -17,7 +17,7 @@ APP=$(PLATFORM)/bin/$(APPNAME)
export RUSTUP_HOME=$(PREFIX)/.rustup
export CARGO_HOME=$(PREFIX)/.cargo
-RUST_TOOLCHAIN_VERSION=1.75.0
+RUST_TOOLCHAIN_VERSION=1.78.0
RUSTUP_ENV_VARS = RUSTUP_HOME=$(PREFIX)/.rustup \
CARGO_HOME=$(PREFIX)/.cargo
RUSTUP = $(RUSTUP_ENV_VARS) $(PREFIX)/bin/rustup
diff --git a/tools/depends/native/rustup/RUSTUP-VERSION b/tools/depends/native/rustup/RUSTUP-VERSION
index ae487ce2b8..3db97524b6 100644
--- a/tools/depends/native/rustup/RUSTUP-VERSION
+++ b/tools/depends/native/rustup/RUSTUP-VERSION
@@ -1,5 +1,5 @@
APPNAME=rustup
-VERSION=1.26.0
+VERSION=1.27.0
SOURCE=$(APPNAME)-$(VERSION)
ARCHIVE=$(SOURCE).tar.gz
-SHA512=bc7cb580640248a601dbafb87c3a9e908b6c687377b4e0f88280576af15527f5837d9463f7831c14b0c274cd3170449e634cd851e0d03ea4ff1d0461d4a941be
+SHA512=0b9349364e0f9d60ba0d486064295413012d38ec97597207b3c82e07ebcf6b5ade403a46fb3910fe4d63607150ce5b0e367ac322f894599bd6b02dae3872e8f0
diff --git a/tools/depends/target/Makefile b/tools/depends/target/Makefile
index a498d373e4..e47e8bff26 100644
--- a/tools/depends/target/Makefile
+++ b/tools/depends/target/Makefile
@@ -6,8 +6,8 @@ endif
# Keep in alphabetical order
DEPENDS = \
+ brotli \
bzip2 \
- curl \
dav1d \
expat \
ffmpeg \
@@ -150,7 +150,7 @@ $(DOWNLOAD_TARGETS):
download: $(DOWNLOAD_TARGETS)
crossguid: $(LIBUUID)
-curl: openssl nghttp2 $(ZLIB)
+curl: brotli openssl nghttp2 $(ZLIB)
dbus: expat
ffmpeg: $(ICONV) $(ZLIB) bzip2 gnutls dav1d $(LIBVA)
fontconfig: freetype2 expat $(ICONV) $(LIBUUID)
diff --git a/tools/depends/target/brotli/01-all-disable-exe.patch b/tools/depends/target/brotli/01-all-disable-exe.patch
new file mode 100644
index 0000000000..8b02506443
--- /dev/null
+++ b/tools/depends/target/brotli/01-all-disable-exe.patch
@@ -0,0 +1,28 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -169,15 +169,19 @@
+ endif()
+
+ # Build the brotli executable
+-add_executable(brotli c/tools/brotli.c)
+-target_link_libraries(brotli ${BROTLI_LIBRARIES})
++if(NOT BROTLI_DISABLE_EXE)
++ add_executable(brotli c/tools/brotli.c)
++ target_link_libraries(brotli ${BROTLI_LIBRARIES})
++endif()
+
+ # Installation
+ if(NOT BROTLI_BUNDLED_MODE)
+- install(
+- TARGETS brotli
+- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+- )
++ if(NOT BROTLI_DISABLE_EXE)
++ install(
++ TARGETS brotli
++ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
++ )
++ endif()
+
+ install(
+ TARGETS ${BROTLI_LIBRARIES_CORE}
diff --git a/tools/depends/target/brotli/BROTLI-VERSION b/tools/depends/target/brotli/BROTLI-VERSION
new file mode 100644
index 0000000000..7747ea6a22
--- /dev/null
+++ b/tools/depends/target/brotli/BROTLI-VERSION
@@ -0,0 +1,5 @@
+LIBNAME=brotli
+VERSION=1.1.0
+ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
+SHA512=6eb280d10d8e1b43d22d00fa535435923c22ce8448709419d676ff47d4a644102ea04f488fc65a179c6c09fee12380992e9335bad8dfebd5d1f20908d10849d9
+BYPRODUCT=libbrotlidec.a
diff --git a/tools/depends/target/brotli/Makefile b/tools/depends/target/brotli/Makefile
new file mode 100644
index 0000000000..e3154fb8ce
--- /dev/null
+++ b/tools/depends/target/brotli/Makefile
@@ -0,0 +1,33 @@
+include ../../Makefile.include BROTLI-VERSION ../../download-files.include
+DEPS = ../../Makefile.include Makefile BROTLI-VERSION ../../download-files.include \
+ 01-all-disable-exe.patch
+
+LIBDYLIB=$(PLATFORM)/build/$(BYPRODUCT)
+
+CMAKE_OPTIONS=-DBUILD_SHARED_LIBS=OFF \
+ -DCMAKE_INSTALL_PREFIX=$(PREFIX) \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBROTLI_DISABLE_TESTS=ON \
+ -DBROTLI_DISABLE_EXE=ON
+
+all: .installed-$(PLATFORM)
+
+$(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE)
+ rm -rf $(PLATFORM); mkdir -p $(PLATFORM)/build
+ cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
+ cd $(PLATFORM); patch -p1 -i ../01-all-disable-exe.patch
+ cd $(PLATFORM)/build; $(CMAKE) ${CMAKE_OPTIONS} ..
+
+$(LIBDYLIB): $(PLATFORM)
+ $(MAKE) -C $(PLATFORM)/build
+
+.installed-$(PLATFORM): $(LIBDYLIB)
+ $(MAKE) -C $(PLATFORM)/build install
+ touch $@
+
+clean:
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
+
+distclean::
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
+
diff --git a/tools/depends/target/cec/Makefile b/tools/depends/target/cec/Makefile
index 403f4f03f1..6b9fd9835d 100644
--- a/tools/depends/target/cec/Makefile
+++ b/tools/depends/target/cec/Makefile
@@ -19,7 +19,7 @@ CMAKE_OPTIONS=-DBUILD_SHARED_LIBS=1 \
all: .installed-$(PLATFORM)
-$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE) $(DEPS)
+$(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE)
rm -rf $(PLATFORM); mkdir -p $(PLATFORM)/build
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); patch -p1 -i ../001-all-cmakelists.patch
diff --git a/tools/depends/target/curl/01-win-nghttp2-add-name.patch b/tools/depends/target/curl/01-win-nghttp2-add-name.patch
new file mode 100644
index 0000000000..e07843010a
--- /dev/null
+++ b/tools/depends/target/curl/01-win-nghttp2-add-name.patch
@@ -0,0 +1,11 @@
+--- a/CMake/FindNGHTTP2.cmake
++++ b/CMake/FindNGHTTP2.cmake
+@@ -25,7 +25,7 @@
+
+ find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
+
+-find_library(NGHTTP2_LIBRARY NAMES nghttp2)
++find_library(NGHTTP2_LIBRARY NAMES nghttp2 nghttp2_static)
+
+ find_package_handle_standard_args(NGHTTP2
+ FOUND_VAR
diff --git a/tools/depends/target/curl/CURL-VERSION b/tools/depends/target/curl/CURL-VERSION
index 42bdd1d64f..f9a42c2939 100644
--- a/tools/depends/target/curl/CURL-VERSION
+++ b/tools/depends/target/curl/CURL-VERSION
@@ -1,5 +1,6 @@
LIBNAME=curl
-VERSION=8.4.0
+VERSION=8.7.1
ARCHIVE=$(LIBNAME)-$(VERSION).tar.xz
-SHA512=7027dbf3b759b39d6ec9c4da58fadd254e84bb93bff599541b3bc3135bad4c2955c6237d7ddd60973f9f1a6948bc32d7e312985fb50658bc958b9f22fee74f2b
+SHA512=5bbde9d5648e9226f5490fa951690aaf159149345f3a315df2ba58b2468f3e59ca32e8a49734338afc861803a4f81caac6d642a4699b72c6310ebfb1f618aad2
BYPRODUCT=libcurl.a
+BYPRODUCT_WIN=libcurl.lib
diff --git a/tools/depends/target/curl/Makefile b/tools/depends/target/curl/Makefile
index 896a67ddf4..1b5a4c1ab2 100644
--- a/tools/depends/target/curl/Makefile
+++ b/tools/depends/target/curl/Makefile
@@ -1,64 +1,48 @@
include ../../Makefile.include CURL-VERSION ../../download-files.include
DEPS = ../../Makefile.include Makefile CURL-VERSION ../../download-files.include
-# configuration settings
-CONFIGURE=cp -f $(CONFIG_SUB) $(CONFIG_GUESS) .; \
- ./configure --prefix=$(PREFIX) \
- --disable-shared \
- --disable-ldap \
- --without-libssh2 \
- --disable-ntlm-wb \
- --enable-ipv6 \
- --without-librtmp \
- --without-libidn2 \
- --with-ca-fallback \
- --with-ssl=$(PREFIX) \
- --with-nghttp2=$(PREFIX) \
- --with-zlib \
- --without-libpsl \
- --without-zstd \
- --without-brotli \
- --without-gssapi \
- --without-gsasl \
- --without-hyper \
- --without-ngtcp2 \
- --without-nghttp3 \
- --without-quiche \
- --without-msh3 \
- --without-gnutls \
- --without-nss \
- --without-mbedtls \
- --without-wolfssl
-
-LIBDYLIB=$(PLATFORM)/lib/.libs/$(BYPRODUCT)
+CMAKE_OPTIONS=-DCMAKE_INSTALL_PREFIX=$(PREFIX) \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_CURL_EXE=OFF \
+ -DBUILD_SHARED_LIBS=OFF \
+ -DBUILD_STATIC_LIBS=ON \
+ -DBUILD_LIBCURL_DOCS=OFF \
+ -DENABLE_CURL_MANUAL=OFF \
+ -DCURL_DISABLE_TESTS=OFF \
+ -DCURL_DISABLE_LDAP=ON \
+ -DCURL_DISABLE_LDAPS=ON \
+ -DCURL_DISABLE_SMB=OFF \
+ -DCURL_USE_OPENSSL=ON \
+ -DOPENSSL_ROOT_DIR=$(PREFIX) \
+ -DCURL_BROTLI=ON \
+ -DUSE_NGHTTP2=ON \
+ -DUSE_LIBIDN2=OFF \
+ -DCURL_USE_LIBSSH2=OFF \
+ -DCURL_USE_GSSAPI=OFF \
+ -DCURL_CA_FALLBACK=ON
+
+LIBDYLIB=$(PLATFORM)/build/lib/$(BYPRODUCT)
all: .installed-$(PLATFORM)
$(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE)
- rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
+ rm -rf $(PLATFORM); mkdir -p $(PLATFORM)/build
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
- cd $(PLATFORM); $(AUTORECONF) -vif
- cd $(PLATFORM); $(CONFIGURE)
+ cd $(PLATFORM)/build; $(CMAKE) ${CMAKE_OPTIONS} ..
$(LIBDYLIB): $(PLATFORM)
- $(MAKE) -C $(PLATFORM)/lib
+ $(MAKE) -C $(PLATFORM)/build
.installed-$(PLATFORM): $(LIBDYLIB)
- # install only libcurl and includes
- $(MAKE) -C $(PLATFORM)/lib install
- $(MAKE) -C $(PLATFORM)/include install
- # make sure to also install libcurl.pc, we need to do
- # this because we are selectively installing only libcurl
- $(MAKE) -C $(PLATFORM) install-pkgconfigDATA
+ $(MAKE) -C $(PLATFORM)/build install
touch $@
clean:
- $(MAKE) -C $(PLATFORM) clean
- rm -f .installed-$(PLATFORM)
+ rm -rf $(PLATFORM) .installed-$(PLATFORM)
distclean::
rm -rf $(PLATFORM) .installed-$(PLATFORM)
.PHONY: update-cacert
update-cacert: $(PLATFORM)
- $(PLATFORM)/lib/mk-ca-bundle.pl -u $(CMAKE_SOURCE_DIR)/system/certs/cacert.pem
+ $(PLATFORM)/scripts/mk-ca-bundle.pl -u $(CMAKE_SOURCE_DIR)/system/certs/cacert.pem
diff --git a/tools/depends/target/effects11/01-win-debugpostfix.patch b/tools/depends/target/effects11/01-win-debugpostfix.patch
new file mode 100644
index 0000000000..b10d6e96fe
--- /dev/null
+++ b/tools/depends/target/effects11/01-win-debugpostfix.patch
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -22,6 +22,8 @@
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+ set(CMAKE_CXX_EXTENSIONS OFF)
+
++set(CMAKE_DEBUG_POSTFIX d)
++
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/CMake")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/CMake")
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/CMake")
diff --git a/tools/depends/target/effects11/EFFECTS11-VERSION b/tools/depends/target/effects11/EFFECTS11-VERSION
new file mode 100644
index 0000000000..a20e4907a3
--- /dev/null
+++ b/tools/depends/target/effects11/EFFECTS11-VERSION
@@ -0,0 +1,5 @@
+LIBNAME=FX11
+VERSION=11.29
+ARCHIVE=$(LIBNAME)-jun2023.tar.gz
+SHA512=93a90b42efbc8e1e9cb76de80c959bc24406536af9d943d21e324a82be677d695c201deb995490e331ecfcda301d8b42285b90577fbed9acd5bb61c753efd66c
+BYPRODUCT_WIN=effects11.lib
diff --git a/tools/depends/target/gmp/Makefile b/tools/depends/target/gmp/Makefile
index 9c3e85752b..ffdcbfd97e 100644
--- a/tools/depends/target/gmp/Makefile
+++ b/tools/depends/target/gmp/Makefile
@@ -46,7 +46,7 @@ LIBDYLIB=$(PLATFORM)/.libs/lib$(LIBNAME).a
all: .installed-$(PLATFORM)
-$(PLATFORM)/config.status: $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE) $(DEPS)
+$(PLATFORM)/config.status: $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE)
rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); $(CONFIGURE)
diff --git a/tools/depends/target/gnutls/Makefile b/tools/depends/target/gnutls/Makefile
index f60773dce9..1b1e5e3287 100644
--- a/tools/depends/target/gnutls/Makefile
+++ b/tools/depends/target/gnutls/Makefile
@@ -1,8 +1,7 @@
include ../../Makefile.include GNUTLS-VERSION ../../download-files.include
DEPS = ../../Makefile.include Makefile ../../download-files.include \
add-dl-as-private-lib.patch \
- 03-support-correct-cisdigit.patch \
- android-fpending.patch
+ 03-support-correct-cisdigit.patch
# disable rpl_malloc and rpl_realloc symbols in glib
# causes linking errors in libmicrohttpd and ffmpeg with missing symbols
@@ -32,6 +31,7 @@ CONFIGURE=./configure --prefix=$(PREFIX) \
--disable-guile \
--disable-tools \
--without-idn \
+ --without-brotli \
$(CONFIGURE_OPTIONS)
# LLVM 15 has raised this to error by default. drop back to warning
@@ -47,7 +47,6 @@ $(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE)
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); patch -p1 -i ../add-dl-as-private-lib.patch
cd $(PLATFORM); patch -p1 -i ../03-support-correct-cisdigit.patch
- cd $(PLATFORM); patch -p1 -i ../android-fpending.patch
cd $(PLATFORM); $(AUTORECONF) -vif
cd $(PLATFORM); $(CONFIGURE)
diff --git a/tools/depends/target/gnutls/android-fpending.patch b/tools/depends/target/gnutls/android-fpending.patch
deleted file mode 100644
index a16f671908..0000000000
--- a/tools/depends/target/gnutls/android-fpending.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/src/gl/fpending.c
-+++ b/src/gl/fpending.c
-@@ -39,7 +39,9 @@
- #if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
- /* GNU libc, BeOS, Haiku, Linux libc5 */
- return fp->_IO_write_ptr - fp->_IO_write_base;
--#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
-+#elif defined __ANDROID__
-+ return fp_->_p - fp_->_bf._base;
-+#elif defined __sferror || defined __DragonFly__
- /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin < 1.7.34, Minix 3, Android */
- return fp->_p - fp->_bf._base;
- #elif defined __EMX__ /* emx+gcc */
diff --git a/tools/depends/target/libgcrypt/Makefile b/tools/depends/target/libgcrypt/Makefile
index bb5a0053c5..2fefa9b66f 100644
--- a/tools/depends/target/libgcrypt/Makefile
+++ b/tools/depends/target/libgcrypt/Makefile
@@ -1,13 +1,6 @@
include ../../Makefile.include LIBGCRYPT-VERSION ../../download-files.include
DEPS = ../../Makefile.include Makefile LIBGCRYPT-VERSION ../../download-files.include
-ifeq ($(OS),android)
- # Just blanket disable neon support for non arm64 arch
- ifneq ($(findstring arm64, $(CPU)), arm64)
- CONFIGURE_FLAGS+= --disable-neon-support
- endif
-endif
-
ifeq ($(findstring apple-darwin, $(HOST)), apple-darwin)
# required to fix asm link failure due C_SYMBOL_NAME macro not prepending _ to exported symbol
# exported symbols only have s single _ instead of double __
diff --git a/tools/depends/target/openssl/001-android-getauxvalrevert.patch b/tools/depends/target/openssl/001-android-getauxvalrevert.patch
index 810a8e80bb..1e75c57374 100644
--- a/tools/depends/target/openssl/001-android-getauxvalrevert.patch
+++ b/tools/depends/target/openssl/001-android-getauxvalrevert.patch
@@ -1,6 +1,6 @@
--- a/crypto/armcap.c
+++ b/crypto/armcap.c
-@@ -68,12 +68,6 @@
+@@ -74,12 +74,6 @@
# include <sys/auxv.h>
# define OSSL_IMPLEMENT_GETAUXVAL
# endif
@@ -13,7 +13,7 @@
# endif
# if defined(__FreeBSD__)
# include <sys/param.h>
-@@ -94,15 +88,6 @@
+@@ -100,15 +94,6 @@
# endif
/*
@@ -31,7 +31,7 @@
*/
--- a/crypto/ppccap.c
+++ b/crypto/ppccap.c
-@@ -211,12 +211,6 @@
+@@ -89,12 +89,6 @@
# if __GLIBC_PREREQ(2, 16)
# include <sys/auxv.h>
# define OSSL_IMPLEMENT_GETAUXVAL
diff --git a/tools/depends/target/openssl/16-kodi.conf b/tools/depends/target/openssl/16-kodi.conf
index eccb609a27..1855ed462c 100644
--- a/tools/depends/target/openssl/16-kodi.conf
+++ b/tools/depends/target/openssl/16-kodi.conf
@@ -5,28 +5,28 @@
#
my %targets = (
"kodi-darwin64-x86_64" => {
- inherit_from => [ "darwin-common", asm("x86_64_asm") ],
- cflags => add("\$(CFLAGS)"),
+ inherit_from => [ "darwin-common" ],
+ asm_arch => 'x86_64',
lib_cppflags => add("-DL_ENDIAN"),
bn_ops => "SIXTY_FOUR_BIT_LONG",
perlasm_scheme => "macosx",
},
"kodi-darwin64-arm64" => {
- inherit_from => [ "darwin-common", asm("aarch64_asm") ],
- cflags => add("\$(CFLAGS)"),
+ inherit_from => [ "darwin-common" ],
+ asm_arch => 'aarch64',
lib_cppflags => add("-DL_ENDIAN"),
bn_ops => "SIXTY_FOUR_BIT_LONG",
perlasm_scheme => "ios64",
},
"kodi-iphoneos-arm64" => {
- inherit_from => [ "ios-common", asm("aarch64_asm") ],
- cflags => add("\$(CFLAGS)"),
+ inherit_from => [ "ios-common" ],
+ asm_arch => 'aarch64',
bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
perlasm_scheme => "ios64",
},
"kodi-appletvos-arm64" => {
- inherit_from => [ "ios-common", asm("aarch64_asm") ],
- cflags => add("\$(CFLAGS)"),
+ inherit_from => [ "ios-common"],
+ asm_arch => 'aarch64',
defines => [ "HAVE_FORK=0" ],
bn_ops => "SIXTY_FOUR_BIT_LONG RC4_CHAR",
perlasm_scheme => "ios64",
diff --git a/tools/depends/target/openssl/Makefile b/tools/depends/target/openssl/Makefile
index c03177e484..6a7f614153 100644
--- a/tools/depends/target/openssl/Makefile
+++ b/tools/depends/target/openssl/Makefile
@@ -4,15 +4,27 @@ DEPS = ../../Makefile.include Makefile OPENSSL-VERSION ../../download-files.incl
# configuration settings
ifeq ($(OS), linux)
- # Need to export our vars to override "default" conf data of openssl
TARGETOPT=--with-zlib-include=$(PREFIX)/include --with-zlib-lib=$(PREFIX)/lib
- CONFIGURE=MACHINE=$(PLATFORM) ./config no-shared zlib no-tests no-asm $(TARGETOPT) --prefix=$(PREFIX) --libdir=lib
+ CONFIGURE=./Configure no-shared zlib no-tests no-asm no-module $(TARGETOPT) --prefix=$(PREFIX) --libdir=lib
+ ifeq ($(TARGET_PLATFORM),webos)
+ CONFIGURE+= linux-armv4
+ else
+ ifeq ($(CPU),aarch64)
+ CONFIGURE+= linux-aarch64
+ else ifeq ($(CPU),arm)
+ CONFIGURE+= linux-armv4
+ else ifeq ($(CPU),x86_64)
+ CONFIGURE+= linux-x86_64
+ else
+ # Fallback to base generic linux target
+ CONFIGURE+= linux-generic32
+ endif
+ endif
else
ifeq ($(OS), android)
- TARGETOPT=--with-zlib-include=$(PREFIX)/include --with-zlib-lib=$(PREFIX)/lib -D__ANDROID_API__=$(NDK_LEVEL)
- # openssl 1.x incorrectly uses ANDROID_NDK_HOME, when openssl 3.x.x comes in use ANDROID_NDK_ROOT
- # see https://github.com/openssl/openssl/pull/11206
- export ANDROID_NDK_HOME=$(NDKROOT)
+ TARGETOPT=--with-zlib-include=$(PREFIX)/include --with-zlib-lib=$(PREFIX)/lib -U__ANDROID_API__ -D__ANDROID_API__=$(NDK_LEVEL)
+
+ export ANDROID_NDK_ROOT=$(NDKROOT)
export PATH:=$(TOOLCHAIN)/bin:$(PATH)
ifeq ($(MESON_CPU), aarch64)
OPENSSLPLATFORM=android-arm64
@@ -24,18 +36,21 @@ else
# LLVM 15 has raised this to error by default. drop back to warning
CFLAGS+= -Wno-error=implicit-int
export SDKROOT CFLAGS
- OPENSSLPLATFORM=kodi-$(TARGET_PLATFORM)-$(CPU)
+ OPENSSLPLATFORM=kodi-iphoneos-arm64
+
ifeq ($(TARGET_PLATFORM),appletvos)
+ OPENSSLPLATFORM=kodi-appletvos-arm64
# Need to add "no-async" to avoid "'setcontext' is unavailable: not available on tvOS" error
- TARGETOPT=no-async
+ TARGETOPT+= no-async
endif
endif
ifeq ($(OS), osx)
OPENSSLPLATFORM=kodi-darwin64-$(CPU)
- ASMFLAG=no-asm
endif
- CONFIGURE=./Configure $(OPENSSLPLATFORM) no-shared $(ASMFLAG) zlib no-tests $(TARGETOPT) --prefix=$(PREFIX)
+ # Openssl 3.2.0 allows no-apps no-docs as options. Use when we update further
+ # We explicitly use no-asm as there is a symbol clash with gnutls
+ CONFIGURE=./Configure no-shared zlib no-tests no-asm no-module $(TARGETOPT) --prefix=$(PREFIX) $(OPENSSLPLATFORM)
endif
export CC CXX AR RANLIB
diff --git a/tools/depends/target/openssl/OPENSSL-VERSION b/tools/depends/target/openssl/OPENSSL-VERSION
index 1712a0c3da..424c6d4036 100644
--- a/tools/depends/target/openssl/OPENSSL-VERSION
+++ b/tools/depends/target/openssl/OPENSSL-VERSION
@@ -1,4 +1,4 @@
LIBNAME=openssl
-VERSION=1.1.1w
+VERSION=3.0.13
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
-SHA512=b4c625fe56a4e690b57b6a011a225ad0cb3af54bd8fb67af77b5eceac55cc7191291d96a660c5b568a08a2fbf62b4612818e7cca1bb95b2b6b4fc649b0552b6d
+SHA512=22f4096781f0b075f5bf81bd39a0f97e111760dfa73b6f858f6bb54968a7847944d74969ae10f9a51cc21a2f4af20d9a4c463649dc824f5e439e196d6764c4f9
diff --git a/tools/depends/target/pythonmodule-pil/PYTHONMODULE-PIL-VERSION b/tools/depends/target/pythonmodule-pil/PYTHONMODULE-PIL-VERSION
index 9940c862f7..8f7afcc92b 100644
--- a/tools/depends/target/pythonmodule-pil/PYTHONMODULE-PIL-VERSION
+++ b/tools/depends/target/pythonmodule-pil/PYTHONMODULE-PIL-VERSION
@@ -1,4 +1,4 @@
LIBNAME=Pillow
-VERSION=8.4.0
+VERSION=10.1.0
ARCHIVE=$(LIBNAME)-$(VERSION).tar.gz
-SHA512=d395f69ccb37c52a3b6f45836700ffbc3173afae31848cc61d7b47db88ca1594541023beb9a14fd9067aca664e182c7d6e3300ab3e3095c31afe8dcbc6e08233
+SHA512=01c97b68d4167d10539a2d29fb82676fb417ee5003f0acd9f602ed13d41b200579497cc0ef0949b2c1549b684f76f2d43895a52abdb1367345d2affd544c5b5a
diff --git a/tools/depends/target/tinyxml2/Makefile b/tools/depends/target/tinyxml2/Makefile
index 23b86ed643..a7a5222969 100644
--- a/tools/depends/target/tinyxml2/Makefile
+++ b/tools/depends/target/tinyxml2/Makefile
@@ -7,7 +7,7 @@ LIBDYLIB=$(PLATFORM)/build/$(BYPRODUCT)
all: .installed-$(PLATFORM)
-$(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE) $(DEPS)
+$(PLATFORM): $(DEPS) | $(TARBALLS_LOCATION)/$(ARCHIVE).$(HASH_TYPE)
rm -rf $(PLATFORM); mkdir -p $(PLATFORM)/build
cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
cd $(PLATFORM); sed -ie 's|\r$$||' CMakeLists.txt
diff --git a/xbmc/AutoSwitch.cpp b/xbmc/AutoSwitch.cpp
index 14adb8e2bc..0dd710f757 100644
--- a/xbmc/AutoSwitch.cpp
+++ b/xbmc/AutoSwitch.cpp
@@ -9,6 +9,7 @@
#include "AutoSwitch.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindowManager.h"
diff --git a/xbmc/Autorun.cpp b/xbmc/Autorun.cpp
index 6c672b208d..5f8d321a5f 100644
--- a/xbmc/Autorun.cpp
+++ b/xbmc/Autorun.cpp
@@ -9,6 +9,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "PlayListPlayer.h"
@@ -25,12 +26,14 @@
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
#include "messaging/helpers/DialogHelper.h"
+#include "music/MusicFileItemClassify.h"
#include "playlists/PlayList.h"
#include "profiles/ProfileManager.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
#include "settings/lib/SettingDefinitions.h"
+#include "video/VideoFileItemClassify.h"
#include <stdlib.h>
#ifndef TARGET_WINDOWS
@@ -50,7 +53,9 @@
using namespace XFILE;
using namespace MEDIA_DETECT;
+using namespace KODI;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
using namespace std::chrono_literals;
using KODI::MESSAGING::HELPERS::DialogResponse;
@@ -399,7 +404,7 @@ bool CAutorun::RunDisc(IDirectory* pDir, const std::string& strDrive, int& nAdde
for (int i = 0; i < tempItems.Size(); i++)
{
CFileItemPtr pItem = tempItems[i];
- if (!pItem->m_bIsFolder && pItem->IsVideo())
+ if (!pItem->m_bIsFolder && IsVideo(*pItem))
{
bPlaying = true;
if (pItem->IsStack())
@@ -436,7 +441,7 @@ bool CAutorun::RunDisc(IDirectory* pDir, const std::string& strDrive, int& nAdde
for (int i = 0; i < vecItems.Size(); i++)
{
CFileItemPtr pItem = vecItems[i];
- if (!pItem->m_bIsFolder && pItem->IsAudio())
+ if (!pItem->m_bIsFolder && MUSIC::IsAudio(*pItem))
{
nAddedToPlaylist++;
CServiceBroker::GetPlaylistPlayer().Add(PLAYLIST::TYPE_MUSIC, pItem);
diff --git a/xbmc/BackgroundInfoLoader.cpp b/xbmc/BackgroundInfoLoader.cpp
index 55d221ab04..de3d5a3a9e 100644
--- a/xbmc/BackgroundInfoLoader.cpp
+++ b/xbmc/BackgroundInfoLoader.cpp
@@ -9,6 +9,7 @@
#include "BackgroundInfoLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "threads/Thread.h"
#include "utils/log.h"
diff --git a/xbmc/CMakeLists.txt b/xbmc/CMakeLists.txt
index b7c838b3da..689f4af296 100644
--- a/xbmc/CMakeLists.txt
+++ b/xbmc/CMakeLists.txt
@@ -8,6 +8,7 @@ set(SOURCES AutoSwitch.cpp
DbUrl.cpp
DynamicDll.cpp
FileItem.cpp
+ FileItemList.cpp
FileItemListModification.cpp
GUIInfoManager.cpp
GUILargeTextureManager.cpp
@@ -45,6 +46,7 @@ set(HEADERS AutoSwitch.h
DllPaths_win32.h
DynamicDll.h
FileItem.h
+ FileItemList.h
FileItemListModification.h
GUIInfoManager.h
GUILargeTextureManager.h
diff --git a/xbmc/ContextMenus.cpp b/xbmc/ContextMenus.cpp
index 215545eda3..342c16e063 100644
--- a/xbmc/ContextMenus.cpp
+++ b/xbmc/ContextMenus.cpp
@@ -14,18 +14,21 @@
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
#include "input/WindowTranslator.h"
+#include "music/MusicFileItemClassify.h"
#include "storage/MediaManager.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "utils/Variant.h"
+using namespace KODI;
+
namespace CONTEXTMENU
{
bool CEjectDisk::IsVisible(const CFileItem& item) const
{
#ifdef HAS_OPTICAL_DRIVE
- return item.IsRemovable() && (item.IsDVD() || item.IsCDDA());
+ return item.IsRemovable() && (item.IsDVD() || MUSIC::IsCDDA(item));
#else
return false;
#endif
@@ -43,7 +46,7 @@ namespace CONTEXTMENU
bool CEjectDrive::IsVisible(const CFileItem& item) const
{
// Must be HDD
- return item.IsRemovable() && !item.IsDVD() && !item.IsCDDA();
+ return item.IsRemovable() && !item.IsDVD() && !MUSIC::IsCDDA(item);
}
bool CEjectDrive::Execute(const std::shared_ptr<CFileItem>& item) const
diff --git a/xbmc/CueDocument.cpp b/xbmc/CueDocument.cpp
index 674a94aa51..abc5185e63 100644
--- a/xbmc/CueDocument.cpp
+++ b/xbmc/CueDocument.cpp
@@ -43,6 +43,7 @@
#include "CueDocument.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp
index d2e2e34980..8b7012a0e6 100644
--- a/xbmc/FileItem.cpp
+++ b/xbmc/FileItem.cpp
@@ -9,6 +9,7 @@
#include "FileItem.h"
#include "CueDocument.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
@@ -17,7 +18,7 @@
#include "filesystem/Directory.h"
#include "filesystem/File.h"
#include "filesystem/MultiPathDirectory.h"
-#include "filesystem/MusicDatabaseDirectory.h"
+#include "filesystem/MusicDatabaseDirectory/QueryParams.h"
#include "filesystem/StackDirectory.h"
#include "filesystem/VideoDatabaseDirectory.h"
#include "filesystem/VideoDatabaseDirectory/QueryParams.h"
@@ -28,8 +29,10 @@
#include "music/Album.h"
#include "music/Artist.h"
#include "music/MusicDatabase.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "music/tags/MusicInfoTagLoaderFactory.h"
+#include "network/NetworkFileItemClassify.h"
#include "pictures/PictureInfoTag.h"
#include "playlists/PlayList.h"
#include "playlists/PlayListFactory.h"
@@ -48,10 +51,8 @@
#include "settings/SettingsComponent.h"
#include "settings/lib/Setting.h"
#include "utils/Archive.h"
-#include "utils/Crc32.h"
#include "utils/FileExtensionProvider.h"
#include "utils/Mime.h"
-#include "utils/Random.h"
#include "utils/RegExp.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
@@ -59,13 +60,12 @@
#include "utils/log.h"
#include "video/Bookmark.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoUtils.h"
-#include <algorithm>
#include <cstdlib>
#include <memory>
-#include <mutex>
using namespace KODI;
using namespace XFILE;
@@ -842,16 +842,11 @@ void CFileItem::ToSortable(SortItem &sortable, const Fields &fields) const
bool CFileItem::Exists(bool bUseCache /* = true */) const
{
- if (m_strPath.empty()
- || IsPath("add")
- || IsInternetStream()
- || IsParentFolder()
- || IsVirtualDirectoryRoot()
- || IsPlugin()
- || IsPVR())
+ if (m_strPath.empty() || IsPath("add") || NETWORK::IsInternetStream(*this) || IsParentFolder() ||
+ IsVirtualDirectoryRoot() || IsPlugin() || IsPVR())
return true;
- if (IsVideoDb() && HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(*this) && HasVideoInfoTag())
{
CFileItem dbItem(m_bIsFolder ? GetVideoInfoTag()->m_strPath : GetVideoInfoTag()->m_strFileNameAndPath, m_bIsFolder);
return dbItem.Exists();
@@ -873,51 +868,6 @@ bool CFileItem::Exists(bool bUseCache /* = true */) const
return false;
}
-bool CFileItem::IsVideo() const
-{
- /* check preset mime type */
- if(StringUtils::StartsWithNoCase(m_mimetype, "video/"))
- return true;
-
- if (HasVideoInfoTag())
- return true;
-
- if (HasGameInfoTag())
- return false;
-
- if (HasMusicInfoTag())
- return false;
-
- if (HasPictureInfoTag())
- return false;
-
- // TV recordings are videos...
- if (!m_bIsFolder && URIUtils::IsPVRTVRecordingFileOrFolder(GetPath()))
- return true;
-
- // ... all other PVR items are not.
- if (IsPVR())
- return false;
-
- if (URIUtils::IsDVD(m_strPath))
- return true;
-
- std::string extension;
- if(StringUtils::StartsWithNoCase(m_mimetype, "application/"))
- { /* check for some standard types */
- extension = m_mimetype.substr(12);
- if( StringUtils::EqualsNoCase(extension, "ogg")
- || StringUtils::EqualsNoCase(extension, "mp4")
- || StringUtils::EqualsNoCase(extension, "mxf") )
- return true;
- }
-
- //! @todo If the file is a zip file, ask the game clients if any support this
- // file before assuming it is video.
-
- return URIUtils::HasExtension(m_strPath, CServiceBroker::GetFileExtensionProvider().GetVideoExtensions());
-}
-
bool CFileItem::IsEPG() const
{
return HasEPGInfoTag();
@@ -958,53 +908,6 @@ bool CFileItem::IsPVRTimer() const
return HasPVRTimerInfoTag();
}
-bool CFileItem::IsDiscStub() const
-{
- if (IsVideoDb() && HasVideoInfoTag())
- {
- CFileItem dbItem(m_bIsFolder ? GetVideoInfoTag()->m_strPath : GetVideoInfoTag()->m_strFileNameAndPath, m_bIsFolder);
- return dbItem.IsDiscStub();
- }
-
- return URIUtils::HasExtension(m_strPath, CServiceBroker::GetFileExtensionProvider().GetDiscStubExtensions());
-}
-
-bool CFileItem::IsAudio() const
-{
- /* check preset mime type */
- if(StringUtils::StartsWithNoCase(m_mimetype, "audio/"))
- return true;
-
- if (HasMusicInfoTag())
- return true;
-
- if (HasVideoInfoTag())
- return false;
-
- if (HasPictureInfoTag())
- return false;
-
- if (HasGameInfoTag())
- return false;
-
- if (IsCDDA())
- return true;
-
- if(StringUtils::StartsWithNoCase(m_mimetype, "application/"))
- { /* check for some standard types */
- std::string extension = m_mimetype.substr(12);
- if( StringUtils::EqualsNoCase(extension, "ogg")
- || StringUtils::EqualsNoCase(extension, "mp4")
- || StringUtils::EqualsNoCase(extension, "mxf") )
- return true;
- }
-
- //! @todo If the file is a zip file, ask the game clients if any support this
- // file before assuming it is audio
-
- return URIUtils::HasExtension(m_strPath, CServiceBroker::GetFileExtensionProvider().GetMusicExtensions());
-}
-
bool CFileItem::IsDeleted() const
{
if (HasPVRRecordingInfoTag())
@@ -1013,11 +916,6 @@ bool CFileItem::IsDeleted() const
return false;
}
-bool CFileItem::IsAudioBook() const
-{
- return IsType(".m4b") || IsType(".mka");
-}
-
bool CFileItem::IsGame() const
{
if (HasGameInfoTag())
@@ -1068,46 +966,12 @@ bool CFileItem::IsPicture() const
return false;
}
-bool CFileItem::IsLyrics() const
-{
- return URIUtils::HasExtension(m_strPath, ".cdg|.lrc");
-}
-
-bool CFileItem::IsSubtitle() const
-{
- return URIUtils::HasExtension(m_strPath, CServiceBroker::GetFileExtensionProvider().GetSubtitleExtensions());
-}
-
-bool CFileItem::IsCUESheet() const
-{
- return URIUtils::HasExtension(m_strPath, ".cue");
-}
-
-bool CFileItem::IsInternetStream(const bool bStrictCheck /* = false */) const
-{
- if (HasProperty("IsHTTPDirectory"))
- return bStrictCheck;
-
- if (!m_strDynPath.empty())
- return URIUtils::IsInternetStream(m_strDynPath, bStrictCheck);
-
- return URIUtils::IsInternetStream(m_strPath, bStrictCheck);
-}
-
-bool CFileItem::IsStreamedFilesystem() const
-{
- if (!m_strDynPath.empty())
- return URIUtils::IsStreamedFilesystem(m_strDynPath);
-
- return URIUtils::IsStreamedFilesystem(m_strPath);
-}
-
bool CFileItem::IsFileFolder(EFileFolderType types) const
{
EFileFolderType always_type = EFILEFOLDER_TYPE_ALWAYS;
/* internet streams are not directly expanded */
- if(IsInternetStream())
+ if (NETWORK::IsInternetStream(*this))
always_type = EFILEFOLDER_TYPE_ONCLICK;
// strm files are not browsable
@@ -1116,16 +980,13 @@ bool CFileItem::IsFileFolder(EFileFolderType types) const
if(types & always_type)
{
- if(IsSmartPlayList()
- || (IsPlayList() && CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_playlistAsFolders)
- || IsAPK()
- || IsZIP()
- || IsRAR()
- || IsRSS()
- || IsAudioBook()
- || IsType(".ogg|.oga|.xbt")
+ if (IsSmartPlayList() ||
+ (IsPlayList() &&
+ CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_playlistAsFolders) ||
+ IsAPK() || IsZIP() || IsRAR() || IsRSS() || MUSIC::IsAudioBook(*this) ||
+ IsType(".ogg|.oga|.xbt")
#if defined(TARGET_ANDROID)
- || IsType(".apk")
+ || IsType(".apk")
#endif
)
return true;
@@ -1185,12 +1046,6 @@ bool CFileItem::IsNFO() const
return URIUtils::HasExtension(m_strPath, ".nfo");
}
-bool CFileItem::IsVideoExtras() const
-{
- return m_bIsFolder &&
- StringUtils::EqualsNoCase(URIUtils::GetFileOrFolderName(m_strPath), "extras");
-}
-
bool CFileItem::IsDiscImage() const
{
return URIUtils::IsDiscImage(GetDynPath());
@@ -1198,38 +1053,10 @@ bool CFileItem::IsDiscImage() const
bool CFileItem::IsOpticalMediaFile() const
{
- if (IsDVDFile(false, true))
+ if (VIDEO::IsDVDFile(*this, false, true))
return true;
- return IsBDFile();
-}
-
-bool CFileItem::IsDVDFile(bool bVobs /*= true*/, bool bIfos /*= true*/) const
-{
- std::string strFileName = URIUtils::GetFileName(GetDynPath());
- if (bIfos)
- {
- if (StringUtils::EqualsNoCase(strFileName, "video_ts.ifo"))
- return true;
- if (StringUtils::StartsWithNoCase(strFileName, "vts_") && StringUtils::EndsWithNoCase(strFileName, "_0.ifo") && strFileName.length() == 12)
- return true;
- }
- if (bVobs)
- {
- if (StringUtils::EqualsNoCase(strFileName, "video_ts.vob"))
- return true;
- if (StringUtils::StartsWithNoCase(strFileName, "vts_") && StringUtils::EndsWithNoCase(strFileName, ".vob"))
- return true;
- }
-
- return false;
-}
-
-bool CFileItem::IsBDFile() const
-{
- std::string strFileName = URIUtils::GetFileName(GetDynPath());
- return (StringUtils::EqualsNoCase(strFileName, "index.bdmv") || StringUtils::EqualsNoCase(strFileName, "MovieObject.bdmv")
- || StringUtils::EqualsNoCase(strFileName, "INDEX.BDM") || StringUtils::EqualsNoCase(strFileName, "MOVIEOBJ.BDM"));
+ return VIDEO::IsBDFile(*this);
}
bool CFileItem::IsRAR() const
@@ -1309,24 +1136,9 @@ bool CFileItem::IsBluray() const
if (URIUtils::IsBluray(m_strPath))
return true;
- CFileItem item = CFileItem(VIDEO_UTILS::GetOpticalMediaPath(*this), false);
+ CFileItem item = CFileItem(VIDEO::UTILS::GetOpticalMediaPath(*this), false);
- return item.IsBDFile();
-}
-
-bool CFileItem::IsProtectedBlurayDisc() const
-{
- std::string path;
- path = URIUtils::AddFileToFolder(GetPath(), "AACS", "Unit_Key_RO.inf");
- if (CFile::Exists(path))
- return true;
-
- return false;
-}
-
-bool CFileItem::IsCDDA() const
-{
- return URIUtils::IsCDDA(m_strPath);
+ return VIDEO::IsBDFile(item);
}
bool CFileItem::IsDVD() const
@@ -1344,21 +1156,11 @@ bool CFileItem::IsNfs() const
return URIUtils::IsNfs(m_strPath);
}
-bool CFileItem::IsOnLAN() const
-{
- return URIUtils::IsOnLAN(m_strPath);
-}
-
bool CFileItem::IsISO9660() const
{
return URIUtils::IsISO9660(m_strPath);
}
-bool CFileItem::IsRemote() const
-{
- return URIUtils::IsRemote(m_strPath);
-}
-
bool CFileItem::IsSmb() const
{
return URIUtils::IsSmb(m_strPath);
@@ -1384,16 +1186,6 @@ bool CFileItem::IsHD() const
return URIUtils::IsHD(m_strPath);
}
-bool CFileItem::IsMusicDb() const
-{
- return URIUtils::IsMusicDb(m_strPath);
-}
-
-bool CFileItem::IsVideoDb() const
-{
- return URIUtils::IsVideoDb(m_strPath);
-}
-
bool CFileItem::IsVirtualDirectoryRoot() const
{
return (m_bIsFolder && m_strPath.empty());
@@ -1401,7 +1193,7 @@ bool CFileItem::IsVirtualDirectoryRoot() const
bool CFileItem::IsRemovable() const
{
- return IsOnDVD() || IsCDDA() || m_iDriveType == CMediaSource::SOURCE_TYPE_REMOVABLE;
+ return IsOnDVD() || MUSIC::IsCDDA(*this) || m_iDriveType == CMediaSource::SOURCE_TYPE_REMOVABLE;
}
bool CFileItem::IsReadOnly() const
@@ -1472,12 +1264,12 @@ void CFileItem::FillInDefaultIcon()
// PVR deleted recording
SetArt("icon", "DefaultVideoDeleted.png");
}
- else if ( IsAudio() )
+ else if (MUSIC::IsAudio(*this))
{
// audio
SetArt("icon", "DefaultAudio.png");
}
- else if ( IsVideo() )
+ else if (VIDEO::IsVideo(*this))
{
// video
SetArt("icon", "DefaultVideo.png");
@@ -1654,7 +1446,7 @@ void CFileItem::UpdateMimeType(bool lookup /*= true*/)
void CFileItem::SetMimeTypeForInternetFile()
{
- if (m_doContentLookup && IsInternetStream())
+ if (m_doContentLookup && NETWORK::IsInternetStream(*this))
{
SetMimeType("");
FillInMimeType(true);
@@ -1670,6 +1462,9 @@ bool CFileItem::IsSamePath(const CFileItem *item) const
{
if (item->HasProperty("item_start") || HasProperty("item_start"))
return (item->GetProperty("item_start") == GetProperty("item_start"));
+ // See if we have associated a bluray playlist
+ if (VIDEO::IsBlurayPlaylist(*this) || VIDEO::IsBlurayPlaylist(*item))
+ return (GetDynPath() == item->GetDynPath());
return true;
}
if (HasMusicInfoTag() && item->HasMusicInfoTag())
@@ -1694,28 +1489,28 @@ bool CFileItem::IsSamePath(const CFileItem *item) const
}
}
}
- if (IsMusicDb() && HasMusicInfoTag())
+ if (MUSIC::IsMusicDb(*this) && HasMusicInfoTag())
{
CFileItem dbItem(m_musicInfoTag->GetURL(), false);
if (HasProperty("item_start"))
dbItem.SetProperty("item_start", GetProperty("item_start"));
return dbItem.IsSamePath(item);
}
- if (IsVideoDb() && HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(*this) && HasVideoInfoTag())
{
CFileItem dbItem(GetVideoInfoTag()->m_strFileNameAndPath, false);
if (HasProperty("item_start"))
dbItem.SetProperty("item_start", GetProperty("item_start"));
return dbItem.IsSamePath(item);
}
- if (item->IsMusicDb() && item->HasMusicInfoTag())
+ if (MUSIC::IsMusicDb(*item) && item->HasMusicInfoTag())
{
CFileItem dbItem(item->m_musicInfoTag->GetURL(), false);
if (item->HasProperty("item_start"))
dbItem.SetProperty("item_start", item->GetProperty("item_start"));
return IsSamePath(&dbItem);
}
- if (item->IsVideoDb() && item->HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(*item) && item->HasVideoInfoTag())
{
CFileItem dbItem(item->GetVideoInfoTag()->m_strFileNameAndPath, false);
if (item->HasProperty("item_start"))
@@ -1866,7 +1661,7 @@ void CFileItem::MergeInfo(const CFileItem& item)
SetLabel2(item.GetLabel2());
if (!item.GetArt().empty())
{
- if (item.IsVideo())
+ if (VIDEO::IsVideo(item))
AppendArt(item.GetArt());
else
SetArt(item.GetArt());
@@ -2069,6 +1864,22 @@ void CFileItem::SetDynPath(const std::string &path)
m_strDynPath = path;
}
+std::string CFileItem::GetBlurayPath() const
+{
+ if (VIDEO::IsBlurayPlaylist(*this))
+ {
+ CURL url(GetDynPath());
+ CURL url2(url.GetHostName()); // strip bluray://
+ if (url2.IsProtocol("udf"))
+ // ISO
+ return url2.GetHostName(); // strip udf://
+ else if (url.IsProtocol("bluray"))
+ // BDMV
+ return url2.Get() + "BDMV/index.bdmv";
+ }
+ return GetDynPath();
+}
+
void CFileItem::SetCueDocument(const CCueDocumentPtr& cuePtr)
{
m_cueDocument = cuePtr;
@@ -2165,1097 +1976,15 @@ bool CFileItem::LoadTracksFromCueDocument(CFileItemList& scannedItems)
return tracksFound != 0;
}
-/////////////////////////////////////////////////////////////////////////////////
-/////
-///// CFileItemList
-/////
-//////////////////////////////////////////////////////////////////////////////////
-
-CFileItemList::CFileItemList()
-: CFileItem("", true)
-{
-}
-
-CFileItemList::CFileItemList(const std::string& strPath)
-: CFileItem(strPath, true)
-{
-}
-
-CFileItemList::~CFileItemList()
-{
- Clear();
-}
-
-CFileItemPtr CFileItemList::operator[] (int iItem)
-{
- return Get(iItem);
-}
-
-const CFileItemPtr CFileItemList::operator[] (int iItem) const
-{
- return Get(iItem);
-}
-
-CFileItemPtr CFileItemList::operator[] (const std::string& strPath)
-{
- return Get(strPath);
-}
-
-const CFileItemPtr CFileItemList::operator[] (const std::string& strPath) const
-{
- return Get(strPath);
-}
-
-void CFileItemList::SetIgnoreURLOptions(bool ignoreURLOptions)
-{
- m_ignoreURLOptions = ignoreURLOptions;
-
- if (m_fastLookup)
- {
- m_fastLookup = false; // Force SetFastlookup to clear map
- SetFastLookup(true); // and regenerate map
- }
-}
-
-void CFileItemList::SetFastLookup(bool fastLookup)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (fastLookup && !m_fastLookup)
- { // generate the map
- m_map.clear();
- for (unsigned int i=0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
- }
- }
- if (!fastLookup && m_fastLookup)
- m_map.clear();
- m_fastLookup = fastLookup;
-}
-
-bool CFileItemList::Contains(const std::string& fileName) const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (m_fastLookup)
- return m_map.find(m_ignoreURLOptions ? CURL(fileName).GetWithoutOptions() : fileName) != m_map.end();
-
- // slow method...
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- const CFileItemPtr pItem = m_items[i];
- if (pItem->IsPath(m_ignoreURLOptions ? CURL(fileName).GetWithoutOptions() : fileName))
- return true;
- }
- return false;
-}
-
-void CFileItemList::Clear()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- ClearItems();
- m_sortDescription.sortBy = SortByNone;
- m_sortDescription.sortOrder = SortOrderNone;
- m_sortDescription.sortAttributes = SortAttributeNone;
- m_sortIgnoreFolders = false;
- m_cacheToDisc = CACHE_IF_SLOW;
- m_sortDetails.clear();
- m_replaceListing = false;
- m_content.clear();
-}
-
-void CFileItemList::ClearItems()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- // make sure we free the memory of the items (these are GUIControls which may have allocated resources)
- FreeMemory();
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr item = m_items[i];
- item->FreeMemory();
- }
- m_items.clear();
- m_map.clear();
-}
-
-void CFileItemList::Add(CFileItemPtr pItem)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- if (m_fastLookup)
- m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
- m_items.emplace_back(std::move(pItem));
-}
-
-void CFileItemList::Add(CFileItem&& item)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- auto ptr = std::make_shared<CFileItem>(std::move(item));
- if (m_fastLookup)
- m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(ptr->GetPath()).GetWithoutOptions() : ptr->GetPath(), ptr));
- m_items.emplace_back(std::move(ptr));
-}
-
-void CFileItemList::AddFront(const CFileItemPtr &pItem, int itemPosition)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (itemPosition >= 0)
- {
- m_items.insert(m_items.begin()+itemPosition, pItem);
- }
- else
- {
- m_items.insert(m_items.begin()+(m_items.size()+itemPosition), pItem);
- }
- if (m_fastLookup)
- {
- m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
- }
-}
-
-void CFileItemList::Remove(CFileItem* pItem)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- for (IVECFILEITEMS it = m_items.begin(); it != m_items.end(); ++it)
- {
- if (pItem == it->get())
- {
- m_items.erase(it);
- if (m_fastLookup)
- {
- m_map.erase(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath());
- }
- break;
- }
- }
-}
-
-VECFILEITEMS::iterator CFileItemList::erase(VECFILEITEMS::iterator first,
- VECFILEITEMS::iterator last)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- return m_items.erase(first, last);
-}
-
-void CFileItemList::Remove(int iItem)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (iItem >= 0 && iItem < Size())
- {
- CFileItemPtr pItem = *(m_items.begin() + iItem);
- if (m_fastLookup)
- {
- m_map.erase(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath());
- }
- m_items.erase(m_items.begin() + iItem);
- }
-}
-
-void CFileItemList::Append(const CFileItemList& itemlist)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- for (int i = 0; i < itemlist.Size(); ++i)
- Add(itemlist[i]);
-}
-
-void CFileItemList::Assign(const CFileItemList& itemlist, bool append)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- if (!append)
- Clear();
- Append(itemlist);
- SetPath(itemlist.GetPath());
- SetLabel(itemlist.GetLabel());
- m_sortDetails = itemlist.m_sortDetails;
- m_sortDescription = itemlist.m_sortDescription;
- m_replaceListing = itemlist.m_replaceListing;
- m_content = itemlist.m_content;
- m_mapProperties = itemlist.m_mapProperties;
- m_cacheToDisc = itemlist.m_cacheToDisc;
-}
-
-bool CFileItemList::Copy(const CFileItemList& items, bool copyItems /* = true */)
-{
- // assign all CFileItem parts
- *static_cast<CFileItem*>(this) = static_cast<const CFileItem&>(items);
-
- // assign the rest of the CFileItemList properties
- m_replaceListing = items.m_replaceListing;
- m_content = items.m_content;
- m_mapProperties = items.m_mapProperties;
- m_cacheToDisc = items.m_cacheToDisc;
- m_sortDetails = items.m_sortDetails;
- m_sortDescription = items.m_sortDescription;
- m_sortIgnoreFolders = items.m_sortIgnoreFolders;
-
- if (copyItems)
- {
- // make a copy of each item
- for (int i = 0; i < items.Size(); i++)
- {
- CFileItemPtr newItem(new CFileItem(*items[i]));
- Add(newItem);
- }
- }
-
- return true;
-}
-
-CFileItemPtr CFileItemList::Get(int iItem) const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (iItem > -1 && iItem < (int)m_items.size())
- return m_items[iItem];
-
- return CFileItemPtr();
-}
-
-CFileItemPtr CFileItemList::Get(const std::string& strPath) const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- if (m_fastLookup)
- {
- MAPFILEITEMS::const_iterator it =
- m_map.find(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath);
- if (it != m_map.end())
- return it->second;
-
- return CFileItemPtr();
- }
- // slow method...
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->IsPath(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath))
- return pItem;
- }
-
- return CFileItemPtr();
-}
-
-int CFileItemList::Size() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- return (int)m_items.size();
-}
-
-bool CFileItemList::IsEmpty() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- return m_items.empty();
-}
-
-void CFileItemList::Reserve(size_t iCount)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- m_items.reserve(iCount);
-}
-
-void CFileItemList::Sort(FILEITEMLISTCOMPARISONFUNC func)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- std::stable_sort(m_items.begin(), m_items.end(), func);
-}
-
-void CFileItemList::FillSortFields(FILEITEMFILLFUNC func)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- std::for_each(m_items.begin(), m_items.end(), func);
-}
-
-void CFileItemList::Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute sortAttributes /* = SortAttributeNone */)
-{
- if (sortBy == SortByNone ||
- (m_sortDescription.sortBy == sortBy && m_sortDescription.sortOrder == sortOrder &&
- m_sortDescription.sortAttributes == sortAttributes))
- return;
-
- SortDescription sorting;
- sorting.sortBy = sortBy;
- sorting.sortOrder = sortOrder;
- sorting.sortAttributes = sortAttributes;
-
- Sort(sorting);
- m_sortDescription = sorting;
-}
-
-void CFileItemList::Sort(SortDescription sortDescription)
-{
- if (sortDescription.sortBy == SortByFile || sortDescription.sortBy == SortBySortTitle ||
- sortDescription.sortBy == SortByOriginalTitle || sortDescription.sortBy == SortByDateAdded ||
- sortDescription.sortBy == SortByRating || sortDescription.sortBy == SortByYear ||
- sortDescription.sortBy == SortByPlaylistOrder || sortDescription.sortBy == SortByLastPlayed ||
- sortDescription.sortBy == SortByPlaycount)
- sortDescription.sortAttributes = (SortAttribute)((int)sortDescription.sortAttributes | SortAttributeIgnoreFolders);
-
- if (sortDescription.sortBy == SortByNone ||
- (m_sortDescription.sortBy == sortDescription.sortBy && m_sortDescription.sortOrder == sortDescription.sortOrder &&
- m_sortDescription.sortAttributes == sortDescription.sortAttributes))
- return;
-
- if (m_sortIgnoreFolders)
- sortDescription.sortAttributes = (SortAttribute)((int)sortDescription.sortAttributes | SortAttributeIgnoreFolders);
-
- const Fields fields = SortUtils::GetFieldsForSorting(sortDescription.sortBy);
- SortItems sortItems((size_t)Size());
- for (int index = 0; index < Size(); index++)
- {
- sortItems[index] = std::make_shared<SortItem>();
- m_items[index]->ToSortable(*sortItems[index], fields);
- (*sortItems[index])[FieldId] = index;
- }
-
- // do the sorting
- SortUtils::Sort(sortDescription, sortItems);
-
- // apply the new order to the existing CFileItems
- VECFILEITEMS sortedFileItems;
- sortedFileItems.reserve(Size());
- for (SortItems::const_iterator it = sortItems.begin(); it != sortItems.end(); ++it)
- {
- CFileItemPtr item = m_items[(int)(*it)->at(FieldId).asInteger()];
- // Set the sort label in the CFileItem
- item->SetSortLabel((*it)->at(FieldSort).asWideString());
-
- sortedFileItems.push_back(item);
- }
-
- // replace the current list with the re-ordered one
- m_items = std::move(sortedFileItems);
-}
-
-void CFileItemList::Randomize()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- KODI::UTILS::RandomShuffle(m_items.begin(), m_items.end());
-}
-
-void CFileItemList::Archive(CArchive& ar)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- if (ar.IsStoring())
- {
- CFileItem::Archive(ar);
-
- int i = 0;
- if (!m_items.empty() && m_items[0]->IsParentFolder())
- i = 1;
-
- ar << (int)(m_items.size() - i);
-
- ar << m_ignoreURLOptions;
-
- ar << m_fastLookup;
-
- ar << (int)m_sortDescription.sortBy;
- ar << (int)m_sortDescription.sortOrder;
- ar << (int)m_sortDescription.sortAttributes;
- ar << m_sortIgnoreFolders;
- ar << (int)m_cacheToDisc;
-
- ar << (int)m_sortDetails.size();
- for (unsigned int j = 0; j < m_sortDetails.size(); ++j)
- {
- const GUIViewSortDetails &details = m_sortDetails[j];
- ar << (int)details.m_sortDescription.sortBy;
- ar << (int)details.m_sortDescription.sortOrder;
- ar << (int)details.m_sortDescription.sortAttributes;
- ar << details.m_buttonLabel;
- ar << details.m_labelMasks.m_strLabelFile;
- ar << details.m_labelMasks.m_strLabelFolder;
- ar << details.m_labelMasks.m_strLabel2File;
- ar << details.m_labelMasks.m_strLabel2Folder;
- }
-
- ar << m_content;
-
- for (; i < (int)m_items.size(); ++i)
- {
- CFileItemPtr pItem = m_items[i];
- ar << *pItem;
- }
- }
- else
- {
- CFileItemPtr pParent;
- if (!IsEmpty())
- {
- CFileItemPtr pItem=m_items[0];
- if (pItem->IsParentFolder())
- pParent = std::make_shared<CFileItem>(*pItem);
- }
-
- SetIgnoreURLOptions(false);
- SetFastLookup(false);
- Clear();
-
- CFileItem::Archive(ar);
-
- int iSize = 0;
- ar >> iSize;
- if (iSize <= 0)
- return ;
-
- if (pParent)
- {
- m_items.reserve(iSize + 1);
- m_items.push_back(pParent);
- }
- else
- m_items.reserve(iSize);
-
- bool ignoreURLOptions = false;
- ar >> ignoreURLOptions;
-
- bool fastLookup = false;
- ar >> fastLookup;
-
- int tempint;
- ar >> tempint;
- m_sortDescription.sortBy = (SortBy)tempint;
- ar >> tempint;
- m_sortDescription.sortOrder = (SortOrder)tempint;
- ar >> tempint;
- m_sortDescription.sortAttributes = (SortAttribute)tempint;
- ar >> m_sortIgnoreFolders;
- ar >> tempint;
- m_cacheToDisc = CACHE_TYPE(tempint);
-
- unsigned int detailSize = 0;
- ar >> detailSize;
- for (unsigned int j = 0; j < detailSize; ++j)
- {
- GUIViewSortDetails details;
- ar >> tempint;
- details.m_sortDescription.sortBy = (SortBy)tempint;
- ar >> tempint;
- details.m_sortDescription.sortOrder = (SortOrder)tempint;
- ar >> tempint;
- details.m_sortDescription.sortAttributes = (SortAttribute)tempint;
- ar >> details.m_buttonLabel;
- ar >> details.m_labelMasks.m_strLabelFile;
- ar >> details.m_labelMasks.m_strLabelFolder;
- ar >> details.m_labelMasks.m_strLabel2File;
- ar >> details.m_labelMasks.m_strLabel2Folder;
- m_sortDetails.push_back(details);
- }
-
- ar >> m_content;
-
- for (int i = 0; i < iSize; ++i)
- {
- CFileItemPtr pItem(new CFileItem);
- ar >> *pItem;
- Add(pItem);
- }
-
- SetIgnoreURLOptions(ignoreURLOptions);
- SetFastLookup(fastLookup);
- }
-}
-
-void CFileItemList::FillInDefaultIcons()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- for (int i = 0; i < (int)m_items.size(); ++i)
- {
- CFileItemPtr pItem = m_items[i];
- pItem->FillInDefaultIcon();
- }
-}
-
-int CFileItemList::GetFolderCount() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- int nFolderCount = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->m_bIsFolder)
- nFolderCount++;
- }
-
- return nFolderCount;
-}
-
-int CFileItemList::GetObjectCount() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- int numObjects = (int)m_items.size();
- if (numObjects && m_items[0]->IsParentFolder())
- numObjects--;
-
- return numObjects;
-}
-
-int CFileItemList::GetFileCount() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- int nFileCount = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (!pItem->m_bIsFolder)
- nFileCount++;
- }
-
- return nFileCount;
-}
-
-int CFileItemList::GetSelectedCount() const
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- int count = 0;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->IsSelected())
- count++;
- }
-
- return count;
-}
-
-void CFileItemList::FilterCueItems()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- // Handle .CUE sheet files...
- std::vector<std::string> itemstodelete;
- for (int i = 0; i < (int)m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (!pItem->m_bIsFolder)
- { // see if it's a .CUE sheet
- if (pItem->IsCUESheet())
- {
- CCueDocumentPtr cuesheet(new CCueDocument);
- if (cuesheet->ParseFile(pItem->GetPath()))
- {
- std::vector<std::string> MediaFileVec;
- cuesheet->GetMediaFiles(MediaFileVec);
-
- // queue the cue sheet and the underlying media file for deletion
- for (std::vector<std::string>::iterator itMedia = MediaFileVec.begin();
- itMedia != MediaFileVec.end(); ++itMedia)
- {
- std::string strMediaFile = *itMedia;
- std::string fileFromCue = strMediaFile; // save the file from the cue we're matching against,
- // as we're going to search for others here...
- bool bFoundMediaFile = CFile::Exists(strMediaFile);
- if (!bFoundMediaFile)
- {
- // try file in same dir, not matching case...
- if (Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- }
- else
- {
- // try removing the .cue extension...
- strMediaFile = pItem->GetPath();
- URIUtils::RemoveExtension(strMediaFile);
- CFileItem item(strMediaFile, false);
- if (item.IsAudio() && Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- }
- else
- { // try replacing the extension with one of our allowed ones.
- std::vector<std::string> extensions = StringUtils::Split(CServiceBroker::GetFileExtensionProvider().GetMusicExtensions(), "|");
- for (std::vector<std::string>::const_iterator i = extensions.begin(); i != extensions.end(); ++i)
- {
- strMediaFile = URIUtils::ReplaceExtension(pItem->GetPath(), *i);
- CFileItem item(strMediaFile, false);
- if (!item.IsCUESheet() && !item.IsPlayList() && Contains(strMediaFile))
- {
- bFoundMediaFile = true;
- break;
- }
- }
- }
- }
- }
- if (bFoundMediaFile)
- {
- cuesheet->UpdateMediaFile(fileFromCue, strMediaFile);
- // apply CUE for later processing
- for (int j = 0; j < (int)m_items.size(); j++)
- {
- CFileItemPtr pItem = m_items[j];
- if (StringUtils::CompareNoCase(pItem->GetPath(), strMediaFile) == 0)
- pItem->SetCueDocument(cuesheet);
- }
- }
- }
- }
- itemstodelete.push_back(pItem->GetPath());
- }
- }
- }
- // now delete the .CUE files.
- for (int i = 0; i < (int)itemstodelete.size(); i++)
- {
- for (int j = 0; j < (int)m_items.size(); j++)
- {
- CFileItemPtr pItem = m_items[j];
- if (StringUtils::CompareNoCase(pItem->GetPath(), itemstodelete[i]) == 0)
- { // delete this item
- m_items.erase(m_items.begin() + j);
- break;
- }
- }
- }
-}
-
-// Remove the extensions from the filenames
-void CFileItemList::RemoveExtensions()
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
- for (int i = 0; i < Size(); ++i)
- m_items[i]->RemoveExtension();
-}
-
-void CFileItemList::Stack(bool stackFiles /* = true */)
-{
- std::unique_lock<CCriticalSection> lock(m_lock);
-
- // not allowed here
- if (IsVirtualDirectoryRoot() ||
- IsLiveTV() ||
- IsSourcesPath() ||
- IsLibraryFolder())
- return;
-
- SetProperty("isstacked", true);
-
- // items needs to be sorted for stuff below to work properly
- Sort(SortByLabel, SortOrderAscending);
-
- StackFolders();
-
- if (stackFiles)
- StackFiles();
-}
-
-void CFileItemList::StackFolders()
-{
- // Precompile our REs
- VECCREGEXP folderRegExps;
- CRegExp folderRegExp(true, CRegExp::autoUtf8);
- const std::vector<std::string>& strFolderRegExps = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_folderStackRegExps;
-
- std::vector<std::string>::const_iterator strExpression = strFolderRegExps.begin();
- while (strExpression != strFolderRegExps.end())
- {
- if (!folderRegExp.RegComp(*strExpression))
- CLog::Log(LOGERROR, "{}: Invalid folder stack RegExp:'{}'", __FUNCTION__,
- strExpression->c_str());
- else
- folderRegExps.push_back(folderRegExp);
-
- ++strExpression;
- }
-
- if (!folderRegExp.IsCompiled())
- {
- CLog::Log(LOGDEBUG, "{}: No stack expressions available. Skipping folder stacking",
- __FUNCTION__);
- return;
- }
-
- // stack folders
- for (int i = 0; i < Size(); i++)
- {
- CFileItemPtr item = Get(i);
- // combined the folder checks
- if (item->m_bIsFolder)
- {
- // only check known fast sources?
- // NOTES:
- // 1. rars and zips may be on slow sources? is this supposed to be allowed?
- if( !item->IsRemote()
- || item->IsSmb()
- || item->IsNfs()
- || URIUtils::IsInRAR(item->GetPath())
- || URIUtils::IsInZIP(item->GetPath())
- || URIUtils::IsOnLAN(item->GetPath())
- )
- {
- // stack cd# folders if contains only a single video file
-
- bool bMatch(false);
-
- VECCREGEXP::iterator expr = folderRegExps.begin();
- while (!bMatch && expr != folderRegExps.end())
- {
- //CLog::Log(LOGDEBUG,"{}: Running expression {} on {}", __FUNCTION__, expr->GetPattern(), item->GetLabel());
- bMatch = (expr->RegFind(item->GetLabel().c_str()) != -1);
- if (bMatch)
- {
- CFileItemList items;
- CDirectory::GetDirectory(item->GetPath(), items,
- CServiceBroker::GetFileExtensionProvider().GetVideoExtensions(),
- DIR_FLAG_DEFAULTS);
- // optimized to only traverse listing once by checking for filecount
- // and recording last file item for later use
- int nFiles = 0;
- int index = -1;
- for (int j = 0; j < items.Size(); j++)
- {
- if (!items[j]->m_bIsFolder)
- {
- nFiles++;
- index = j;
- }
-
- if (nFiles > 1)
- break;
- }
-
- if (nFiles == 1)
- *item = *items[index];
- }
- ++expr;
- }
-
- // check for dvd folders
- if (!bMatch)
- {
- std::string dvdPath = VIDEO_UTILS::GetOpticalMediaPath(*item);
-
- if (!dvdPath.empty())
- {
- // NOTE: should this be done for the CD# folders too?
- item->m_bIsFolder = false;
- item->SetPath(dvdPath);
- item->SetLabel2("");
- item->SetLabelPreformatted(true);
- m_sortDescription.sortBy = SortByNone; /* sorting is now broken */
- }
- }
- }
- }
- }
-}
-
-void CFileItemList::StackFiles()
-{
- // Precompile our REs
- VECCREGEXP stackRegExps;
- CRegExp tmpRegExp(true, CRegExp::autoUtf8);
- const std::vector<std::string>& strStackRegExps = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoStackRegExps;
- std::vector<std::string>::const_iterator strRegExp = strStackRegExps.begin();
- while (strRegExp != strStackRegExps.end())
- {
- if (tmpRegExp.RegComp(*strRegExp))
- {
- if (tmpRegExp.GetCaptureTotal() == 4)
- stackRegExps.push_back(tmpRegExp);
- else
- CLog::Log(LOGERROR, "Invalid video stack RE ({}). Must have 4 captures.", *strRegExp);
- }
- ++strRegExp;
- }
-
- // now stack the files, some of which may be from the previous stack iteration
- int i = 0;
- while (i < Size())
- {
- CFileItemPtr item1 = Get(i);
-
- // skip folders, nfo files, playlists
- if (item1->m_bIsFolder
- || item1->IsParentFolder()
- || item1->IsNFO()
- || item1->IsPlayList()
- )
- {
- // increment index
- i++;
- continue;
- }
-
- int64_t size = 0;
- size_t offset = 0;
- std::string stackName;
- std::string file1;
- std::string filePath;
- std::vector<int> stack;
- VECCREGEXP::iterator expr = stackRegExps.begin();
-
- URIUtils::Split(item1->GetPath(), filePath, file1);
- if (URIUtils::HasEncodedFilename(CURL(filePath)))
- file1 = CURL::Decode(file1);
-
- int j;
- while (expr != stackRegExps.end())
- {
- if (expr->RegFind(file1, offset) != -1)
- {
- std::string Title1 = expr->GetMatch(1),
- Volume1 = expr->GetMatch(2),
- Ignore1 = expr->GetMatch(3),
- Extension1 = expr->GetMatch(4);
- if (offset)
- Title1 = file1.substr(0, expr->GetSubStart(2));
- j = i + 1;
- while (j < Size())
- {
- CFileItemPtr item2 = Get(j);
-
- // skip folders, nfo files, playlists
- if (item2->m_bIsFolder
- || item2->IsParentFolder()
- || item2->IsNFO()
- || item2->IsPlayList()
- )
- {
- // increment index
- j++;
- continue;
- }
-
- std::string file2, filePath2;
- URIUtils::Split(item2->GetPath(), filePath2, file2);
- if (URIUtils::HasEncodedFilename(CURL(filePath2)) )
- file2 = CURL::Decode(file2);
-
- if (expr->RegFind(file2, offset) != -1)
- {
- std::string Title2 = expr->GetMatch(1),
- Volume2 = expr->GetMatch(2),
- Ignore2 = expr->GetMatch(3),
- Extension2 = expr->GetMatch(4);
- if (offset)
- Title2 = file2.substr(0, expr->GetSubStart(2));
- if (StringUtils::EqualsNoCase(Title1, Title2))
- {
- if (!StringUtils::EqualsNoCase(Volume1, Volume2))
- {
- if (StringUtils::EqualsNoCase(Ignore1, Ignore2) &&
- StringUtils::EqualsNoCase(Extension1, Extension2))
- {
- if (stack.empty())
- {
- stackName = Title1 + Ignore1 + Extension1;
- stack.push_back(i);
- size += item1->m_dwSize;
- }
- stack.push_back(j);
- size += item2->m_dwSize;
- }
- else // Sequel
- {
- offset = 0;
- ++expr;
- break;
- }
- }
- else if (!StringUtils::EqualsNoCase(Ignore1, Ignore2)) // False positive, try again with offset
- {
- offset = expr->GetSubStart(3);
- break;
- }
- else // Extension mismatch
- {
- offset = 0;
- ++expr;
- break;
- }
- }
- else // Title mismatch
- {
- offset = 0;
- ++expr;
- break;
- }
- }
- else // No match 2, next expression
- {
- offset = 0;
- ++expr;
- break;
- }
- j++;
- }
- if (j == Size())
- expr = stackRegExps.end();
- }
- else // No match 1
- {
- offset = 0;
- ++expr;
- }
- if (stack.size() > 1)
- {
- // have a stack, remove the items and add the stacked item
- // dont actually stack a multipart rar set, just remove all items but the first
- std::string stackPath;
- if (Get(stack[0])->IsRAR())
- stackPath = Get(stack[0])->GetPath();
- else
- {
- CStackDirectory dir;
- stackPath = dir.ConstructStackPath(*this, stack);
- }
- item1->SetPath(stackPath);
- // clean up list
- for (unsigned k = 1; k < stack.size(); k++)
- Remove(i+1);
- // item->m_bIsFolder = true; // don't treat stacked files as folders
- // the label may be in a different char set from the filename (eg over smb
- // the label is converted from utf8, but the filename is not)
- if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_SHOWEXTENSIONS))
- URIUtils::RemoveExtension(stackName);
-
- item1->SetLabel(stackName);
- item1->m_dwSize = size;
- break;
- }
- }
- i++;
- }
-}
-
-bool CFileItemList::Load(int windowID)
-{
- CFile file;
- auto path = GetDiscFileCache(windowID);
- try
- {
- if (file.Open(path))
- {
- CArchive ar(&file, CArchive::load);
- ar >> *this;
- CLog::Log(LOGDEBUG, "Loading items: {}, directory: {} sort method: {}, ascending: {}", Size(),
- CURL::GetRedacted(GetPath()), m_sortDescription.sortBy,
- m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
- ar.Close();
- file.Close();
- return true;
- }
- }
- catch(const std::out_of_range&)
- {
- CLog::Log(LOGERROR, "Corrupt archive: {}", CURL::GetRedacted(path));
- }
-
- return false;
-}
-
-bool CFileItemList::Save(int windowID)
-{
- int iSize = Size();
- if (iSize <= 0)
- return false;
-
- CLog::Log(LOGDEBUG, "Saving fileitems [{}]", CURL::GetRedacted(GetPath()));
-
- CFile file;
- std::string cachefile = GetDiscFileCache(windowID);
- if (file.OpenForWrite(cachefile, true)) // overwrite always
- {
- // Before caching save simplified cache file name in every item so the cache file can be
- // identifed and removed if the item is updated. List path and options (used for file
- // name when list cached) can not be accurately derived from item path.
- StringUtils::Replace(cachefile, "special://temp/archive_cache/", "");
- StringUtils::Replace(cachefile, ".fi", "");
- for (const auto& item : m_items)
- item->SetProperty("cachefilename", cachefile);
-
- CArchive ar(&file, CArchive::store);
- ar << *this;
- CLog::Log(LOGDEBUG, " -- items: {}, sort method: {}, ascending: {}", iSize,
- m_sortDescription.sortBy,
- m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
- ar.Close();
- file.Close();
- return true;
- }
-
- return false;
-}
-
-void CFileItemList::RemoveDiscCache(int windowID) const
-{
- RemoveDiscCache(GetDiscFileCache(windowID));
-}
-
-void CFileItemList::RemoveDiscCache(const std::string& cacheFile) const
-{
- if (CFile::Exists(cacheFile))
- {
- CLog::Log(LOGDEBUG, "Clearing cached fileitems [{}]", CURL::GetRedacted(GetPath()));
- CFile::Delete(cacheFile);
- }
-}
-
-void CFileItemList::RemoveDiscCacheCRC(const std::string& crc) const
-{
- std::string cachefile = StringUtils::Format("special://temp/archive_cache/{}.fi", crc);
- RemoveDiscCache(cachefile);
-}
-
-std::string CFileItemList::GetDiscFileCache(int windowID) const
-{
- std::string strPath(GetPath());
- URIUtils::RemoveSlashAtEnd(strPath);
-
- uint32_t crc = Crc32::ComputeFromLowerCase(strPath);
-
- if (IsCDDA() || IsOnDVD())
- return StringUtils::Format("special://temp/archive_cache/r-{:08x}.fi", crc);
-
- if (IsMusicDb())
- return StringUtils::Format("special://temp/archive_cache/mdb-{:08x}.fi", crc);
-
- if (IsVideoDb())
- return StringUtils::Format("special://temp/archive_cache/vdb-{:08x}.fi", crc);
-
- if (IsSmartPlayList())
- return StringUtils::Format("special://temp/archive_cache/sp-{:08x}.fi", crc);
-
- if (windowID)
- return StringUtils::Format("special://temp/archive_cache/{}-{:08x}.fi", windowID, crc);
-
- return StringUtils::Format("special://temp/archive_cache/{:08x}.fi", crc);
-}
-
-bool CFileItemList::AlwaysCache() const
-{
- // some database folders are always cached
- if (IsMusicDb())
- return CMusicDatabaseDirectory::CanCache(GetPath());
- if (IsVideoDb())
- return CVideoDatabaseDirectory::CanCache(GetPath());
- if (IsEPG())
- return true; // always cache
- return false;
-}
-
std::string CFileItem::GetUserMusicThumb(bool alwaysCheckRemote /* = false */, bool fallbackToFolder /* = false */) const
{
- if (m_strPath.empty()
- || StringUtils::StartsWithNoCase(m_strPath, "newsmartplaylist://")
- || StringUtils::StartsWithNoCase(m_strPath, "newplaylist://")
- || m_bIsShareOrDrive
- || IsInternetStream()
- || URIUtils::IsUPnP(m_strPath)
- || (URIUtils::IsFTP(m_strPath) && !CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bFTPThumbs)
- || IsPlugin()
- || IsAddonsPath()
- || IsLibraryFolder()
- || IsParentFolder()
- || IsMusicDb())
+ if (m_strPath.empty() || StringUtils::StartsWithNoCase(m_strPath, "newsmartplaylist://") ||
+ StringUtils::StartsWithNoCase(m_strPath, "newplaylist://") || m_bIsShareOrDrive ||
+ NETWORK::IsInternetStream(*this) || URIUtils::IsUPnP(m_strPath) ||
+ (URIUtils::IsFTP(m_strPath) &&
+ !CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bFTPThumbs) ||
+ IsPlugin() || IsAddonsPath() || IsLibraryFolder() || IsParentFolder() ||
+ MUSIC::IsMusicDb(*this))
return "";
// we first check for <filename>.tbn or <foldername>.tbn
@@ -3271,7 +2000,10 @@ std::string CFileItem::GetUserMusicThumb(bool alwaysCheckRemote /* = false */, b
}
// if a folder, check for folder.jpg
- if (m_bIsFolder && !IsFileFolder() && (!IsRemote() || alwaysCheckRemote || CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MUSICFILES_FINDREMOTETHUMBS)))
+ if (m_bIsFolder && !IsFileFolder() &&
+ (!NETWORK::IsRemote(*this) || alwaysCheckRemote ||
+ CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_MUSICFILES_FINDREMOTETHUMBS)))
{
std::vector<CVariant> thumbs = CServiceBroker::GetSettingsComponent()->GetSettings()->GetList(
CSettings::SETTING_MUSICLIBRARY_MUSICTHUMBS);
@@ -3363,20 +2095,13 @@ std::string CFileItem::GetTBNFile() const
bool CFileItem::SkipLocalArt() const
{
- return (m_strPath.empty()
- || StringUtils::StartsWithNoCase(m_strPath, "newsmartplaylist://")
- || StringUtils::StartsWithNoCase(m_strPath, "newplaylist://")
- || m_bIsShareOrDrive
- || IsInternetStream()
- || URIUtils::IsUPnP(m_strPath)
- || (URIUtils::IsFTP(m_strPath) && !CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bFTPThumbs)
- || IsPlugin()
- || IsAddonsPath()
- || IsLibraryFolder()
- || IsParentFolder()
- || IsLiveTV()
- || IsPVRRecording()
- || IsDVD());
+ return (m_strPath.empty() || StringUtils::StartsWithNoCase(m_strPath, "newsmartplaylist://") ||
+ StringUtils::StartsWithNoCase(m_strPath, "newplaylist://") || m_bIsShareOrDrive ||
+ NETWORK::IsInternetStream(*this) || URIUtils::IsUPnP(m_strPath) ||
+ (URIUtils::IsFTP(m_strPath) &&
+ !CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bFTPThumbs) ||
+ IsPlugin() || IsAddonsPath() || IsLibraryFolder() || IsParentFolder() || IsLiveTV() ||
+ IsPVRRecording() || IsDVD());
}
std::string CFileItem::GetThumbHideIfUnwatched(const CFileItem* item) const
@@ -3575,7 +2300,7 @@ std::string CFileItem::GetBaseMoviePath(bool bUseFolderNames) const
std::string CFileItem::GetLocalFanart() const
{
- if (IsVideoDb())
+ if (VIDEO::IsVideoDb(*this))
{
if (!HasVideoInfoTag())
return ""; // nothing can be done
@@ -3606,15 +2331,11 @@ std::string CFileItem::GetLocalFanart() const
}
// no local fanart available for these
- if (IsInternetStream()
- || URIUtils::IsUPnP(strFile)
- || URIUtils::IsBluray(strFile)
- || IsLiveTV()
- || IsPlugin()
- || IsAddonsPath()
- || IsDVD()
- || (URIUtils::IsFTP(strFile) && !CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bFTPThumbs)
- || m_strPath.empty())
+ if (NETWORK::IsInternetStream(*this) || URIUtils::IsUPnP(strFile) ||
+ URIUtils::IsBluray(strFile) || IsLiveTV() || IsPlugin() || IsAddonsPath() || IsDVD() ||
+ (URIUtils::IsFTP(strFile) &&
+ !CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bFTPThumbs) ||
+ m_strPath.empty())
return "";
std::string strDir = URIUtils::GetDirectory(strFile);
@@ -3660,7 +2381,11 @@ std::string CFileItem::GetLocalMetadataPath() const
if (m_bIsFolder && !IsFileFolder())
return m_strPath;
- std::string parent(URIUtils::GetParentPath(m_strPath));
+ std::string parent{};
+ if (VIDEO::IsBlurayPlaylist(*this))
+ parent = URIUtils::GetParentPath(GetBlurayPath());
+ else
+ parent = URIUtils::GetParentPath(m_strPath);
std::string parentFolder(parent);
URIUtils::RemoveSlashAtEnd(parentFolder);
parentFolder = URIUtils::GetFileName(parentFolder);
@@ -3674,7 +2399,7 @@ std::string CFileItem::GetLocalMetadataPath() const
bool CFileItem::LoadMusicTag()
{
// not audio
- if (!IsAudio())
+ if (!MUSIC::IsAudio(*this))
return false;
// already loaded?
if (HasMusicInfoTag() && m_musicInfoTag->Loaded())
@@ -3701,7 +2426,7 @@ bool CFileItem::LoadMusicTag()
return true;
}
// no tag - try some other things
- if (IsCDDA())
+ if (MUSIC::IsCDDA(*this))
{
// we have the tracknumber...
int iTrack = GetMusicInfoTag()->GetTrackNumber();
@@ -3749,7 +2474,7 @@ bool CFileItem::LoadGameTag()
bool CFileItem::LoadDetails()
{
- if (IsVideoDb())
+ if (VIDEO::IsVideoDb(*this))
{
if (HasVideoInfoTag())
return true;
@@ -3809,7 +2534,7 @@ bool CFileItem::LoadDetails()
return false;
}
- if (!IsPlayList() && IsVideo())
+ if (!IsPlayList() && VIDEO::IsVideo(*this))
{
if (HasVideoInfoTag())
return true;
@@ -3841,7 +2566,7 @@ bool CFileItem::LoadDetails()
if (playlist->Load(GetPath()) && playlist->size() == 1)
{
const auto item{(*playlist)[0]};
- if (item->IsVideo())
+ if (VIDEO::IsVideo(*item))
{
CVideoDatabase db;
if (!db.Open())
@@ -3858,7 +2583,7 @@ bool CFileItem::LoadDetails()
return true;
}
}
- else if (item->IsAudio())
+ else if (MUSIC::IsAudio(*item))
{
if (item->LoadMusicTag())
{
@@ -3872,12 +2597,12 @@ bool CFileItem::LoadDetails()
return false;
}
- if (IsAudio())
+ if (MUSIC::IsAudio(*this))
{
return LoadMusicTag();
}
- if (IsMusicDb())
+ if (MUSIC::IsMusicDb(*this))
{
if (HasMusicInfoTag())
return true;
@@ -3929,66 +2654,6 @@ bool CFileItem::LoadDetails()
return false;
}
-void CFileItemList::Swap(unsigned int item1, unsigned int item2)
-{
- if (item1 != item2 && item1 < m_items.size() && item2 < m_items.size())
- std::swap(m_items[item1], m_items[item2]);
-}
-
-bool CFileItemList::UpdateItem(const CFileItem *item)
-{
- if (!item)
- return false;
-
- std::unique_lock<CCriticalSection> lock(m_lock);
- for (unsigned int i = 0; i < m_items.size(); i++)
- {
- CFileItemPtr pItem = m_items[i];
- if (pItem->IsSamePath(item))
- {
- pItem->UpdateInfo(*item);
- return true;
- }
- }
- return false;
-}
-
-void CFileItemList::AddSortMethod(SortBy sortBy, int buttonLabel, const LABEL_MASKS &labelMasks, SortAttribute sortAttributes /* = SortAttributeNone */)
-{
- AddSortMethod(sortBy, sortAttributes, buttonLabel, labelMasks);
-}
-
-void CFileItemList::AddSortMethod(SortBy sortBy, SortAttribute sortAttributes, int buttonLabel, const LABEL_MASKS &labelMasks)
-{
- SortDescription sorting;
- sorting.sortBy = sortBy;
- sorting.sortAttributes = sortAttributes;
-
- AddSortMethod(sorting, buttonLabel, labelMasks);
-}
-
-void CFileItemList::AddSortMethod(SortDescription sortDescription, int buttonLabel, const LABEL_MASKS &labelMasks)
-{
- GUIViewSortDetails sort;
- sort.m_sortDescription = sortDescription;
- sort.m_buttonLabel = buttonLabel;
- sort.m_labelMasks = labelMasks;
-
- m_sortDetails.push_back(sort);
-}
-
-void CFileItemList::SetReplaceListing(bool replace)
-{
- m_replaceListing = replace;
-}
-
-void CFileItemList::ClearSortState()
-{
- m_sortDescription.sortBy = SortByNone;
- m_sortDescription.sortOrder = SortOrderNone;
- m_sortDescription.sortAttributes = SortAttributeNone;
-}
-
bool CFileItem::HasVideoInfoTag() const
{
// Note: CPVRRecording is derived from CVideoInfoTag
@@ -4072,12 +2737,8 @@ std::string CFileItem::FindTrailer() const
}
// no local trailer available for these
- if (IsInternetStream()
- || URIUtils::IsUPnP(strFile)
- || URIUtils::IsBluray(strFile)
- || IsLiveTV()
- || IsPlugin()
- || IsDVD())
+ if (NETWORK::IsInternetStream(*this) || URIUtils::IsUPnP(strFile) ||
+ URIUtils::IsBluray(strFile) || IsLiveTV() || IsPlugin() || IsDVD())
return "";
std::string strDir = URIUtils::GetDirectory(strFile);
diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h
index 5d338a1f65..7083cf77e0 100644
--- a/xbmc/FileItem.h
+++ b/xbmc/FileItem.h
@@ -142,6 +142,8 @@ public:
const std::string &GetDynPath() const;
void SetDynPath(const std::string &path);
+ std::string GetBlurayPath() const;
+
/*! \brief reset class to it's default values as per construction.
Free's all allocated memory.
\sa Initialize
@@ -157,29 +159,11 @@ public:
bool Exists(bool bUseCache = true) const;
/*!
- \brief Check whether an item is a video item. Note that this returns true for
- anything with a video info tag, so that may include eg. folders.
- \return true if item is video, false otherwise.
- */
- bool IsVideo() const;
-
- bool IsDiscStub() const;
-
- /*!
\brief Check whether an item is a picture item. Note that this returns true for
anything with a picture info tag, so that may include eg. folders.
\return true if item is picture, false otherwise.
*/
bool IsPicture() const;
- bool IsLyrics() const;
- bool IsSubtitle() const;
-
- /*!
- \brief Check whether an item is an audio item. Note that this returns true for
- anything with a music info tag, so that may include eg. folders.
- \return true if item is audio, false otherwise.
- */
- bool IsAudio() const;
/*!
\brief Check whether an item is 'deleted' (for example, a trashed pvr recording).
@@ -187,16 +171,7 @@ public:
*/
bool IsDeleted() const;
- /*!
- \brief Check whether an item is an audio book item.
- \return true if item is audiobook, false otherwise.
- */
- bool IsAudioBook() const;
-
bool IsGame() const;
- bool IsCUESheet() const;
- bool IsInternetStream(const bool bStrictCheck = false) const;
- bool IsStreamedFilesystem() const;
bool IsPlayList() const;
bool IsSmartPlayList() const;
bool IsLibraryFolder() const;
@@ -206,33 +181,24 @@ public:
bool IsAddonsPath() const;
bool IsSourcesPath() const;
bool IsNFO() const;
- bool IsVideoExtras() const;
bool IsDiscImage() const;
bool IsOpticalMediaFile() const;
- bool IsDVDFile(bool bVobs = true, bool bIfos = true) const;
- bool IsBDFile() const;
bool IsBluray() const;
- bool IsProtectedBlurayDisc() const;
bool IsRAR() const;
bool IsAPK() const;
bool IsZIP() const;
bool IsCBZ() const;
bool IsCBR() const;
bool IsISO9660() const;
- bool IsCDDA() const;
bool IsDVD() const;
bool IsOnDVD() const;
- bool IsOnLAN() const;
bool IsHD() const;
bool IsNfs() const;
- bool IsRemote() const;
bool IsSmb() const;
bool IsURL() const;
bool IsStack() const;
bool IsFavourite() const;
bool IsMultiPath() const;
- bool IsMusicDb() const;
- bool IsVideoDb() const;
bool IsEPG() const;
bool IsPVRChannel() const;
bool IsPVRChannelGroup() const;
@@ -625,6 +591,7 @@ public:
void LoadEmbeddedCue();
bool HasCueDocument() const;
bool LoadTracksFromCueDocument(CFileItemList& scannedItems);
+
private:
/*! \brief initialize all members of this class (not CGUIListItem members) to default values.
Called from constructors, and from Reset()
@@ -708,181 +675,4 @@ typedef std::map<std::string, CFileItemPtr > MAPFILEITEMS;
typedef std::pair<std::string, CFileItemPtr > MAPFILEITEMSPAIR;
typedef bool (*FILEITEMLISTCOMPARISONFUNC) (const CFileItemPtr &pItem1, const CFileItemPtr &pItem2);
-typedef void (*FILEITEMFILLFUNC) (CFileItemPtr &item);
-
-/*!
- \brief Represents a list of files
- \sa CFileItemList, CFileItem
- */
-class CFileItemList : public CFileItem
-{
-public:
- enum CACHE_TYPE { CACHE_NEVER = 0, CACHE_IF_SLOW, CACHE_ALWAYS };
-
- CFileItemList();
- explicit CFileItemList(const std::string& strPath);
- ~CFileItemList() override;
- void Archive(CArchive& ar) override;
- CFileItemPtr operator[] (int iItem);
- const CFileItemPtr operator[] (int iItem) const;
- CFileItemPtr operator[] (const std::string& strPath);
- const CFileItemPtr operator[] (const std::string& strPath) const;
- void Clear();
- void ClearItems();
- void Add(CFileItemPtr item);
- void Add(CFileItem&& item);
- void AddFront(const CFileItemPtr &pItem, int itemPosition);
- void Remove(CFileItem* pItem);
- void Remove(int iItem);
- CFileItemPtr Get(int iItem) const;
- const VECFILEITEMS& GetList() const { return m_items; }
- CFileItemPtr Get(const std::string& strPath) const;
- int Size() const;
- bool IsEmpty() const;
- void Append(const CFileItemList& itemlist);
- void Assign(const CFileItemList& itemlist, bool append = false);
- bool Copy (const CFileItemList& item, bool copyItems = true);
- void Reserve(size_t iCount);
- void Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute sortAttributes = SortAttributeNone);
- /* \brief Sorts the items based on the given sorting options
-
- In contrast to Sort (see above) this does not change the internal
- state by storing the sorting method and order used and therefore
- will always execute the sorting even if the list of items has
- already been sorted with the same options before.
- */
- void Sort(SortDescription sortDescription);
- void Randomize();
- void FillInDefaultIcons();
- int GetFolderCount() const;
- int GetFileCount() const;
- int GetSelectedCount() const;
- int GetObjectCount() const;
- void FilterCueItems();
- void RemoveExtensions();
- void SetIgnoreURLOptions(bool ignoreURLOptions);
- void SetFastLookup(bool fastLookup);
- bool Contains(const std::string& fileName) const;
- bool GetFastLookup() const { return m_fastLookup; }
-
- /*! \brief stack a CFileItemList
- By default we stack all items (files and folders) in a CFileItemList
- \param stackFiles whether to stack all items or just collapse folders (defaults to true)
- \sa StackFiles,StackFolders
- */
- void Stack(bool stackFiles = true);
-
- SortOrder GetSortOrder() const { return m_sortDescription.sortOrder; }
- SortBy GetSortMethod() const { return m_sortDescription.sortBy; }
- void SetSortOrder(SortOrder sortOrder) { m_sortDescription.sortOrder = sortOrder; }
- void SetSortMethod(SortBy sortBy) { m_sortDescription.sortBy = sortBy; }
-
- /*! \brief load a CFileItemList out of the cache
-
- The file list may be cached based on which window we're viewing in, as different
- windows will be listing different portions of the same URL (eg viewing music files
- versus viewing video files)
-
- \param windowID id of the window that's loading this list (defaults to 0)
- \return true if we loaded from the cache, false otherwise.
- \sa Save,RemoveDiscCache
- */
- bool Load(int windowID = 0);
-
- /*! \brief save a CFileItemList to the cache
-
- The file list may be cached based on which window we're viewing in, as different
- windows will be listing different portions of the same URL (eg viewing music files
- versus viewing video files)
-
- \param windowID id of the window that's saving this list (defaults to 0)
- \return true if successful, false otherwise.
- \sa Load,RemoveDiscCache
- */
- bool Save(int windowID = 0);
- void SetCacheToDisc(CACHE_TYPE cacheToDisc) { m_cacheToDisc = cacheToDisc; }
- bool CacheToDiscAlways() const { return m_cacheToDisc == CACHE_ALWAYS; }
- bool CacheToDiscIfSlow() const { return m_cacheToDisc == CACHE_IF_SLOW; }
- /*! \brief remove a previously cached CFileItemList from the cache
-
- The file list may be cached based on which window we're viewing in, as different
- windows will be listing different portions of the same URL (eg viewing music files
- versus viewing video files)
-
- \param windowID id of the window whose cache we which to remove (defaults to 0)
- \sa Save,Load
- */
- void RemoveDiscCache(int windowID = 0) const;
- void RemoveDiscCache(const std::string& cachefile) const;
- void RemoveDiscCacheCRC(const std::string& crc) const;
- bool AlwaysCache() const;
-
- void Swap(unsigned int item1, unsigned int item2);
-
- /*! \brief Update an item in the item list
- \param item the new item, which we match based on path to an existing item in the list
- \return true if the item exists in the list (and was thus updated), false otherwise.
- */
- bool UpdateItem(const CFileItem *item);
-
- void AddSortMethod(SortBy sortBy, int buttonLabel, const LABEL_MASKS &labelMasks, SortAttribute sortAttributes = SortAttributeNone);
- void AddSortMethod(SortBy sortBy, SortAttribute sortAttributes, int buttonLabel, const LABEL_MASKS &labelMasks);
- void AddSortMethod(SortDescription sortDescription, int buttonLabel, const LABEL_MASKS &labelMasks);
- bool HasSortDetails() const { return m_sortDetails.size() != 0; }
- const std::vector<GUIViewSortDetails> &GetSortDetails() const { return m_sortDetails; }
-
- /*! \brief Specify whether this list should be sorted with folders separate from files
- By default we sort with folders listed (and sorted separately) except for those sort modes
- which should be explicitly sorted with folders interleaved with files (eg SORT_METHOD_FILES).
- With this set the folder state will be ignored, allowing folders and files to sort interleaved.
- \param sort whether to ignore the folder state.
- */
- void SetSortIgnoreFolders(bool sort) { m_sortIgnoreFolders = sort; }
- bool GetReplaceListing() const { return m_replaceListing; }
- void SetReplaceListing(bool replace);
- void SetContent(const std::string& content) { m_content = content; }
- const std::string& GetContent() const { return m_content; }
-
- void ClearSortState();
-
- VECFILEITEMS::iterator begin() { return m_items.begin(); }
- VECFILEITEMS::iterator end() { return m_items.end(); }
- VECFILEITEMS::iterator erase(VECFILEITEMS::iterator first, VECFILEITEMS::iterator last);
- VECFILEITEMS::const_iterator begin() const { return m_items.begin(); }
- VECFILEITEMS::const_iterator end() const { return m_items.end(); }
- VECFILEITEMS::const_iterator cbegin() const { return m_items.cbegin(); }
- VECFILEITEMS::const_iterator cend() const { return m_items.cend(); }
- std::reverse_iterator<VECFILEITEMS::const_iterator> rbegin() const { return m_items.rbegin(); }
- std::reverse_iterator<VECFILEITEMS::const_iterator> rend() const { return m_items.rend(); }
-
-private:
- void Sort(FILEITEMLISTCOMPARISONFUNC func);
- void FillSortFields(FILEITEMFILLFUNC func);
- std::string GetDiscFileCache(int windowID) const;
-
- /*!
- \brief stack files in a CFileItemList
- \sa Stack
- */
- void StackFiles();
-
- /*!
- \brief stack folders in a CFileItemList
- \sa Stack
- */
- void StackFolders();
-
- VECFILEITEMS m_items;
- MAPFILEITEMS m_map;
- bool m_ignoreURLOptions = false;
- bool m_fastLookup = false;
- SortDescription m_sortDescription;
- bool m_sortIgnoreFolders = false;
- CACHE_TYPE m_cacheToDisc = CACHE_IF_SLOW;
- bool m_replaceListing = false;
- std::string m_content;
-
- std::vector<GUIViewSortDetails> m_sortDetails;
-
- mutable CCriticalSection m_lock;
-};
+typedef void (*FILEITEMFILLFUNC)(CFileItemPtr& item);
diff --git a/xbmc/FileItemList.cpp b/xbmc/FileItemList.cpp
new file mode 100644
index 0000000000..e14b9a6c61
--- /dev/null
+++ b/xbmc/FileItemList.cpp
@@ -0,0 +1,1176 @@
+/*
+ * Copyright (C) 2005-2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "FileItemList.h"
+
+#include "CueDocument.h"
+#include "ServiceBroker.h"
+#include "URL.h"
+#include "filesystem/Directory.h"
+#include "filesystem/File.h"
+#include "filesystem/MusicDatabaseDirectory.h"
+#include "filesystem/StackDirectory.h"
+#include "filesystem/VideoDatabaseDirectory.h"
+#include "music/MusicFileItemClassify.h"
+#include "network/NetworkFileItemClassify.h"
+#include "settings/AdvancedSettings.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "utils/Archive.h"
+#include "utils/Crc32.h"
+#include "utils/FileExtensionProvider.h"
+#include "utils/Random.h"
+#include "utils/RegExp.h"
+#include "utils/URIUtils.h"
+#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
+#include "video/VideoUtils.h"
+
+#include <algorithm>
+
+using namespace KODI;
+using namespace XFILE;
+
+CFileItemList::CFileItemList() : CFileItem("", true)
+{
+}
+
+CFileItemList::CFileItemList(const std::string& strPath) : CFileItem(strPath, true)
+{
+}
+
+CFileItemList::~CFileItemList()
+{
+ Clear();
+}
+
+CFileItemPtr CFileItemList::operator[](int iItem)
+{
+ return Get(iItem);
+}
+
+const CFileItemPtr CFileItemList::operator[](int iItem) const
+{
+ return Get(iItem);
+}
+
+CFileItemPtr CFileItemList::operator[](const std::string& strPath)
+{
+ return Get(strPath);
+}
+
+const CFileItemPtr CFileItemList::operator[](const std::string& strPath) const
+{
+ return Get(strPath);
+}
+
+void CFileItemList::SetIgnoreURLOptions(bool ignoreURLOptions)
+{
+ m_ignoreURLOptions = ignoreURLOptions;
+
+ if (m_fastLookup)
+ {
+ m_fastLookup = false; // Force SetFastlookup to clear map
+ SetFastLookup(true); // and regenerate map
+ }
+}
+
+void CFileItemList::SetFastLookup(bool fastLookup)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (fastLookup && !m_fastLookup)
+ { // generate the map
+ m_map.clear();
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ m_map.insert(MAPFILEITEMSPAIR(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions()
+ : pItem->GetPath(),
+ pItem));
+ }
+ }
+ if (!fastLookup && m_fastLookup)
+ m_map.clear();
+ m_fastLookup = fastLookup;
+}
+
+bool CFileItemList::Contains(const std::string& fileName) const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (m_fastLookup)
+ return m_map.find(m_ignoreURLOptions ? CURL(fileName).GetWithoutOptions() : fileName) !=
+ m_map.end();
+
+ // slow method...
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ const CFileItemPtr pItem = m_items[i];
+ if (pItem->IsPath(m_ignoreURLOptions ? CURL(fileName).GetWithoutOptions() : fileName))
+ return true;
+ }
+ return false;
+}
+
+void CFileItemList::Clear()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ ClearItems();
+ m_sortDescription.sortBy = SortByNone;
+ m_sortDescription.sortOrder = SortOrderNone;
+ m_sortDescription.sortAttributes = SortAttributeNone;
+ m_sortIgnoreFolders = false;
+ m_cacheToDisc = CACHE_IF_SLOW;
+ m_sortDetails.clear();
+ m_replaceListing = false;
+ m_content.clear();
+}
+
+void CFileItemList::ClearItems()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ // make sure we free the memory of the items (these are GUIControls which may have allocated resources)
+ FreeMemory();
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ CFileItemPtr item = m_items[i];
+ item->FreeMemory();
+ }
+ m_items.clear();
+ m_map.clear();
+}
+
+void CFileItemList::Add(CFileItemPtr pItem)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ if (m_fastLookup)
+ m_map.insert(MAPFILEITEMSPAIR(
+ m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
+ m_items.emplace_back(std::move(pItem));
+}
+
+void CFileItemList::Add(CFileItem&& item)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ auto ptr = std::make_shared<CFileItem>(std::move(item));
+ if (m_fastLookup)
+ m_map.insert(MAPFILEITEMSPAIR(
+ m_ignoreURLOptions ? CURL(ptr->GetPath()).GetWithoutOptions() : ptr->GetPath(), ptr));
+ m_items.emplace_back(std::move(ptr));
+}
+
+void CFileItemList::AddFront(const CFileItemPtr& pItem, int itemPosition)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (itemPosition >= 0)
+ {
+ m_items.insert(m_items.begin() + itemPosition, pItem);
+ }
+ else
+ {
+ m_items.insert(m_items.begin() + (m_items.size() + itemPosition), pItem);
+ }
+ if (m_fastLookup)
+ {
+ m_map.insert(MAPFILEITEMSPAIR(
+ m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions() : pItem->GetPath(), pItem));
+ }
+}
+
+void CFileItemList::Remove(CFileItem* pItem)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ for (IVECFILEITEMS it = m_items.begin(); it != m_items.end(); ++it)
+ {
+ if (pItem == it->get())
+ {
+ m_items.erase(it);
+ if (m_fastLookup)
+ {
+ m_map.erase(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions()
+ : pItem->GetPath());
+ }
+ break;
+ }
+ }
+}
+
+VECFILEITEMS::iterator CFileItemList::erase(VECFILEITEMS::iterator first,
+ VECFILEITEMS::iterator last)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ return m_items.erase(first, last);
+}
+
+void CFileItemList::Remove(int iItem)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (iItem >= 0 && iItem < Size())
+ {
+ CFileItemPtr pItem = *(m_items.begin() + iItem);
+ if (m_fastLookup)
+ {
+ m_map.erase(m_ignoreURLOptions ? CURL(pItem->GetPath()).GetWithoutOptions()
+ : pItem->GetPath());
+ }
+ m_items.erase(m_items.begin() + iItem);
+ }
+}
+
+void CFileItemList::Append(const CFileItemList& itemlist)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ for (int i = 0; i < itemlist.Size(); ++i)
+ Add(itemlist[i]);
+}
+
+void CFileItemList::Assign(const CFileItemList& itemlist, bool append)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ if (!append)
+ Clear();
+ Append(itemlist);
+ SetPath(itemlist.GetPath());
+ SetLabel(itemlist.GetLabel());
+ m_sortDetails = itemlist.m_sortDetails;
+ m_sortDescription = itemlist.m_sortDescription;
+ m_replaceListing = itemlist.m_replaceListing;
+ m_content = itemlist.m_content;
+ m_mapProperties = itemlist.m_mapProperties;
+ m_cacheToDisc = itemlist.m_cacheToDisc;
+}
+
+bool CFileItemList::Copy(const CFileItemList& items, bool copyItems /* = true */)
+{
+ // assign all CFileItem parts
+ *static_cast<CFileItem*>(this) = static_cast<const CFileItem&>(items);
+
+ // assign the rest of the CFileItemList properties
+ m_replaceListing = items.m_replaceListing;
+ m_content = items.m_content;
+ m_mapProperties = items.m_mapProperties;
+ m_cacheToDisc = items.m_cacheToDisc;
+ m_sortDetails = items.m_sortDetails;
+ m_sortDescription = items.m_sortDescription;
+ m_sortIgnoreFolders = items.m_sortIgnoreFolders;
+
+ if (copyItems)
+ {
+ // make a copy of each item
+ for (int i = 0; i < items.Size(); i++)
+ {
+ CFileItemPtr newItem(new CFileItem(*items[i]));
+ Add(newItem);
+ }
+ }
+
+ return true;
+}
+
+CFileItemPtr CFileItemList::Get(int iItem) const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (iItem > -1 && iItem < (int)m_items.size())
+ return m_items[iItem];
+
+ return CFileItemPtr();
+}
+
+CFileItemPtr CFileItemList::Get(const std::string& strPath) const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ if (m_fastLookup)
+ {
+ MAPFILEITEMS::const_iterator it =
+ m_map.find(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath);
+ if (it != m_map.end())
+ return it->second;
+
+ return CFileItemPtr();
+ }
+ // slow method...
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (pItem->IsPath(m_ignoreURLOptions ? CURL(strPath).GetWithoutOptions() : strPath))
+ return pItem;
+ }
+
+ return CFileItemPtr();
+}
+
+int CFileItemList::Size() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ return (int)m_items.size();
+}
+
+bool CFileItemList::IsEmpty() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ return m_items.empty();
+}
+
+void CFileItemList::Reserve(size_t iCount)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ m_items.reserve(iCount);
+}
+
+void CFileItemList::Sort(FILEITEMLISTCOMPARISONFUNC func)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ std::stable_sort(m_items.begin(), m_items.end(), func);
+}
+
+void CFileItemList::FillSortFields(FILEITEMFILLFUNC func)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ std::for_each(m_items.begin(), m_items.end(), func);
+}
+
+void CFileItemList::Sort(SortBy sortBy,
+ SortOrder sortOrder,
+ SortAttribute sortAttributes /* = SortAttributeNone */)
+{
+ if (sortBy == SortByNone ||
+ (m_sortDescription.sortBy == sortBy && m_sortDescription.sortOrder == sortOrder &&
+ m_sortDescription.sortAttributes == sortAttributes))
+ return;
+
+ SortDescription sorting;
+ sorting.sortBy = sortBy;
+ sorting.sortOrder = sortOrder;
+ sorting.sortAttributes = sortAttributes;
+
+ Sort(sorting);
+ m_sortDescription = sorting;
+}
+
+void CFileItemList::Sort(SortDescription sortDescription)
+{
+ if (sortDescription.sortBy == SortByFile || sortDescription.sortBy == SortBySortTitle ||
+ sortDescription.sortBy == SortByOriginalTitle || sortDescription.sortBy == SortByDateAdded ||
+ sortDescription.sortBy == SortByRating || sortDescription.sortBy == SortByYear ||
+ sortDescription.sortBy == SortByPlaylistOrder || sortDescription.sortBy == SortByLastPlayed ||
+ sortDescription.sortBy == SortByPlaycount)
+ sortDescription.sortAttributes =
+ (SortAttribute)((int)sortDescription.sortAttributes | SortAttributeIgnoreFolders);
+
+ if (sortDescription.sortBy == SortByNone ||
+ (m_sortDescription.sortBy == sortDescription.sortBy &&
+ m_sortDescription.sortOrder == sortDescription.sortOrder &&
+ m_sortDescription.sortAttributes == sortDescription.sortAttributes))
+ return;
+
+ if (m_sortIgnoreFolders)
+ sortDescription.sortAttributes =
+ (SortAttribute)((int)sortDescription.sortAttributes | SortAttributeIgnoreFolders);
+
+ const Fields fields = SortUtils::GetFieldsForSorting(sortDescription.sortBy);
+ SortItems sortItems((size_t)Size());
+ for (int index = 0; index < Size(); index++)
+ {
+ sortItems[index] = std::make_shared<SortItem>();
+ m_items[index]->ToSortable(*sortItems[index], fields);
+ (*sortItems[index])[FieldId] = index;
+ }
+
+ // do the sorting
+ SortUtils::Sort(sortDescription, sortItems);
+
+ // apply the new order to the existing CFileItems
+ VECFILEITEMS sortedFileItems;
+ sortedFileItems.reserve(Size());
+ for (SortItems::const_iterator it = sortItems.begin(); it != sortItems.end(); ++it)
+ {
+ CFileItemPtr item = m_items[(int)(*it)->at(FieldId).asInteger()];
+ // Set the sort label in the CFileItem
+ item->SetSortLabel((*it)->at(FieldSort).asWideString());
+
+ sortedFileItems.push_back(item);
+ }
+
+ // replace the current list with the re-ordered one
+ m_items = std::move(sortedFileItems);
+}
+
+void CFileItemList::Randomize()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ KODI::UTILS::RandomShuffle(m_items.begin(), m_items.end());
+}
+
+void CFileItemList::Archive(CArchive& ar)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ if (ar.IsStoring())
+ {
+ CFileItem::Archive(ar);
+
+ int i = 0;
+ if (!m_items.empty() && m_items[0]->IsParentFolder())
+ i = 1;
+
+ ar << (int)(m_items.size() - i);
+
+ ar << m_ignoreURLOptions;
+
+ ar << m_fastLookup;
+
+ ar << (int)m_sortDescription.sortBy;
+ ar << (int)m_sortDescription.sortOrder;
+ ar << (int)m_sortDescription.sortAttributes;
+ ar << m_sortIgnoreFolders;
+ ar << (int)m_cacheToDisc;
+
+ ar << (int)m_sortDetails.size();
+ for (unsigned int j = 0; j < m_sortDetails.size(); ++j)
+ {
+ const GUIViewSortDetails& details = m_sortDetails[j];
+ ar << (int)details.m_sortDescription.sortBy;
+ ar << (int)details.m_sortDescription.sortOrder;
+ ar << (int)details.m_sortDescription.sortAttributes;
+ ar << details.m_buttonLabel;
+ ar << details.m_labelMasks.m_strLabelFile;
+ ar << details.m_labelMasks.m_strLabelFolder;
+ ar << details.m_labelMasks.m_strLabel2File;
+ ar << details.m_labelMasks.m_strLabel2Folder;
+ }
+
+ ar << m_content;
+
+ for (; i < (int)m_items.size(); ++i)
+ {
+ CFileItemPtr pItem = m_items[i];
+ ar << *pItem;
+ }
+ }
+ else
+ {
+ CFileItemPtr pParent;
+ if (!IsEmpty())
+ {
+ CFileItemPtr pItem = m_items[0];
+ if (pItem->IsParentFolder())
+ pParent = std::make_shared<CFileItem>(*pItem);
+ }
+
+ SetIgnoreURLOptions(false);
+ SetFastLookup(false);
+ Clear();
+
+ CFileItem::Archive(ar);
+
+ int iSize = 0;
+ ar >> iSize;
+ if (iSize <= 0)
+ return;
+
+ if (pParent)
+ {
+ m_items.reserve(iSize + 1);
+ m_items.push_back(pParent);
+ }
+ else
+ m_items.reserve(iSize);
+
+ bool ignoreURLOptions = false;
+ ar >> ignoreURLOptions;
+
+ bool fastLookup = false;
+ ar >> fastLookup;
+
+ int tempint;
+ ar >> tempint;
+ m_sortDescription.sortBy = (SortBy)tempint;
+ ar >> tempint;
+ m_sortDescription.sortOrder = (SortOrder)tempint;
+ ar >> tempint;
+ m_sortDescription.sortAttributes = (SortAttribute)tempint;
+ ar >> m_sortIgnoreFolders;
+ ar >> tempint;
+ m_cacheToDisc = CACHE_TYPE(tempint);
+
+ unsigned int detailSize = 0;
+ ar >> detailSize;
+ for (unsigned int j = 0; j < detailSize; ++j)
+ {
+ GUIViewSortDetails details;
+ ar >> tempint;
+ details.m_sortDescription.sortBy = (SortBy)tempint;
+ ar >> tempint;
+ details.m_sortDescription.sortOrder = (SortOrder)tempint;
+ ar >> tempint;
+ details.m_sortDescription.sortAttributes = (SortAttribute)tempint;
+ ar >> details.m_buttonLabel;
+ ar >> details.m_labelMasks.m_strLabelFile;
+ ar >> details.m_labelMasks.m_strLabelFolder;
+ ar >> details.m_labelMasks.m_strLabel2File;
+ ar >> details.m_labelMasks.m_strLabel2Folder;
+ m_sortDetails.push_back(details);
+ }
+
+ ar >> m_content;
+
+ for (int i = 0; i < iSize; ++i)
+ {
+ CFileItemPtr pItem(new CFileItem);
+ ar >> *pItem;
+ Add(pItem);
+ }
+
+ SetIgnoreURLOptions(ignoreURLOptions);
+ SetFastLookup(fastLookup);
+ }
+}
+
+void CFileItemList::FillInDefaultIcons()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ for (int i = 0; i < (int)m_items.size(); ++i)
+ {
+ CFileItemPtr pItem = m_items[i];
+ pItem->FillInDefaultIcon();
+ }
+}
+
+int CFileItemList::GetFolderCount() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ int nFolderCount = 0;
+ for (int i = 0; i < (int)m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (pItem->m_bIsFolder)
+ nFolderCount++;
+ }
+
+ return nFolderCount;
+}
+
+int CFileItemList::GetObjectCount() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ int numObjects = (int)m_items.size();
+ if (numObjects && m_items[0]->IsParentFolder())
+ numObjects--;
+
+ return numObjects;
+}
+
+int CFileItemList::GetFileCount() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ int nFileCount = 0;
+ for (int i = 0; i < (int)m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (!pItem->m_bIsFolder)
+ nFileCount++;
+ }
+
+ return nFileCount;
+}
+
+int CFileItemList::GetSelectedCount() const
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ int count = 0;
+ for (int i = 0; i < (int)m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (pItem->IsSelected())
+ count++;
+ }
+
+ return count;
+}
+
+void CFileItemList::FilterCueItems()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ // Handle .CUE sheet files...
+ std::vector<std::string> itemstodelete;
+ for (int i = 0; i < (int)m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (!pItem->m_bIsFolder)
+ { // see if it's a .CUE sheet
+ if (MUSIC::IsCUESheet(*pItem))
+ {
+ CCueDocumentPtr cuesheet(new CCueDocument);
+ if (cuesheet->ParseFile(pItem->GetPath()))
+ {
+ std::vector<std::string> MediaFileVec;
+ cuesheet->GetMediaFiles(MediaFileVec);
+
+ // queue the cue sheet and the underlying media file for deletion
+ for (std::vector<std::string>::iterator itMedia = MediaFileVec.begin();
+ itMedia != MediaFileVec.end(); ++itMedia)
+ {
+ std::string strMediaFile = *itMedia;
+ std::string fileFromCue =
+ strMediaFile; // save the file from the cue we're matching against,
+ // as we're going to search for others here...
+ bool bFoundMediaFile = CFile::Exists(strMediaFile);
+ if (!bFoundMediaFile)
+ {
+ // try file in same dir, not matching case...
+ if (Contains(strMediaFile))
+ {
+ bFoundMediaFile = true;
+ }
+ else
+ {
+ // try removing the .cue extension...
+ strMediaFile = pItem->GetPath();
+ URIUtils::RemoveExtension(strMediaFile);
+ CFileItem item(strMediaFile, false);
+ if (MUSIC::IsAudio(item) && Contains(strMediaFile))
+ {
+ bFoundMediaFile = true;
+ }
+ else
+ { // try replacing the extension with one of our allowed ones.
+ std::vector<std::string> extensions = StringUtils::Split(
+ CServiceBroker::GetFileExtensionProvider().GetMusicExtensions(), "|");
+ for (std::vector<std::string>::const_iterator i = extensions.begin();
+ i != extensions.end(); ++i)
+ {
+ strMediaFile = URIUtils::ReplaceExtension(pItem->GetPath(), *i);
+ CFileItem item(strMediaFile, false);
+ if (!MUSIC::IsCUESheet(item) && !item.IsPlayList() && Contains(strMediaFile))
+ {
+ bFoundMediaFile = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (bFoundMediaFile)
+ {
+ cuesheet->UpdateMediaFile(fileFromCue, strMediaFile);
+ // apply CUE for later processing
+ for (int j = 0; j < (int)m_items.size(); j++)
+ {
+ CFileItemPtr pItem = m_items[j];
+ if (StringUtils::CompareNoCase(pItem->GetPath(), strMediaFile) == 0)
+ pItem->SetCueDocument(cuesheet);
+ }
+ }
+ }
+ }
+ itemstodelete.push_back(pItem->GetPath());
+ }
+ }
+ }
+ // now delete the .CUE files.
+ for (int i = 0; i < (int)itemstodelete.size(); i++)
+ {
+ for (int j = 0; j < (int)m_items.size(); j++)
+ {
+ CFileItemPtr pItem = m_items[j];
+ if (StringUtils::CompareNoCase(pItem->GetPath(), itemstodelete[i]) == 0)
+ { // delete this item
+ m_items.erase(m_items.begin() + j);
+ break;
+ }
+ }
+ }
+}
+
+// Remove the extensions from the filenames
+void CFileItemList::RemoveExtensions()
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ for (int i = 0; i < Size(); ++i)
+ m_items[i]->RemoveExtension();
+}
+
+void CFileItemList::Stack(bool stackFiles /* = true */)
+{
+ std::unique_lock<CCriticalSection> lock(m_lock);
+
+ // not allowed here
+ if (IsVirtualDirectoryRoot() || IsLiveTV() || IsSourcesPath() || IsLibraryFolder())
+ return;
+
+ SetProperty("isstacked", true);
+
+ // items needs to be sorted for stuff below to work properly
+ Sort(SortByLabel, SortOrderAscending);
+
+ StackFolders();
+
+ if (stackFiles)
+ StackFiles();
+}
+
+void CFileItemList::StackFolders()
+{
+ // Precompile our REs
+ VECCREGEXP folderRegExps;
+ CRegExp folderRegExp(true, CRegExp::autoUtf8);
+ const std::vector<std::string>& strFolderRegExps =
+ CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_folderStackRegExps;
+
+ std::vector<std::string>::const_iterator strExpression = strFolderRegExps.begin();
+ while (strExpression != strFolderRegExps.end())
+ {
+ if (!folderRegExp.RegComp(*strExpression))
+ CLog::Log(LOGERROR, "{}: Invalid folder stack RegExp:'{}'", __FUNCTION__,
+ strExpression->c_str());
+ else
+ folderRegExps.push_back(folderRegExp);
+
+ ++strExpression;
+ }
+
+ if (!folderRegExp.IsCompiled())
+ {
+ CLog::Log(LOGDEBUG, "{}: No stack expressions available. Skipping folder stacking",
+ __FUNCTION__);
+ return;
+ }
+
+ // stack folders
+ for (int i = 0; i < Size(); i++)
+ {
+ CFileItemPtr item = Get(i);
+ // combined the folder checks
+ if (item->m_bIsFolder)
+ {
+ // only check known fast sources?
+ // NOTES:
+ // 1. rars and zips may be on slow sources? is this supposed to be allowed?
+ if (!NETWORK::IsRemote(*item) || item->IsSmb() || item->IsNfs() ||
+ URIUtils::IsInRAR(item->GetPath()) || URIUtils::IsInZIP(item->GetPath()) ||
+ URIUtils::IsOnLAN(item->GetPath()))
+ {
+ // stack cd# folders if contains only a single video file
+
+ bool bMatch(false);
+
+ VECCREGEXP::iterator expr = folderRegExps.begin();
+ while (!bMatch && expr != folderRegExps.end())
+ {
+ //CLog::Log(LOGDEBUG,"{}: Running expression {} on {}", __FUNCTION__, expr->GetPattern(), item->GetLabel());
+ bMatch = (expr->RegFind(item->GetLabel().c_str()) != -1);
+ if (bMatch)
+ {
+ CFileItemList items;
+ CDirectory::GetDirectory(
+ item->GetPath(), items,
+ CServiceBroker::GetFileExtensionProvider().GetVideoExtensions(), DIR_FLAG_DEFAULTS);
+ // optimized to only traverse listing once by checking for filecount
+ // and recording last file item for later use
+ int nFiles = 0;
+ int index = -1;
+ for (int j = 0; j < items.Size(); j++)
+ {
+ if (!items[j]->m_bIsFolder)
+ {
+ nFiles++;
+ index = j;
+ }
+
+ if (nFiles > 1)
+ break;
+ }
+
+ if (nFiles == 1)
+ *item = *items[index];
+ }
+ ++expr;
+ }
+
+ // check for dvd folders
+ if (!bMatch)
+ {
+ std::string dvdPath = VIDEO::UTILS::GetOpticalMediaPath(*item);
+
+ if (!dvdPath.empty())
+ {
+ // NOTE: should this be done for the CD# folders too?
+ item->m_bIsFolder = false;
+ item->SetPath(dvdPath);
+ item->SetLabel2("");
+ item->SetLabelPreformatted(true);
+ m_sortDescription.sortBy = SortByNone; /* sorting is now broken */
+ }
+ }
+ }
+ }
+ }
+}
+
+void CFileItemList::StackFiles()
+{
+ // Precompile our REs
+ VECCREGEXP stackRegExps;
+ CRegExp tmpRegExp(true, CRegExp::autoUtf8);
+ const std::vector<std::string>& strStackRegExps =
+ CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_videoStackRegExps;
+ std::vector<std::string>::const_iterator strRegExp = strStackRegExps.begin();
+ while (strRegExp != strStackRegExps.end())
+ {
+ if (tmpRegExp.RegComp(*strRegExp))
+ {
+ if (tmpRegExp.GetCaptureTotal() == 4)
+ stackRegExps.push_back(tmpRegExp);
+ else
+ CLog::Log(LOGERROR, "Invalid video stack RE ({}). Must have 4 captures.", *strRegExp);
+ }
+ ++strRegExp;
+ }
+
+ // now stack the files, some of which may be from the previous stack iteration
+ int i = 0;
+ while (i < Size())
+ {
+ CFileItemPtr item1 = Get(i);
+
+ // skip folders, nfo files, playlists
+ if (item1->m_bIsFolder || item1->IsParentFolder() || item1->IsNFO() || item1->IsPlayList())
+ {
+ // increment index
+ i++;
+ continue;
+ }
+
+ int64_t size = 0;
+ size_t offset = 0;
+ std::string stackName;
+ std::string file1;
+ std::string filePath;
+ std::vector<int> stack;
+ VECCREGEXP::iterator expr = stackRegExps.begin();
+
+ URIUtils::Split(item1->GetPath(), filePath, file1);
+ if (URIUtils::HasEncodedFilename(CURL(filePath)))
+ file1 = CURL::Decode(file1);
+
+ int j;
+ while (expr != stackRegExps.end())
+ {
+ if (expr->RegFind(file1, offset) != -1)
+ {
+ std::string Title1 = expr->GetMatch(1), Volume1 = expr->GetMatch(2),
+ Ignore1 = expr->GetMatch(3), Extension1 = expr->GetMatch(4);
+ if (offset)
+ Title1 = file1.substr(0, expr->GetSubStart(2));
+ j = i + 1;
+ while (j < Size())
+ {
+ CFileItemPtr item2 = Get(j);
+
+ // skip folders, nfo files, playlists
+ if (item2->m_bIsFolder || item2->IsParentFolder() || item2->IsNFO() ||
+ item2->IsPlayList())
+ {
+ // increment index
+ j++;
+ continue;
+ }
+
+ std::string file2, filePath2;
+ URIUtils::Split(item2->GetPath(), filePath2, file2);
+ if (URIUtils::HasEncodedFilename(CURL(filePath2)))
+ file2 = CURL::Decode(file2);
+
+ if (expr->RegFind(file2, offset) != -1)
+ {
+ std::string Title2 = expr->GetMatch(1), Volume2 = expr->GetMatch(2),
+ Ignore2 = expr->GetMatch(3), Extension2 = expr->GetMatch(4);
+ if (offset)
+ Title2 = file2.substr(0, expr->GetSubStart(2));
+ if (StringUtils::EqualsNoCase(Title1, Title2))
+ {
+ if (!StringUtils::EqualsNoCase(Volume1, Volume2))
+ {
+ if (StringUtils::EqualsNoCase(Ignore1, Ignore2) &&
+ StringUtils::EqualsNoCase(Extension1, Extension2))
+ {
+ if (stack.empty())
+ {
+ stackName = Title1 + Ignore1 + Extension1;
+ stack.push_back(i);
+ size += item1->m_dwSize;
+ }
+ stack.push_back(j);
+ size += item2->m_dwSize;
+ }
+ else // Sequel
+ {
+ offset = 0;
+ ++expr;
+ break;
+ }
+ }
+ else if (!StringUtils::EqualsNoCase(Ignore1,
+ Ignore2)) // False positive, try again with offset
+ {
+ offset = expr->GetSubStart(3);
+ break;
+ }
+ else // Extension mismatch
+ {
+ offset = 0;
+ ++expr;
+ break;
+ }
+ }
+ else // Title mismatch
+ {
+ offset = 0;
+ ++expr;
+ break;
+ }
+ }
+ else // No match 2, next expression
+ {
+ offset = 0;
+ ++expr;
+ break;
+ }
+ j++;
+ }
+ if (j == Size())
+ expr = stackRegExps.end();
+ }
+ else // No match 1
+ {
+ offset = 0;
+ ++expr;
+ }
+ if (stack.size() > 1)
+ {
+ // have a stack, remove the items and add the stacked item
+ // dont actually stack a multipart rar set, just remove all items but the first
+ std::string stackPath;
+ if (Get(stack[0])->IsRAR())
+ stackPath = Get(stack[0])->GetPath();
+ else
+ {
+ CStackDirectory dir;
+ stackPath = dir.ConstructStackPath(*this, stack);
+ }
+ item1->SetPath(stackPath);
+ // clean up list
+ for (unsigned k = 1; k < stack.size(); k++)
+ Remove(i + 1);
+ // item->m_bIsFolder = true; // don't treat stacked files as folders
+ // the label may be in a different char set from the filename (eg over smb
+ // the label is converted from utf8, but the filename is not)
+ if (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_FILELISTS_SHOWEXTENSIONS))
+ URIUtils::RemoveExtension(stackName);
+
+ item1->SetLabel(stackName);
+ item1->m_dwSize = size;
+ break;
+ }
+ }
+ i++;
+ }
+}
+
+bool CFileItemList::Load(int windowID)
+{
+ CFile file;
+ auto path = GetDiscFileCache(windowID);
+ try
+ {
+ if (file.Open(path))
+ {
+ CArchive ar(&file, CArchive::load);
+ ar >> *this;
+ CLog::Log(LOGDEBUG, "Loading items: {}, directory: {} sort method: {}, ascending: {}", Size(),
+ CURL::GetRedacted(GetPath()), m_sortDescription.sortBy,
+ m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
+ ar.Close();
+ file.Close();
+ return true;
+ }
+ }
+ catch (const std::out_of_range&)
+ {
+ CLog::Log(LOGERROR, "Corrupt archive: {}", CURL::GetRedacted(path));
+ }
+
+ return false;
+}
+
+bool CFileItemList::Save(int windowID)
+{
+ int iSize = Size();
+ if (iSize <= 0)
+ return false;
+
+ CLog::Log(LOGDEBUG, "Saving fileitems [{}]", CURL::GetRedacted(GetPath()));
+
+ CFile file;
+ std::string cachefile = GetDiscFileCache(windowID);
+ if (file.OpenForWrite(cachefile, true)) // overwrite always
+ {
+ // Before caching save simplified cache file name in every item so the cache file can be
+ // identifed and removed if the item is updated. List path and options (used for file
+ // name when list cached) can not be accurately derived from item path.
+ StringUtils::Replace(cachefile, "special://temp/archive_cache/", "");
+ StringUtils::Replace(cachefile, ".fi", "");
+ for (const auto& item : m_items)
+ item->SetProperty("cachefilename", cachefile);
+
+ CArchive ar(&file, CArchive::store);
+ ar << *this;
+ CLog::Log(LOGDEBUG, " -- items: {}, sort method: {}, ascending: {}", iSize,
+ m_sortDescription.sortBy,
+ m_sortDescription.sortOrder == SortOrderAscending ? "true" : "false");
+ ar.Close();
+ file.Close();
+ return true;
+ }
+
+ return false;
+}
+
+void CFileItemList::RemoveDiscCache(int windowID) const
+{
+ RemoveDiscCache(GetDiscFileCache(windowID));
+}
+
+void CFileItemList::RemoveDiscCache(const std::string& cacheFile) const
+{
+ if (CFile::Exists(cacheFile))
+ {
+ CLog::Log(LOGDEBUG, "Clearing cached fileitems [{}]", CURL::GetRedacted(GetPath()));
+ CFile::Delete(cacheFile);
+ }
+}
+
+void CFileItemList::RemoveDiscCacheCRC(const std::string& crc) const
+{
+ std::string cachefile = StringUtils::Format("special://temp/archive_cache/{}.fi", crc);
+ RemoveDiscCache(cachefile);
+}
+
+std::string CFileItemList::GetDiscFileCache(int windowID) const
+{
+ std::string strPath(GetPath());
+ URIUtils::RemoveSlashAtEnd(strPath);
+
+ uint32_t crc = Crc32::ComputeFromLowerCase(strPath);
+
+ if (MUSIC::IsCDDA(*this) || IsOnDVD())
+ return StringUtils::Format("special://temp/archive_cache/r-{:08x}.fi", crc);
+
+ if (MUSIC::IsMusicDb(*this))
+ return StringUtils::Format("special://temp/archive_cache/mdb-{:08x}.fi", crc);
+
+ if (VIDEO::IsVideoDb(*this))
+ return StringUtils::Format("special://temp/archive_cache/vdb-{:08x}.fi", crc);
+
+ if (IsSmartPlayList())
+ return StringUtils::Format("special://temp/archive_cache/sp-{:08x}.fi", crc);
+
+ if (windowID)
+ return StringUtils::Format("special://temp/archive_cache/{}-{:08x}.fi", windowID, crc);
+
+ return StringUtils::Format("special://temp/archive_cache/{:08x}.fi", crc);
+}
+
+bool CFileItemList::AlwaysCache() const
+{
+ // some database folders are always cached
+ if (MUSIC::IsMusicDb(*this))
+ return CMusicDatabaseDirectory::CanCache(GetPath());
+ if (VIDEO::IsVideoDb(*this))
+ return CVideoDatabaseDirectory::CanCache(GetPath());
+ if (IsEPG())
+ return true; // always cache
+ return false;
+}
+
+void CFileItemList::Swap(unsigned int item1, unsigned int item2)
+{
+ if (item1 != item2 && item1 < m_items.size() && item2 < m_items.size())
+ std::swap(m_items[item1], m_items[item2]);
+}
+
+bool CFileItemList::UpdateItem(const CFileItem* item)
+{
+ if (!item)
+ return false;
+
+ std::unique_lock<CCriticalSection> lock(m_lock);
+ for (unsigned int i = 0; i < m_items.size(); i++)
+ {
+ CFileItemPtr pItem = m_items[i];
+ if (pItem->IsSamePath(item))
+ {
+ pItem->UpdateInfo(*item);
+ return true;
+ }
+ }
+ return false;
+}
+
+void CFileItemList::AddSortMethod(SortBy sortBy,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks,
+ SortAttribute sortAttributes /* = SortAttributeNone */)
+{
+ AddSortMethod(sortBy, sortAttributes, buttonLabel, labelMasks);
+}
+
+void CFileItemList::AddSortMethod(SortBy sortBy,
+ SortAttribute sortAttributes,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks)
+{
+ SortDescription sorting;
+ sorting.sortBy = sortBy;
+ sorting.sortAttributes = sortAttributes;
+
+ AddSortMethod(sorting, buttonLabel, labelMasks);
+}
+
+void CFileItemList::AddSortMethod(SortDescription sortDescription,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks)
+{
+ GUIViewSortDetails sort;
+ sort.m_sortDescription = sortDescription;
+ sort.m_buttonLabel = buttonLabel;
+ sort.m_labelMasks = labelMasks;
+
+ m_sortDetails.push_back(sort);
+}
+
+void CFileItemList::SetReplaceListing(bool replace)
+{
+ m_replaceListing = replace;
+}
+
+void CFileItemList::ClearSortState()
+{
+ m_sortDescription.sortBy = SortByNone;
+ m_sortDescription.sortOrder = SortOrderNone;
+ m_sortDescription.sortAttributes = SortAttributeNone;
+}
diff --git a/xbmc/FileItemList.h b/xbmc/FileItemList.h
new file mode 100644
index 0000000000..5f04f179d2
--- /dev/null
+++ b/xbmc/FileItemList.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+/*!
+ \file FileItemList.h
+ \brief
+ */
+
+#include "FileItem.h"
+
+/*!
+ \brief Represents a list of files
+ \sa CFileItemList, CFileItem
+ */
+class CFileItemList : public CFileItem
+{
+public:
+ enum CACHE_TYPE
+ {
+ CACHE_NEVER = 0,
+ CACHE_IF_SLOW,
+ CACHE_ALWAYS
+ };
+
+ CFileItemList();
+ explicit CFileItemList(const std::string& strPath);
+ ~CFileItemList() override;
+ void Archive(CArchive& ar) override;
+ CFileItemPtr operator[](int iItem);
+ const CFileItemPtr operator[](int iItem) const;
+ CFileItemPtr operator[](const std::string& strPath);
+ const CFileItemPtr operator[](const std::string& strPath) const;
+ void Clear();
+ void ClearItems();
+ void Add(CFileItemPtr item);
+ void Add(CFileItem&& item);
+ void AddFront(const CFileItemPtr& pItem, int itemPosition);
+ void Remove(CFileItem* pItem);
+ void Remove(int iItem);
+ CFileItemPtr Get(int iItem) const;
+ const VECFILEITEMS& GetList() const { return m_items; }
+ CFileItemPtr Get(const std::string& strPath) const;
+ int Size() const;
+ bool IsEmpty() const;
+ void Append(const CFileItemList& itemlist);
+ void Assign(const CFileItemList& itemlist, bool append = false);
+ bool Copy(const CFileItemList& item, bool copyItems = true);
+ void Reserve(size_t iCount);
+ void Sort(SortBy sortBy, SortOrder sortOrder, SortAttribute sortAttributes = SortAttributeNone);
+ /* \brief Sorts the items based on the given sorting options
+
+ In contrast to Sort (see above) this does not change the internal
+ state by storing the sorting method and order used and therefore
+ will always execute the sorting even if the list of items has
+ already been sorted with the same options before.
+ */
+ void Sort(SortDescription sortDescription);
+ void Randomize();
+ void FillInDefaultIcons();
+ int GetFolderCount() const;
+ int GetFileCount() const;
+ int GetSelectedCount() const;
+ int GetObjectCount() const;
+ void FilterCueItems();
+ void RemoveExtensions();
+ void SetIgnoreURLOptions(bool ignoreURLOptions);
+ void SetFastLookup(bool fastLookup);
+ bool Contains(const std::string& fileName) const;
+ bool GetFastLookup() const { return m_fastLookup; }
+
+ /*! \brief stack a CFileItemList
+ By default we stack all items (files and folders) in a CFileItemList
+ \param stackFiles whether to stack all items or just collapse folders (defaults to true)
+ \sa StackFiles,StackFolders
+ */
+ void Stack(bool stackFiles = true);
+
+ SortOrder GetSortOrder() const { return m_sortDescription.sortOrder; }
+ SortBy GetSortMethod() const { return m_sortDescription.sortBy; }
+ void SetSortOrder(SortOrder sortOrder) { m_sortDescription.sortOrder = sortOrder; }
+ void SetSortMethod(SortBy sortBy) { m_sortDescription.sortBy = sortBy; }
+
+ /*! \brief load a CFileItemList out of the cache
+
+ The file list may be cached based on which window we're viewing in, as different
+ windows will be listing different portions of the same URL (eg viewing music files
+ versus viewing video files)
+
+ \param windowID id of the window that's loading this list (defaults to 0)
+ \return true if we loaded from the cache, false otherwise.
+ \sa Save,RemoveDiscCache
+ */
+ bool Load(int windowID = 0);
+
+ /*! \brief save a CFileItemList to the cache
+
+ The file list may be cached based on which window we're viewing in, as different
+ windows will be listing different portions of the same URL (eg viewing music files
+ versus viewing video files)
+
+ \param windowID id of the window that's saving this list (defaults to 0)
+ \return true if successful, false otherwise.
+ \sa Load,RemoveDiscCache
+ */
+ bool Save(int windowID = 0);
+ void SetCacheToDisc(CACHE_TYPE cacheToDisc) { m_cacheToDisc = cacheToDisc; }
+ bool CacheToDiscAlways() const { return m_cacheToDisc == CACHE_ALWAYS; }
+ bool CacheToDiscIfSlow() const { return m_cacheToDisc == CACHE_IF_SLOW; }
+ /*! \brief remove a previously cached CFileItemList from the cache
+
+ The file list may be cached based on which window we're viewing in, as different
+ windows will be listing different portions of the same URL (eg viewing music files
+ versus viewing video files)
+
+ \param windowID id of the window whose cache we which to remove (defaults to 0)
+ \sa Save,Load
+ */
+ void RemoveDiscCache(int windowID = 0) const;
+ void RemoveDiscCache(const std::string& cachefile) const;
+ void RemoveDiscCacheCRC(const std::string& crc) const;
+ bool AlwaysCache() const;
+
+ void Swap(unsigned int item1, unsigned int item2);
+
+ /*! \brief Update an item in the item list
+ \param item the new item, which we match based on path to an existing item in the list
+ \return true if the item exists in the list (and was thus updated), false otherwise.
+ */
+ bool UpdateItem(const CFileItem* item);
+
+ void AddSortMethod(SortBy sortBy,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks,
+ SortAttribute sortAttributes = SortAttributeNone);
+ void AddSortMethod(SortBy sortBy,
+ SortAttribute sortAttributes,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks);
+ void AddSortMethod(SortDescription sortDescription,
+ int buttonLabel,
+ const LABEL_MASKS& labelMasks);
+ bool HasSortDetails() const { return m_sortDetails.size() != 0; }
+ const std::vector<GUIViewSortDetails>& GetSortDetails() const { return m_sortDetails; }
+
+ /*! \brief Specify whether this list should be sorted with folders separate from files
+ By default we sort with folders listed (and sorted separately) except for those sort modes
+ which should be explicitly sorted with folders interleaved with files (eg SORT_METHOD_FILES).
+ With this set the folder state will be ignored, allowing folders and files to sort interleaved.
+ \param sort whether to ignore the folder state.
+ */
+ void SetSortIgnoreFolders(bool sort) { m_sortIgnoreFolders = sort; }
+ bool GetReplaceListing() const { return m_replaceListing; }
+ void SetReplaceListing(bool replace);
+ void SetContent(const std::string& content) { m_content = content; }
+ const std::string& GetContent() const { return m_content; }
+
+ void ClearSortState();
+
+ VECFILEITEMS::iterator begin() { return m_items.begin(); }
+ VECFILEITEMS::iterator end() { return m_items.end(); }
+ VECFILEITEMS::iterator erase(VECFILEITEMS::iterator first, VECFILEITEMS::iterator last);
+ VECFILEITEMS::const_iterator begin() const { return m_items.begin(); }
+ VECFILEITEMS::const_iterator end() const { return m_items.end(); }
+ VECFILEITEMS::const_iterator cbegin() const { return m_items.cbegin(); }
+ VECFILEITEMS::const_iterator cend() const { return m_items.cend(); }
+ std::reverse_iterator<VECFILEITEMS::const_iterator> rbegin() const { return m_items.rbegin(); }
+ std::reverse_iterator<VECFILEITEMS::const_iterator> rend() const { return m_items.rend(); }
+
+private:
+ void Sort(FILEITEMLISTCOMPARISONFUNC func);
+ void FillSortFields(FILEITEMFILLFUNC func);
+ std::string GetDiscFileCache(int windowID) const;
+
+ /*!
+ \brief stack files in a CFileItemList
+ \sa Stack
+ */
+ void StackFiles();
+
+ /*!
+ \brief stack folders in a CFileItemList
+ \sa Stack
+ */
+ void StackFolders();
+
+ VECFILEITEMS m_items;
+ MAPFILEITEMS m_map;
+ bool m_ignoreURLOptions = false;
+ bool m_fastLookup = false;
+ SortDescription m_sortDescription;
+ bool m_sortIgnoreFolders = false;
+ CACHE_TYPE m_cacheToDisc = CACHE_IF_SLOW;
+ bool m_replaceListing = false;
+ std::string m_content;
+
+ std::vector<GUIViewSortDetails> m_sortDetails;
+
+ mutable CCriticalSection m_lock;
+};
diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp
index 5a0c79d609..ffca6c0eb7 100644
--- a/xbmc/GUIInfoManager.cpp
+++ b/xbmc/GUIInfoManager.cpp
@@ -1334,6 +1334,15 @@ const infomap weather[] = {{ "isfetched", WEATHER_IS_FETCHED },
/// @skinning_v17 **[New Boolean Condition]** \link System_HasPVRAddon
/// `System.HasPVRAddon`\endlink <p>
/// }
+/// \table_row3{ <b>`System.PVRCount`</b>,
+/// \anchor System_PVRCount
+/// _integer_,
+/// @return Number of PVR clients enabled.
+/// @note If a PVR is enabled but unreachable\, it is still counted.
+/// <p><hr>
+/// @skinning_v22 **[New Integer Value]** \link System_PVRCount `System.PVRCount`\endlink
+/// <p>
+/// }
/// \table_row3{ <b>`System.HasCMS`</b>,
/// \anchor System_HasCMS
/// _boolean_,
@@ -1411,6 +1420,14 @@ const infomap weather[] = {{ "isfetched", WEATHER_IS_FETCHED },
/// @return **True** if Kodi is running on an android device.
/// <p>
/// }
+/// \table_row3{ <b>`System.Platform.WebOS`</b>,
+/// \anchor System_PlatformWebOS
+/// _boolean_,
+/// @return **True** if Kodi is running on a WebOS device.
+/// <p><hr>
+/// @skinning_v21 **[New Boolean Condition]** \link System_PlatformWebOS
+/// `System.Platform.WebOS`\endlink <p>
+/// }
/// \table_row3{ <b>`System.CanPowerDown`</b>,
/// \anchor System_CanPowerDown
/// _boolean_,
@@ -1967,6 +1984,7 @@ const infomap system_labels[] = {
{"hascms", SYSTEM_HAS_CMS},
{"privacypolicy", SYSTEM_PRIVACY_POLICY},
{"haspvraddon", SYSTEM_HAS_PVR_ADDON},
+ {"pvrcount", SYSTEM_PVR_COUNT},
{"addonupdatecount", SYSTEM_ADDON_UPDATE_COUNT},
{"supportscpuusage", SYSTEM_SUPPORTS_CPU_USAGE},
{"supportedhdrtypes", SYSTEM_SUPPORTED_HDR_TYPES},
@@ -6474,7 +6492,6 @@ const infomap container_str[] = {{ "property", CONTAINER_PROPERTY },
/// replaces `ListItem.AddonBroken`.
/// <p>
/// }
-
/// \table_row3{ <b>`ListItem.AddonType`</b>,
/// \anchor ListItem_AddonType
/// _string_,
@@ -6911,6 +6928,14 @@ const infomap container_str[] = {{ "property", CONTAINER_PROPERTY },
/// <p><hr>
/// @skinning_v21 **[New Infolabel]** \link ListItem_SongVideoURL `ListItem.SongVideoURL`\endlink
/// }
+/// \table_row3{ <b>`ListItem.BackendInstanceName`</b>,
+/// \anchor ListItem_BackendInstanceName
+/// _string_,
+/// @return The name used by the PVR client addon instance for the selected item.
+/// <p><hr>
+/// @skinning_v22 **[New Infolabel]** \link ListItem_BackendInstanceName `ListItem.BackendInstanceName`\endlink
+/// <p>
+/// }
/// \table_row3{ <b>`ListItem.VideoWidth`</b>,
/// \anchor ListItem_VideoWidth
/// _string_,
@@ -7174,6 +7199,7 @@ const infomap listitem_labels[]= {{ "thumb", LISTITEM_THUMB },
{ "isvideoextra", LISTITEM_ISVIDEOEXTRA },
{ "videoversionname", LISTITEM_VIDEOVERSION_NAME },
{ "hasvideoextras", LISTITEM_HASVIDEOEXTRAS },
+ { "backendinstancename", LISTITEM_BACKEND_INSTANCE_NAME },
};
// clang-format on
@@ -8186,6 +8212,7 @@ const infomap playlist[] = {{ "length", PLAYLIST_LENGTH },
/// <p>
/// }
///
+// clang-format off
const infomap pvr[] = {{ "isrecording", PVR_IS_RECORDING },
{ "hastimer", PVR_HAS_TIMER },
{ "hastvchannels", PVR_HAS_TV_CHANNELS },
@@ -8265,6 +8292,7 @@ const infomap pvr[] = {{ "isrecording", PVR_IS_RECORDING
{ "timeshiftprogressbufferstart", PVR_TIMESHIFT_PROGRESS_BUFFER_START },
{ "timeshiftprogressbufferend", PVR_TIMESHIFT_PROGRESS_BUFFER_END },
{ "epgeventicon", PVR_EPG_EVENT_ICON }};
+// clang-format on
/// \page modules__infolabels_boolean_conditions
/// \table_row3{ <b>`PVR.EpgEventDuration`</b>,
@@ -10561,6 +10589,8 @@ int CGUIInfoManager::TranslateSingleString(const std::string &strCondition, bool
return SYSTEM_PLATFORM_DARWIN_TVOS;
else if (platform == "android")
return SYSTEM_PLATFORM_ANDROID;
+ else if (platform == "webos")
+ return SYSTEM_PLATFORM_WEBOS;
}
if (info[0].name == "musicplayer")
{ //! @todo these two don't allow duration(foo) and also don't allow more than this number of levels...
diff --git a/xbmc/NfoFile.cpp b/xbmc/NfoFile.cpp
index 2a11da2c17..f74d0efd20 100644
--- a/xbmc/NfoFile.cpp
+++ b/xbmc/NfoFile.cpp
@@ -12,6 +12,7 @@
#include "NfoFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "addons/AddonManager.h"
#include "addons/AddonSystemSettings.h"
diff --git a/xbmc/PartyModeManager.cpp b/xbmc/PartyModeManager.cpp
index 829a9191f5..dd74bad29e 100644
--- a/xbmc/PartyModeManager.cpp
+++ b/xbmc/PartyModeManager.cpp
@@ -9,6 +9,7 @@
#include "PartyModeManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
diff --git a/xbmc/PlayListPlayer.cpp b/xbmc/PlayListPlayer.cpp
index 950a0cd97d..17e198aa76 100644
--- a/xbmc/PlayListPlayer.cpp
+++ b/xbmc/PlayListPlayer.cpp
@@ -9,6 +9,7 @@
#include "PlayListPlayer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
#include "ServiceBroker.h"
@@ -28,6 +29,7 @@
#include "interfaces/AnnouncementManager.h"
#include "messaging/ApplicationMessenger.h"
#include "messaging/helpers/DialogOKHelper.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "playlists/PlayList.h"
#include "settings/AdvancedSettings.h"
@@ -37,9 +39,12 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
using namespace PLAYLIST;
+using namespace KODI;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
CPlayListPlayer::CPlayListPlayer(void)
{
@@ -263,11 +268,13 @@ bool CPlayListPlayer::PlayItemIdx(int itemIdx)
return Play();
}
-bool CPlayListPlayer::Play(const CFileItemPtr& pItem, const std::string& player)
+bool CPlayListPlayer::Play(const CFileItemPtr& pItem,
+ const std::string& player,
+ bool forceSelection /* = false */)
{
Id playlistId;
- bool isVideo{pItem->IsVideo()};
- bool isAudio{pItem->IsAudio()};
+ bool isVideo{IsVideo(*pItem)};
+ bool isAudio{MUSIC::IsAudio(*pItem)};
if (isAudio && !isVideo)
playlistId = TYPE_MUSIC;
@@ -301,13 +308,14 @@ bool CPlayListPlayer::Play(const CFileItemPtr& pItem, const std::string& player)
SetCurrentPlaylist(playlistId);
Add(playlistId, pItem);
- return Play(0, player);
+ return Play(0, player, false, false, forceSelection);
}
bool CPlayListPlayer::Play(int iSong,
const std::string& player,
bool bAutoPlay /* = false */,
- bool bPlayPrevious /* = false */)
+ bool bPlayPrevious /* = false */,
+ bool forceSelection /* = false */)
{
if (m_iCurrentPlayList == TYPE_NONE)
return false;
@@ -331,7 +339,7 @@ bool CPlayListPlayer::Play(int iSong,
m_iCurrentSong = iSong;
CFileItemPtr item = playlist[m_iCurrentSong];
- if (item->IsVideoDb() && !item->HasVideoInfoTag())
+ if (IsVideoDb(*item) && !item->HasVideoInfoTag())
*(item->GetVideoInfoTag()) = XFILE::CVideoDatabaseFile::GetVideoTag(CURL(item->GetDynPath()));
playlist.SetPlayed(true);
@@ -339,7 +347,7 @@ bool CPlayListPlayer::Play(int iSong,
m_bPlaybackStarted = false;
const auto playAttempt = std::chrono::steady_clock::now();
- bool ret = g_application.PlayFile(*item, player, bAutoPlay);
+ bool ret = g_application.PlayFile(*item, player, bAutoPlay, forceSelection);
if (!ret)
{
CLog::Log(LOGERROR, "Playlist Player: skipping unplayable item: {}, path [{}]", m_iCurrentSong,
@@ -949,7 +957,7 @@ void PLAYLIST::CPlayListPlayer::OnApplicationMessage(KODI::MESSAGING::ThreadMess
Id playlistId = TYPE_MUSIC;
for (int i = 0; i < list->Size(); i++)
{
- if ((*list)[i]->IsVideo())
+ if (IsVideo(*list->Get(i)))
{
playlistId = TYPE_VIDEO;
break;
@@ -967,7 +975,7 @@ void PLAYLIST::CPlayListPlayer::OnApplicationMessage(KODI::MESSAGING::ThreadMess
{
return;
}
- if (item->IsAudio() || item->IsVideo())
+ if (MUSIC::IsAudio(*item) || IsVideo(*item))
Play(item, pMsg->strParam);
else
g_application.PlayMedia(*item, pMsg->strParam, playlistId);
diff --git a/xbmc/PlayListPlayer.h b/xbmc/PlayListPlayer.h
index 961aaf28d4..f17abf6280 100644
--- a/xbmc/PlayListPlayer.h
+++ b/xbmc/PlayListPlayer.h
@@ -55,19 +55,22 @@ public:
* \brief Creates a new playlist for an item and starts playing it
* \param pItem The item to play.
* \param player The player name.
+ * \param forceSelection for Blurays, force simple menu to change playlist (default to false)
* \return True if has success, otherwise false.
*/
- bool Play(const CFileItemPtr& pItem, const std::string& player);
+ bool Play(const CFileItemPtr& pItem, const std::string& player, bool forceSelection = false);
/*! \brief Start playing a particular entry in the current playlist
\param index the index of the item to play. This value is modified to ensure it lies within the current playlist.
\param replace whether this item should replace the currently playing item. See CApplication::PlayFile (defaults to false).
\param playPreviousOnFail whether to go back to the previous item if playback fails (default to false)
+ \param forceSelection for Blurays, force simple menu to change playlist (default to false)
*/
bool Play(int index,
const std::string& player,
bool replace = false,
- bool playPreviousOnFail = false);
+ bool playPreviousOnFail = false,
+ bool forceSelection = false);
/*! \brief Returns the index of the current item in active playlist.
\return Current item in the active playlist.
diff --git a/xbmc/SeekHandler.cpp b/xbmc/SeekHandler.cpp
index d686e28326..3e93694b16 100644
--- a/xbmc/SeekHandler.cpp
+++ b/xbmc/SeekHandler.cpp
@@ -19,6 +19,7 @@
#include "guilib/LocalizeStrings.h"
#include "input/actions/Action.h"
#include "input/actions/ActionIDs.h"
+#include "music/MusicFileItemClassify.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -34,6 +35,8 @@
#include <mutex>
#include <stdlib.h>
+using namespace KODI;
+
CSeekHandler::~CSeekHandler()
{
m_seekDelays.clear();
@@ -275,7 +278,8 @@ bool CSeekHandler::OnAction(const CAction &action)
if (!appPlayer->IsPlaying() || !appPlayer->CanSeek())
return false;
- SeekType type = g_application.CurrentFileItem().IsAudio() ? SEEK_TYPE_MUSIC : SEEK_TYPE_VIDEO;
+ SeekType type =
+ MUSIC::IsAudio(g_application.CurrentFileItem()) ? SEEK_TYPE_MUSIC : SEEK_TYPE_VIDEO;
if (SeekTimeCode(action))
return true;
diff --git a/xbmc/URL.cpp b/xbmc/URL.cpp
index 99b661e36f..073d1104e0 100644
--- a/xbmc/URL.cpp
+++ b/xbmc/URL.cpp
@@ -7,15 +7,17 @@
*/
#include "URL.h"
-#include "utils/log.h"
-#include "utils/URIUtils.h"
-#include "utils/StringUtils.h"
+
+#include "FileItem.h"
+#include "FileItemList.h"
+#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/File.h"
-#include "FileItem.h"
#include "filesystem/StackDirectory.h"
#include "network/Network.h"
-#include "ServiceBroker.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "utils/log.h"
#ifndef TARGET_POSIX
#include <sys\stat.h>
#endif
diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp
index a4ee52645c..82cc638bee 100644
--- a/xbmc/Util.cpp
+++ b/xbmc/Util.cpp
@@ -7,6 +7,8 @@
*/
#include "network/Network.h"
+#include "network/NetworkFileItemClassify.h"
+#include "video/VideoFileItemClassify.h"
#if defined(TARGET_DARWIN)
#include <sys/param.h>
#include <mach-o/dyld.h>
@@ -92,6 +94,7 @@ using namespace MEDIA_DETECT;
using namespace XFILE;
using namespace PLAYLIST;
using KODI::UTILITY::CDigest;
+using namespace KODI;
#if !defined(TARGET_WINDOWS)
unsigned int CUtil::s_randomSeed = time(NULL);
@@ -2054,10 +2057,8 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector<st
auto start = std::chrono::steady_clock::now();
CFileItem item(strMovie, false);
- if ((item.IsInternetStream() && !URIUtils::IsOnLAN(item.GetDynPath()))
- || item.IsPlayList()
- || item.IsLiveTV()
- || !item.IsVideo())
+ if ((NETWORK::IsInternetStream(item) && !URIUtils::IsOnLAN(item.GetDynPath())) ||
+ item.IsPlayList() || item.IsLiveTV() || !VIDEO::IsVideo(item))
return;
CLog::Log(LOGDEBUG, "{}: Searching for subtitles...", __FUNCTION__);
@@ -2346,11 +2347,8 @@ std::string CUtil::GetVobSubIdxFromSub(const std::string& vobSub)
void CUtil::ScanForExternalAudio(const std::string& videoPath, std::vector<std::string>& vecAudio)
{
CFileItem item(videoPath, false);
- if ( item.IsInternetStream()
- || item.IsPlayList()
- || item.IsLiveTV()
- || item.IsPVR()
- || !item.IsVideo())
+ if (NETWORK::IsInternetStream(item) || item.IsPlayList() || item.IsLiveTV() || item.IsPVR() ||
+ !VIDEO::IsVideo(item))
return;
std::string strBasePath;
diff --git a/xbmc/addons/AddonManager.cpp b/xbmc/addons/AddonManager.cpp
index 2922b66974..7c69b56425 100644
--- a/xbmc/addons/AddonManager.cpp
+++ b/xbmc/addons/AddonManager.cpp
@@ -10,6 +10,7 @@
#include "CompileInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
#include "addons/AddonBuilder.h"
diff --git a/xbmc/addons/AddonManager.h b/xbmc/addons/AddonManager.h
index 10668125c0..fd7ee70f66 100644
--- a/xbmc/addons/AddonManager.h
+++ b/xbmc/addons/AddonManager.h
@@ -16,6 +16,7 @@
#include <mutex>
#include <set>
#include <string>
+#include <utility>
#include <vector>
namespace ADDON
@@ -37,10 +38,10 @@ using ADDON_INFO_LIST = std::map<std::string, AddonInfoPtr>;
class IAddon;
using AddonPtr = std::shared_ptr<IAddon>;
+using AddonWithUpdate = std::pair<std::shared_ptr<IAddon>, std::shared_ptr<IAddon>>;
using VECADDONS = std::vector<AddonPtr>;
struct AddonEvent;
-struct AddonWithUpdate;
struct DependencyInfo;
struct RepositoryDirInfo;
diff --git a/xbmc/addons/AddonRepos.cpp b/xbmc/addons/AddonRepos.cpp
index 5455ca4487..362f051b97 100644
--- a/xbmc/addons/AddonRepos.cpp
+++ b/xbmc/addons/AddonRepos.cpp
@@ -122,20 +122,16 @@ bool CAddonRepos::LoadAddonsFromDatabase(const std::string& addonId,
{
if (m_addonMgr.IsCompatible(addon))
{
- m_addonsByRepoMap[addon->Origin()].insert({addon->ID(), addon});
+ m_addonsByRepoMap[addon->Origin()].emplace(addon->ID(), addon);
}
}
- for (const auto& repo : m_addonsByRepoMap)
+ for (const auto& [repoId, addonsPerRepo] : m_addonsByRepoMap)
{
- CLog::LogFC(LOGDEBUG, LOGADDONS, "{} - {} addon(s) loaded", repo.first, repo.second.size());
+ CLog::LogFC(LOGDEBUG, LOGADDONS, "{} - {} addon(s) loaded", repoId, addonsPerRepo.size());
- const auto& addonsPerRepo = repo.second;
-
- for (const auto& addonMapEntry : addonsPerRepo)
+ for (const auto& [addonId, addonToAdd] : addonsPerRepo)
{
- const auto& addonToAdd = addonMapEntry.second;
-
if (IsFromOfficialRepo(addonToAdd, CheckAddonPath::CHOICE_YES))
{
AddAddonIfLatest(addonToAdd, m_latestOfficialVersions);
@@ -146,7 +142,7 @@ bool CAddonRepos::LoadAddonsFromDatabase(const std::string& addonId,
}
// add to latestVersionsByRepo
- AddAddonIfLatest(repo.first, addonToAdd, m_latestVersionsByRepo);
+ AddAddonIfLatest(repoId, addonToAdd, m_latestVersionsByRepo);
}
}
@@ -156,8 +152,8 @@ bool CAddonRepos::LoadAddonsFromDatabase(const std::string& addonId,
void CAddonRepos::AddAddonIfLatest(const std::shared_ptr<IAddon>& addonToAdd,
std::map<std::string, std::shared_ptr<IAddon>>& map) const
{
- const auto& latestKnown = map.find(addonToAdd->ID());
- if (latestKnown == map.end() || addonToAdd->Version() > latestKnown->second->Version())
+ const auto latestKnownIt = map.find(addonToAdd->ID());
+ if (latestKnownIt == map.end() || addonToAdd->Version() > latestKnownIt->second->Version())
map[addonToAdd->ID()] = addonToAdd;
}
@@ -166,21 +162,23 @@ void CAddonRepos::AddAddonIfLatest(
const std::shared_ptr<IAddon>& addonToAdd,
std::map<std::string, std::map<std::string, std::shared_ptr<IAddon>>>& map) const
{
- const auto& latestVersionByRepo = map.find(repoId);
+ bool doInsert{true};
- if (latestVersionByRepo == map.end()) // repo not found
- {
- map[repoId].insert({addonToAdd->ID(), addonToAdd});
- }
- else
+ const auto latestVersionByRepoIt = map.find(repoId);
+ if (latestVersionByRepoIt != map.end()) // we already have this repository in the outer map
{
- const auto& latestVersionEntryByRepo = latestVersionByRepo->second;
- const auto& latestKnown = latestVersionEntryByRepo.find(addonToAdd->ID());
+ const auto& latestVersionEntryByRepo = latestVersionByRepoIt->second;
+ const auto latestKnownIt = latestVersionEntryByRepo.find(addonToAdd->ID());
- if (latestKnown == latestVersionEntryByRepo.end() ||
- addonToAdd->Version() > latestKnown->second->Version())
- map[repoId][addonToAdd->ID()] = addonToAdd;
+ if (latestKnownIt != latestVersionEntryByRepo.end() &&
+ addonToAdd->Version() <= latestKnownIt->second->Version())
+ {
+ doInsert = false;
+ }
}
+
+ if (doInsert)
+ map[repoId][addonToAdd->ID()] = addonToAdd;
}
void CAddonRepos::BuildUpdateOrOutdatedList(const std::vector<std::shared_ptr<IAddon>>& installed,
@@ -212,7 +210,7 @@ void CAddonRepos::BuildAddonsWithUpdateList(
{
if (DoAddonUpdateCheck(addon, update))
{
- addonsWithUpdate.insert({addon->ID(), {addon, update}});
+ addonsWithUpdate.try_emplace(addon->ID(), addon, update);
}
}
}
@@ -253,10 +251,10 @@ bool CAddonRepos::DoAddonUpdateCheck(const std::shared_ptr<IAddon>& addon,
else
{
// ...we check for updates in the origin repo only
- const auto& repoEntry = m_latestVersionsByRepo.find(addon->Origin());
- if (repoEntry != m_latestVersionsByRepo.end())
+ const auto repoEntryIt = m_latestVersionsByRepo.find(addon->Origin());
+ if (repoEntryIt != m_latestVersionsByRepo.end())
{
- if (!FindAddonAndCheckForUpdate(addon, repoEntry->second, update))
+ if (!FindAddonAndCheckForUpdate(addon, repoEntryIt->second, update))
{
return false;
}
@@ -280,14 +278,14 @@ bool CAddonRepos::FindAddonAndCheckForUpdate(
const std::map<std::string, std::shared_ptr<IAddon>>& map,
std::shared_ptr<IAddon>& update) const
{
- const auto& remote = map.find(addonToCheck->ID());
- if (remote != map.end()) // is addon in the desired map?
+ const auto remoteIt = map.find(addonToCheck->ID());
+ if (remoteIt != map.end()) // is addon in the desired map?
{
- if ((remote->second->Version() > addonToCheck->Version()) ||
+ if ((remoteIt->second->Version() > addonToCheck->Version()) ||
m_addonMgr.IsAddonDisabledWithReason(addonToCheck->ID(), AddonDisabledReason::INCOMPATIBLE))
{
// return addon update
- update = remote->second;
+ update = remoteIt->second;
return true; // update found
}
}
@@ -300,10 +298,10 @@ bool CAddonRepos::GetLatestVersionByMap(const std::string& addonId,
const std::map<std::string, std::shared_ptr<IAddon>>& map,
std::shared_ptr<IAddon>& addon) const
{
- const auto& remote = map.find(addonId);
- if (remote != map.end()) // is addon in the desired map?
+ const auto remoteIt = map.find(addonId);
+ if (remoteIt != map.end()) // is addon in the desired map?
{
- addon = remote->second;
+ addon = remoteIt->second;
return true;
}
@@ -356,14 +354,15 @@ void CAddonRepos::GetLatestAddonVersions(std::vector<std::shared_ptr<IAddon>>& a
// then we insert private addon versions if they don't exist in the official map
// or installation from ANY_REPOSITORY is allowed and the private version is higher
- for (const auto& privateVersion : m_latestPrivateVersions)
+ for (const auto& [privateVersionId, privateVersion] : m_latestPrivateVersions)
{
- const auto& officialVersion = m_latestOfficialVersions.find(privateVersion.first);
- if (officialVersion == m_latestOfficialVersions.end() ||
+ const auto officialVersionIt = m_latestOfficialVersions.find(privateVersionId);
+
+ if (officialVersionIt == m_latestOfficialVersions.end() ||
(updateMode == AddonRepoUpdateMode::ANY_REPOSITORY &&
- privateVersion.second->Version() > officialVersion->second->Version()))
+ privateVersion->Version() > officialVersionIt->second->Version()))
{
- addonList.emplace_back(privateVersion.second);
+ addonList.emplace_back(privateVersion);
}
}
}
@@ -390,18 +389,18 @@ void CAddonRepos::GetLatestAddonVersionsFromAllRepos(
// so we need to filter them out
if (std::none_of(officialRepoInfos.begin(), officialRepoInfos.end(),
- [&](const ADDON::RepoInfo& officialRepo) {
- return repo.first == officialRepo.m_repoId;
- }))
+ [&repo](const ADDON::RepoInfo& officialRepo)
+ { return repo.first == officialRepo.m_repoId; }))
{
- for (const auto& latestAddon : repo.second)
+ for (const auto& [latestAddonId, latestAddon] : repo.second)
{
- const auto& officialVersion = m_latestOfficialVersions.find(latestAddon.first);
- if (officialVersion == m_latestOfficialVersions.end() ||
+ const auto officialVersionIt = m_latestOfficialVersions.find(latestAddonId);
+
+ if (officialVersionIt == m_latestOfficialVersions.end() ||
(updateMode == AddonRepoUpdateMode::ANY_REPOSITORY &&
- latestAddon.second->Version() > officialVersion->second->Version()))
+ latestAddon->Version() > officialVersionIt->second->Version()))
{
- addonList.emplace_back(latestAddon.second);
+ addonList.emplace_back(latestAddon);
}
}
}
@@ -469,10 +468,10 @@ bool CAddonRepos::FindDependencyByParentRepo(const std::string& dependsId,
const std::string& parentRepoId,
std::shared_ptr<IAddon>& dependencyToInstall) const
{
- const auto& repoEntry = m_latestVersionsByRepo.find(parentRepoId);
- if (repoEntry != m_latestVersionsByRepo.end())
+ const auto repoEntryIt = m_latestVersionsByRepo.find(parentRepoId);
+ if (repoEntryIt != m_latestVersionsByRepo.end())
{
- if (GetLatestVersionByMap(dependsId, repoEntry->second, dependencyToInstall))
+ if (GetLatestVersionByMap(dependsId, repoEntryIt->second, dependencyToInstall))
return true;
}
diff --git a/xbmc/addons/AddonRepos.h b/xbmc/addons/AddonRepos.h
index bb9be3473c..4284674f01 100644
--- a/xbmc/addons/AddonRepos.h
+++ b/xbmc/addons/AddonRepos.h
@@ -13,6 +13,7 @@
#include <map>
#include <memory>
#include <string>
+#include <utility>
#include <vector>
namespace ADDON
@@ -30,14 +31,7 @@ enum class CheckAddonPath
CHOICE_NO = false,
};
-/**
- * Struct - CAddonWithUpdate
- */
-struct AddonWithUpdate
-{
- std::shared_ptr<IAddon> m_installed;
- std::shared_ptr<IAddon> m_update;
-};
+using AddonWithUpdate = std::pair<std::shared_ptr<IAddon>, std::shared_ptr<IAddon>>;
/**
* Class - CAddonRepos
diff --git a/xbmc/addons/FilesystemInstaller.cpp b/xbmc/addons/FilesystemInstaller.cpp
index 0f7b32de64..f6dd80131a 100644
--- a/xbmc/addons/FilesystemInstaller.cpp
+++ b/xbmc/addons/FilesystemInstaller.cpp
@@ -8,6 +8,7 @@
#include "FilesystemInstaller.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "filesystem/File.h"
#include "filesystem/SpecialProtocol.h"
diff --git a/xbmc/addons/Scraper.cpp b/xbmc/addons/Scraper.cpp
index 66cedcb969..23e4b4fcf9 100644
--- a/xbmc/addons/Scraper.cpp
+++ b/xbmc/addons/Scraper.cpp
@@ -9,6 +9,7 @@
#include "Scraper.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
@@ -45,8 +46,8 @@
#include <fstrcmp.h>
using namespace XFILE;
+using namespace KODI;
using namespace MUSIC_GRABBER;
-using namespace VIDEO;
namespace ADDON
{
@@ -1250,9 +1251,9 @@ std::vector<CMusicArtistInfo> CScraper::FindArtist(CCurlFile &fcurl, const std::
}
// fetch list of episodes from URL (from video database)
-EPISODELIST CScraper::GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl)
+VIDEO::EPISODELIST CScraper::GetEpisodeList(XFILE::CCurlFile& fcurl, const CScraperUrl& scurl)
{
- EPISODELIST vcep;
+ VIDEO::EPISODELIST vcep;
if (!scurl.HasUrls())
return vcep;
@@ -1275,7 +1276,7 @@ EPISODELIST CScraper::GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl
for (int i = 0; i < items.Size(); ++i)
{
- EPISODE ep;
+ VIDEO::EPISODE ep;
const auto& tag = *items[i]->GetVideoInfoTag();
ep.strTitle = tag.m_strTitle;
ep.iSeason = tag.m_iSeason;
@@ -1311,7 +1312,7 @@ EPISODELIST CScraper::GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl
for (TiXmlElement *pxeMovie = xhDoc.FirstChild("episodeguide").FirstChild("episode").Element();
pxeMovie; pxeMovie = pxeMovie->NextSiblingElement())
{
- EPISODE ep;
+ VIDEO::EPISODE ep;
TiXmlElement *pxeLink = pxeMovie->FirstChildElement("url");
std::string strEpNum;
if (pxeLink && XMLUtils::GetInt(pxeMovie, "season", ep.iSeason) &&
diff --git a/xbmc/addons/Scraper.h b/xbmc/addons/Scraper.h
index 93d34be3d8..d09a4e082c 100644
--- a/xbmc/addons/Scraper.h
+++ b/xbmc/addons/Scraper.h
@@ -129,7 +129,7 @@ public:
const std::string &sAlbum, const std::string &sArtist = "");
std::vector<MUSIC_GRABBER::CMusicArtistInfo> FindArtist(
XFILE::CCurlFile &fcurl, const std::string &sArtist);
- VIDEO::EPISODELIST GetEpisodeList(XFILE::CCurlFile &fcurl, const CScraperUrl &scurl);
+ KODI::VIDEO::EPISODELIST GetEpisodeList(XFILE::CCurlFile& fcurl, const CScraperUrl& scurl);
bool GetVideoDetails(XFILE::CCurlFile& fcurl,
const std::unordered_map<std::string, std::string>& uniqueIDs,
diff --git a/xbmc/addons/Skin.cpp b/xbmc/addons/Skin.cpp
index a6192d902b..746800776c 100644
--- a/xbmc/addons/Skin.cpp
+++ b/xbmc/addons/Skin.cpp
@@ -9,6 +9,7 @@
#include "Skin.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "addons/addoninfo/AddonType.h"
diff --git a/xbmc/addons/VFSEntry.h b/xbmc/addons/VFSEntry.h
index c11fca05da..414f9593af 100644
--- a/xbmc/addons/VFSEntry.h
+++ b/xbmc/addons/VFSEntry.h
@@ -8,6 +8,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "addons/binary-addons/AddonDll.h"
#include "addons/binary-addons/AddonInstanceHandler.h"
#include "addons/kodi-dev-kit/include/kodi/addon-instance/VFS.h"
diff --git a/xbmc/addons/addoninfo/AddonInfo.cpp b/xbmc/addons/addoninfo/AddonInfo.cpp
index f891e73bc9..0f2f7fba5f 100644
--- a/xbmc/addons/addoninfo/AddonInfo.cpp
+++ b/xbmc/addons/addoninfo/AddonInfo.cpp
@@ -9,6 +9,7 @@
#include "AddonInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/addons/gui/GUIDialogAddonInfo.cpp b/xbmc/addons/gui/GUIDialogAddonInfo.cpp
index 671e55dcf4..172af8b216 100644
--- a/xbmc/addons/gui/GUIDialogAddonInfo.cpp
+++ b/xbmc/addons/gui/GUIDialogAddonInfo.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogAddonInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "Util.h"
diff --git a/xbmc/addons/gui/GUIDialogAddonSettings.cpp b/xbmc/addons/gui/GUIDialogAddonSettings.cpp
index 4830283e4d..60cbaa2a2e 100644
--- a/xbmc/addons/gui/GUIDialogAddonSettings.cpp
+++ b/xbmc/addons/gui/GUIDialogAddonSettings.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogAddonSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
diff --git a/xbmc/addons/gui/GUIViewStateAddonBrowser.cpp b/xbmc/addons/gui/GUIViewStateAddonBrowser.cpp
index 5504f33ecd..7ecb3cbcf8 100644
--- a/xbmc/addons/gui/GUIViewStateAddonBrowser.cpp
+++ b/xbmc/addons/gui/GUIViewStateAddonBrowser.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateAddonBrowser.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/File.h"
#include "guilib/WindowIDs.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/addons/gui/GUIWindowAddonBrowser.cpp b/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
index f130bacad1..880e784835 100644
--- a/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
+++ b/xbmc/addons/gui/GUIWindowAddonBrowser.cpp
@@ -10,6 +10,7 @@
#include "ContextMenuManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogAddonInfo.h"
#include "GUIUserMessages.h"
#include "LangInfo.h"
diff --git a/xbmc/addons/interfaces/Filesystem.cpp b/xbmc/addons/interfaces/Filesystem.cpp
index c063b48fd6..9f22b67ecc 100644
--- a/xbmc/addons/interfaces/Filesystem.cpp
+++ b/xbmc/addons/interfaces/Filesystem.cpp
@@ -9,6 +9,7 @@
#include "Filesystem.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "Util.h"
#include "addons/binary-addons/AddonDll.h"
#include "filesystem/CurlFile.h"
diff --git a/xbmc/addons/interfaces/gui/Window.cpp b/xbmc/addons/interfaces/gui/Window.cpp
index b817d443a3..831b89fdbd 100644
--- a/xbmc/addons/interfaces/gui/Window.cpp
+++ b/xbmc/addons/interfaces/gui/Window.cpp
@@ -9,6 +9,7 @@
#include "addons/kodi-dev-kit/include/kodi/gui/Window.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUITranslator.h"
#include "General.h"
#include "ServiceBroker.h"
diff --git a/xbmc/addons/settings/AddonSettings.cpp b/xbmc/addons/settings/AddonSettings.cpp
index 2fc9f26fae..b3bd9bb124 100644
--- a/xbmc/addons/settings/AddonSettings.cpp
+++ b/xbmc/addons/settings/AddonSettings.cpp
@@ -9,6 +9,7 @@
#include "AddonSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
diff --git a/xbmc/application/AppParamParser.cpp b/xbmc/application/AppParamParser.cpp
index ca9cd2acef..20b54e7869 100644
--- a/xbmc/application/AppParamParser.cpp
+++ b/xbmc/application/AppParamParser.cpp
@@ -10,6 +10,7 @@
#include "CompileInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "application/AppParams.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/application/AppParams.cpp b/xbmc/application/AppParams.cpp
index 97c09e3934..8b174467b4 100644
--- a/xbmc/application/AppParams.cpp
+++ b/xbmc/application/AppParams.cpp
@@ -8,12 +8,14 @@
#include "AppParams.h"
-#include "FileItem.h"
+#include "FileItemList.h"
CAppParams::CAppParams() : m_playlist(std::make_unique<CFileItemList>())
{
}
+CAppParams::~CAppParams() = default;
+
void CAppParams::SetRawArgs(std::vector<std::string> args)
{
m_rawArgs = std::move(args);
diff --git a/xbmc/application/AppParams.h b/xbmc/application/AppParams.h
index 6999249719..12d7aba2b9 100644
--- a/xbmc/application/AppParams.h
+++ b/xbmc/application/AppParams.h
@@ -21,7 +21,7 @@ class CAppParams
{
public:
CAppParams();
- virtual ~CAppParams() = default;
+ virtual ~CAppParams();
int GetLogLevel() const { return m_logLevel; }
void SetLogLevel(int logLevel) { m_logLevel = logLevel; }
diff --git a/xbmc/application/Application.cpp b/xbmc/application/Application.cpp
index 3413a18c4c..1f5c65f64e 100644
--- a/xbmc/application/Application.cpp
+++ b/xbmc/application/Application.cpp
@@ -60,6 +60,9 @@
#include "filesystem/DirectoryFactory.h"
#include "filesystem/DllLibCurl.h"
#include "filesystem/File.h"
+#include "music/MusicFileItemClassify.h"
+#include "network/NetworkFileItemClassify.h"
+#include "video/VideoFileItemClassify.h"
#ifdef HAS_FILESYSTEM_NFS
#include "filesystem/NFSFile.h"
#endif
@@ -190,7 +193,6 @@ using namespace XFILE;
#ifdef HAS_OPTICAL_DRIVE
using namespace MEDIA_DETECT;
#endif
-using namespace VIDEO;
using namespace MUSIC_INFO;
using namespace EVENTSERVER;
using namespace JSONRPC;
@@ -808,7 +810,16 @@ void CApplication::Render()
return;
// render gui layer
- if (appPower->GetRenderGUI() && !m_skipGuiRender)
+ const bool renderGUI = appPower->GetRenderGUI();
+ if (m_guiRenderLastState != std::nullopt && renderGUI && m_guiRenderLastState != renderGUI)
+ {
+ CGUIComponent* gui = CServiceBroker::GetGUI();
+ if (gui)
+ CServiceBroker::GetGUI()->GetWindowManager().MarkDirty();
+ }
+ m_guiRenderLastState = renderGUI;
+
+ if (renderGUI && !m_skipGuiRender)
{
if (CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode())
{
@@ -2188,7 +2199,7 @@ bool CApplication::PlayMedia(CFileItem& item, const std::string& player, PLAYLIS
return ProcessAndStartPlaylist(smartpl.GetName(), playlist, smartplPlaylistId);
}
}
- else if (item.IsPlayList() || item.IsInternetStream())
+ else if (item.IsPlayList() || NETWORK::IsInternetStream(item))
{
// Not owner. Dialog auto-deletes itself.
CGUIDialogCache* dlgCache =
@@ -2284,7 +2295,10 @@ bool CApplication::PlayStack(CFileItem& item, bool bRestart)
return PlayFile(selectedStackPart, "", true);
}
-bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRestart)
+bool CApplication::PlayFile(CFileItem item,
+ const std::string& player,
+ bool bRestart /* = false */,
+ bool forceSelection /* = false */)
{
// Ensure the MIME type has been retrieved for http:// and shout:// streams
if (item.GetMimeType().empty())
@@ -2301,11 +2315,11 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
m_nextPlaylistItem = -1;
stackHelper->Clear();
- if (item.IsVideo())
+ if (VIDEO::IsVideo(item))
CUtil::ClearSubtitles();
}
- if (item.IsDiscStub())
+ if (VIDEO::IsDiscStub(item))
{
return CServiceBroker::GetMediaManager().playStubFile(item);
}
@@ -2346,7 +2360,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
{
// the following code block is only applicable when bRestart is false OR to ISO stacks
- if (item.IsVideo())
+ if (VIDEO::IsVideo(item))
{
// open the d/b and retrieve the bookmarks for the current movie
CVideoDatabase dbs;
@@ -2354,7 +2368,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
std::string path = item.GetPath();
std::string videoInfoTagPath(item.GetVideoInfoTag()->m_strFileNameAndPath);
- if (videoInfoTagPath.find("removable://") == 0 || item.IsVideoDb())
+ if (videoInfoTagPath.find("removable://") == 0 || VIDEO::IsVideoDb(item))
path = videoInfoTagPath;
// Note that we need to load the tag from database also if the item already has a tag,
@@ -2424,7 +2438,8 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
// a disc image might be Blu-Ray disc
if (!(options.startpercent > 0.0 || options.starttime > 0.0) &&
- (item.IsBDFile() || item.IsDiscImage()))
+ (VIDEO::IsBDFile(item) || item.IsDiscImage() ||
+ (forceSelection && VIDEO::IsBlurayPlaylist(item))))
{
// No video selection when using external or remote players (they handle it if supported)
const bool isSimpleMenuAllowed = [&]()
@@ -2442,7 +2457,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
if (isSimpleMenuAllowed)
{
// Check if we must show the simplified bd menu.
- if (!CGUIDialogSimpleMenu::ShowPlaySelection(item))
+ if (!CGUIDialogSimpleMenu::ShowPlaySelection(item, forceSelection))
return true;
}
}
@@ -2450,7 +2465,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
// this really aught to be inside !bRestart, but since PlayStack
// uses that to init playback, we have to keep it outside
const PLAYLIST::Id playlistId = CServiceBroker::GetPlaylistPlayer().GetCurrentPlaylist();
- if (item.IsAudio() && playlistId == PLAYLIST::TYPE_MUSIC)
+ if (MUSIC::IsAudio(item) && playlistId == PLAYLIST::TYPE_MUSIC)
{ // playing from a playlist by the looks
// don't switch to fullscreen if we are not playing the first item...
options.fullscreen = !CServiceBroker::GetPlaylistPlayer().HasPlayedFirstFile() &&
@@ -2458,7 +2473,7 @@ bool CApplication::PlayFile(CFileItem item, const std::string& player, bool bRes
CSettings::SETTING_MUSICFILES_SELECTACTION) &&
!CMediaSettings::GetInstance().DoesMediaStartWindowed();
}
- else if (item.IsVideo() && playlistId == PLAYLIST::TYPE_VIDEO &&
+ else if (VIDEO::IsVideo(item) && playlistId == PLAYLIST::TYPE_VIDEO &&
CServiceBroker::GetPlaylistPlayer().GetPlaylist(playlistId).size() > 1)
{ // playing from a playlist by the looks
// don't switch to fullscreen if we are not playing the first item...
@@ -2568,7 +2583,7 @@ void CApplication::PlaybackCleanup()
// DVD ejected while playing in vis ?
if (!appPlayer->IsPlayingAudio() &&
- (m_itemCurrentFile->IsCDDA() || m_itemCurrentFile->IsOnDVD()) &&
+ (MUSIC::IsCDDA(*m_itemCurrentFile) || m_itemCurrentFile->IsOnDVD()) &&
!CServiceBroker::GetMediaManager().IsDiscInDrive() &&
CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_VISUALISATION)
{
@@ -2783,9 +2798,9 @@ bool CApplication::OnMessage(CGUIMessage& message)
bool bNothingToQueue = false;
const auto appPlayer = GetComponent<CApplicationPlayer>();
- if (!file.IsVideo() && appPlayer->IsPlayingVideo())
+ if (!VIDEO::IsVideo(file) && appPlayer->IsPlayingVideo())
bNothingToQueue = true;
- else if ((!file.IsAudio() || file.IsVideo()) && appPlayer->IsPlayingAudio())
+ else if ((!MUSIC::IsAudio(file) || VIDEO::IsVideo(file)) && appPlayer->IsPlayingAudio())
bNothingToQueue = true;
if (bNothingToQueue)
@@ -3053,7 +3068,7 @@ bool CApplication::ExecuteXBMCAction(std::string actionStr,
}
else
#endif
- if (item.IsAudio() || item.IsVideo() || item.IsGame())
+ if (MUSIC::IsAudio(item) || VIDEO::IsVideo(item) || item.IsGame())
{ // an audio or video file
PlayFile(item, "");
}
@@ -3174,10 +3189,8 @@ void CApplication::ProcessSlow()
// Temporarily pause pausable jobs when viewing video/picture
int currentWindow = CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow();
- if (CurrentFileItem().IsVideo() ||
- CurrentFileItem().IsPicture() ||
- currentWindow == WINDOW_FULLSCREEN_VIDEO ||
- currentWindow == WINDOW_FULLSCREEN_GAME ||
+ if (VIDEO::IsVideo(CurrentFileItem()) || CurrentFileItem().IsPicture() ||
+ currentWindow == WINDOW_FULLSCREEN_VIDEO || currentWindow == WINDOW_FULLSCREEN_GAME ||
currentWindow == WINDOW_SLIDESHOW)
{
CServiceBroker::GetJobManager()->PauseJobs();
diff --git a/xbmc/application/Application.h b/xbmc/application/Application.h
index e06df1cc26..b3eaeb5bd4 100644
--- a/xbmc/application/Application.h
+++ b/xbmc/application/Application.h
@@ -24,6 +24,7 @@
#include <atomic>
#include <chrono>
#include <memory>
+#include <optional>
#include <string>
#include <vector>
@@ -69,7 +70,7 @@ namespace ActiveAE
class CActiveAE;
}
-namespace VIDEO
+namespace KODI::VIDEO
{
class CVideoInfoScanner;
}
@@ -125,7 +126,10 @@ public:
PLAYLIST::CPlayList& playlist,
PLAYLIST::Id playlistId,
int track = 0);
- bool PlayFile(CFileItem item, const std::string& player, bool bRestart = false);
+ bool PlayFile(CFileItem item,
+ const std::string& player,
+ bool bRestart = false,
+ bool forceSelection = false);
void StopPlaying();
void Restart(bool bSamePosition = true);
void DelayedPlayerRestart();
@@ -215,6 +219,7 @@ protected:
std::chrono::time_point<std::chrono::steady_clock> m_lastRenderTime;
bool m_skipGuiRender = false;
+ std::optional<bool> m_guiRenderLastState;
std::unique_ptr<MUSIC_INFO::CMusicInfoScanner> m_musicInfoScanner;
diff --git a/xbmc/application/ApplicationPlayer.cpp b/xbmc/application/ApplicationPlayer.cpp
index b517c78fd0..d088f46b6a 100644
--- a/xbmc/application/ApplicationPlayer.cpp
+++ b/xbmc/application/ApplicationPlayer.cpp
@@ -17,9 +17,11 @@
#include "guilib/GUIWindowManager.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingsComponent.h"
+#include "video/VideoFileItemClassify.h"
#include <mutex>
+using namespace KODI;
using namespace std::chrono_literals;
std::shared_ptr<const IPlayer> CApplicationPlayer::GetInternal() const
@@ -99,7 +101,7 @@ bool CApplicationPlayer::OpenFile(const CFileItem& item, const CPlayerOptions& o
{
bool needToClose = false;
- if (item.IsDiscImage() || item.IsDVDFile())
+ if (item.IsDiscImage() || VIDEO::IsDVDFile(item))
needToClose = true;
if (player->m_name != newPlayer)
diff --git a/xbmc/application/ApplicationPlayerCallback.cpp b/xbmc/application/ApplicationPlayerCallback.cpp
index ed36a27e18..955de21f34 100644
--- a/xbmc/application/ApplicationPlayerCallback.cpp
+++ b/xbmc/application/ApplicationPlayerCallback.cpp
@@ -21,8 +21,9 @@
#include "guilib/GUIWindowManager.h"
#include "guilib/StereoscopicsManager.h"
#include "interfaces/AnnouncementManager.h"
-#include "interfaces/json-rpc/JSONUtils.h"
#include "interfaces/python/XBPython.h"
+#include "music/MusicFileItemClassify.h"
+#include "network/NetworkFileItemClassify.h"
#include "profiles/ProfileManager.h"
#include "settings/AdvancedSettings.h"
#include "settings/MediaSettings.h"
@@ -32,10 +33,13 @@
#include "utils/URIUtils.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include <memory>
+using namespace KODI;
+
CApplicationPlayerCallback::CApplicationPlayerCallback()
{
}
@@ -54,8 +58,9 @@ void CApplicationPlayerCallback::OnPlayBackStarted(const CFileItem& file)
std::shared_ptr<CFileItem> itemCurrentFile;
// check if VideoPlayer should set file item stream details from its current streams
- const bool isBlu_dvd_image_or_stream = (URIUtils::IsBluray(file.GetPath()) || file.IsDVDFile() ||
- file.IsDiscImage() || file.IsInternetStream());
+ const bool isBlu_dvd_image_or_stream = URIUtils::IsBluray(file.GetPath()) ||
+ VIDEO::IsDVDFile(file) || file.IsDiscImage() ||
+ NETWORK::IsInternetStream(file);
const bool hasNoStreamDetails =
(!file.HasVideoInfoTag() || !file.GetVideoInfoTag()->HasStreamDetails());
@@ -80,7 +85,7 @@ void CApplicationPlayerCallback::OnPlayBackStarted(const CFileItem& file)
* This should speed up player startup for files on internet filesystems (eg. webdav) and
* increase performance on low powered systems (Atom/ARM).
*/
- if (file.IsVideo() || file.IsGame())
+ if (VIDEO::IsVideo(file) || file.IsGame())
{
CServiceBroker::GetJobManager()->PauseJobs();
}
@@ -126,9 +131,9 @@ void CApplicationPlayerCallback::OnPlayerCloseFile(const CFileItem& file,
const std::shared_ptr<CAdvancedSettings> advancedSettings =
CServiceBroker::GetSettingsComponent()->GetAdvancedSettings();
- if ((fileItem.IsAudio() && advancedSettings->m_audioPlayCountMinimumPercent > 0 &&
+ if ((MUSIC::IsAudio(fileItem) && advancedSettings->m_audioPlayCountMinimumPercent > 0 &&
percent >= advancedSettings->m_audioPlayCountMinimumPercent) ||
- (fileItem.IsVideo() && advancedSettings->m_videoPlayCountMinimumPercent > 0 &&
+ (VIDEO::IsVideo(fileItem) && advancedSettings->m_videoPlayCountMinimumPercent > 0 &&
percent >= advancedSettings->m_videoPlayCountMinimumPercent))
{
playCountUpdate = true;
diff --git a/xbmc/application/ApplicationPowerHandling.cpp b/xbmc/application/ApplicationPowerHandling.cpp
index 4354b9b626..8000a7ee9e 100644
--- a/xbmc/application/ApplicationPowerHandling.cpp
+++ b/xbmc/application/ApplicationPowerHandling.cpp
@@ -67,12 +67,6 @@ void CApplicationPowerHandling::ResetNavigationTimer()
void CApplicationPowerHandling::SetRenderGUI(bool renderGUI)
{
- if (renderGUI && !m_renderGUI)
- {
- CGUIComponent* gui = CServiceBroker::GetGUI();
- if (gui)
- CServiceBroker::GetGUI()->GetWindowManager().MarkDirty();
- }
m_renderGUI = renderGUI;
}
diff --git a/xbmc/application/ApplicationSkinHandling.cpp b/xbmc/application/ApplicationSkinHandling.cpp
index bf73f14363..5f916060ac 100644
--- a/xbmc/application/ApplicationSkinHandling.cpp
+++ b/xbmc/application/ApplicationSkinHandling.cpp
@@ -9,6 +9,7 @@
#include "ApplicationSkinHandling.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUILargeTextureManager.h"
#include "GUIUserMessages.h"
diff --git a/xbmc/application/ApplicationStackHelper.cpp b/xbmc/application/ApplicationStackHelper.cpp
index 27b7808a2a..515c52b5aa 100644
--- a/xbmc/application/ApplicationStackHelper.cpp
+++ b/xbmc/application/ApplicationStackHelper.cpp
@@ -9,6 +9,7 @@
#include "ApplicationStackHelper.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "Util.h"
#include "cores/VideoPlayer/DVDFileInfo.h"
diff --git a/xbmc/cdrip/CDDARipJob.cpp b/xbmc/cdrip/CDDARipJob.cpp
index 61726a5c42..3063a91e65 100644
--- a/xbmc/cdrip/CDDARipJob.cpp
+++ b/xbmc/cdrip/CDDARipJob.cpp
@@ -22,6 +22,7 @@
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
+#include "network/NetworkFileItemClassify.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -37,6 +38,7 @@
using namespace ADDON;
using namespace MUSIC_INFO;
using namespace XFILE;
+using namespace KODI;
using namespace KODI::CDRIP;
CCDDARipJob::CCDDARipJob(const std::string& input,
@@ -66,7 +68,7 @@ bool CCDDARipJob::DoWork()
// if we are ripping to a samba share, rip it to hd first and then copy it to the share
CFileItem file(m_output, false);
- if (file.IsRemote())
+ if (NETWORK::IsRemote(file))
m_output = SetupTempFile();
if (m_output.empty())
@@ -115,7 +117,7 @@ bool CCDDARipJob::DoWork()
encoder.reset();
reader.Close();
- if (file.IsRemote() && !cancelled && result == 2)
+ if (NETWORK::IsRemote(file) && !cancelled && result == 2)
{
// copy the ripped track to the share
if (!CFile::Copy(m_output, file.GetPath()))
diff --git a/xbmc/cdrip/CDDARipper.cpp b/xbmc/cdrip/CDDARipper.cpp
index 41dcc8d5d6..b174c8bbd3 100644
--- a/xbmc/cdrip/CDDARipper.cpp
+++ b/xbmc/cdrip/CDDARipper.cpp
@@ -10,6 +10,7 @@
#include "CDDARipJob.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/cores/AudioEngine/CMakeLists.txt b/xbmc/cores/AudioEngine/CMakeLists.txt
index bc57f3620c..debf3dd203 100644
--- a/xbmc/cores/AudioEngine/CMakeLists.txt
+++ b/xbmc/cores/AudioEngine/CMakeLists.txt
@@ -14,7 +14,8 @@ set(SOURCES AEResampleFactory.cpp
Utils/AELimiter.cpp
Utils/AEPackIEC61937.cpp
Utils/AEStreamInfo.cpp
- Utils/AEUtil.cpp)
+ Utils/AEUtil.cpp
+ Utils/PackerMAT.cpp)
set(HEADERS AEResampleFactory.h
AESinkFactory.h
@@ -44,7 +45,8 @@ set(HEADERS AEResampleFactory.h
Utils/AERingBuffer.h
Utils/AEStreamData.h
Utils/AEStreamInfo.h
- Utils/AEUtil.h)
+ Utils/AEUtil.h
+ Utils/PackerMAT.h)
if(TARGET ALSA::ALSA)
list(APPEND SOURCES Sinks/AESinkALSA.cpp
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
index 908b087b98..528822ddbb 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp
@@ -1313,7 +1313,7 @@ void CActiveAE::Configure(AEAudioFormat *desiredFmt)
format.m_streamInfo.m_type = CAEStreamInfo::STREAM_TYPE_AC3;
format.m_streamInfo.m_channels = 2;
format.m_streamInfo.m_sampleRate = 48000;
- format.m_streamInfo.m_ac3FrameSize = m_encoderFormat.m_frames;
+ format.m_streamInfo.m_frameSize = m_encoderFormat.m_frames;
//! @todo implement
if (m_encoderBuffers && initSink)
{
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
index 02c8eb1b83..e897cbd3ea 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
@@ -148,21 +148,21 @@ bool CActiveAEResampleFFMPEG::Init(SampleConfig dstConfig, SampleConfig srcConfi
AVChannel outChan = av_channel_layout_channel_from_index(&dstChLayout, out);
switch (outChan)
{
- case AV_CH_FRONT_LEFT:
- case AV_CH_BACK_LEFT:
- case AV_CH_SIDE_LEFT:
+ case AV_CHAN_FRONT_LEFT:
+ case AV_CHAN_BACK_LEFT:
+ case AV_CHAN_SIDE_LEFT:
m_rematrix[out][0] = 1.0;
break;
- case AV_CH_FRONT_RIGHT:
- case AV_CH_BACK_RIGHT:
- case AV_CH_SIDE_RIGHT:
+ case AV_CHAN_FRONT_RIGHT:
+ case AV_CHAN_BACK_RIGHT:
+ case AV_CHAN_SIDE_RIGHT:
m_rematrix[out][1] = 1.0;
break;
- case AV_CH_FRONT_CENTER:
+ case AV_CHAN_FRONT_CENTER:
m_rematrix[out][0] = 0.5;
m_rematrix[out][1] = 0.5;
break;
- case AV_CH_LOW_FREQUENCY:
+ case AV_CHAN_LOW_FREQUENCY:
m_rematrix[out][0] = 0.5;
m_rematrix[out][1] = 0.5;
break;
diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
index 96d8def6b0..07c3a99f26 100644
--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp
@@ -911,7 +911,7 @@ void CActiveAESink::OpenSink()
m_needIecPack = NeedIECPacking();
if (m_needIecPack)
{
- m_packer = std::make_unique<CAEBitstreamPacker>();
+ m_packer = std::make_unique<CAEBitstreamPacker>(m_requestedFormat.m_streamInfo);
m_requestedFormat.m_sampleRate = CAEBitstreamPacker::GetOutputRate(m_requestedFormat.m_streamInfo);
m_requestedFormat.m_channelLayout = CAEBitstreamPacker::GetOutputChannelMap(m_requestedFormat.m_streamInfo);
}
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
index bdc197b644..e0a42c62a4 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp
@@ -458,15 +458,15 @@ bool CAESinkAUDIOTRACK::Initialize(AEAudioFormat &format, std::string &device)
rawlength_in_seconds = 8 * m_format.m_streamInfo.GetDuration() / 1000;
break;
case CAEStreamInfo::STREAM_TYPE_AC3:
- ac3FrameSize = m_format.m_streamInfo.m_ac3FrameSize;
- if (ac3FrameSize == 0)
- ac3FrameSize = 1536; // fallback if not set, e.g. Transcoding
- m_min_buffer_size = std::max(m_min_buffer_size * 3, ac3FrameSize * 8);
- m_format.m_frames = m_min_buffer_size;
- multiplier = m_min_buffer_size / ac3FrameSize; // int division is wanted
- rawlength_in_seconds = multiplier * m_format.m_streamInfo.GetDuration() / 1000;
+ ac3FrameSize = m_format.m_streamInfo.m_frameSize;
+ if (ac3FrameSize == 0)
+ ac3FrameSize = 1536; // fallback if not set, e.g. Transcoding
+ m_min_buffer_size = std::max(m_min_buffer_size * 3, ac3FrameSize * 8);
+ m_format.m_frames = m_min_buffer_size;
+ multiplier = m_min_buffer_size / ac3FrameSize; // int division is wanted
+ rawlength_in_seconds = multiplier * m_format.m_streamInfo.GetDuration() / 1000;
break;
- // EAC3 is currently not supported
+ // EAC3 is currently not supported
case CAEStreamInfo::STREAM_TYPE_EAC3:
m_min_buffer_size = 2 * 10752; // least common multiple of 1792 and 1536
m_format.m_frames = m_min_buffer_size; // needs testing
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDARWINTVOS.mm b/xbmc/cores/AudioEngine/Sinks/AESinkDARWINTVOS.mm
index 5d66474ca0..162b5c9650 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkDARWINTVOS.mm
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkDARWINTVOS.mm
@@ -784,15 +784,15 @@ bool CAESinkDARWINTVOS::Initialize(AEAudioFormat& format, std::string& device)
switch (format.m_streamInfo.m_type)
{
case CAEStreamInfo::STREAM_TYPE_AC3:
- if (!format.m_streamInfo.m_ac3FrameSize)
- format.m_streamInfo.m_ac3FrameSize = 1536;
- format.m_frames = format.m_streamInfo.m_ac3FrameSize;
+ if (!format.m_streamInfo.m_frameSize)
+ format.m_streamInfo.m_frameSize = 1536;
+ format.m_frames = format.m_streamInfo.m_frameSize;
buffer_size = format.m_frames * 8;
break;
case CAEStreamInfo::STREAM_TYPE_EAC3:
- if (!format.m_streamInfo.m_ac3FrameSize)
- format.m_streamInfo.m_ac3FrameSize = 1536;
- format.m_frames = format.m_streamInfo.m_ac3FrameSize;
+ if (!format.m_streamInfo.m_frameSize)
+ format.m_streamInfo.m_frameSize = 1536;
+ format.m_frames = format.m_streamInfo.m_frameSize;
buffer_size = format.m_frames * 8;
break;
case CAEStreamInfo::STREAM_TYPE_DTS_512:
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
index 4b450ec5cb..ca02e2bafa 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkDirectSound.cpp
@@ -218,10 +218,10 @@ bool CAESinkDirectSound::Initialize(AEAudioFormat &format, std::string &device)
m_AvgBytesPerSec = wfxex.Format.nAvgBytesPerSec;
- unsigned int uiFrameCount = (int)(format.m_sampleRate * 0.015); //default to 15ms chunks
+ const unsigned int uiFrameCount = static_cast<int>(format.m_sampleRate * 0.050); // 50ms chunks
m_dwFrameSize = wfxex.Format.nBlockAlign;
m_dwChunkSize = m_dwFrameSize * uiFrameCount;
- m_dwBufferLen = m_dwChunkSize * 12; //180ms total buffer
+ m_dwBufferLen = m_dwChunkSize * 8; // 400ms total buffer
// fill in the secondary sound buffer descriptor
DSBUFFERDESC dsbdesc = {};
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp
index c6763bae13..5ec64fe9f0 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp
@@ -19,6 +19,9 @@
#include <memory>
#include <mutex>
+#include <pulse/context.h>
+#include <pulse/introspect.h>
+
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@@ -27,7 +30,7 @@ class CDriverMonitor
public:
CDriverMonitor() = default;
virtual ~CDriverMonitor();
- bool Start();
+ bool Start(bool allowPipeWireCompatServer);
bool IsInitialized();
CCriticalSection m_sec;
@@ -315,6 +318,21 @@ static void SinkChangedCallback(pa_context *c, pa_subscription_event_type_t t, u
}
}
+struct ServerInfoStruct
+{
+ pa_threaded_mainloop* m_mainloop;
+ bool m_isInfoSet{false};
+ std::string m_serverName;
+};
+
+static void ServerInfoCallback(pa_context* c, const pa_server_info* i, void* userdata)
+{
+ auto serverInfo = reinterpret_cast<ServerInfoStruct*>(userdata);
+ serverInfo->m_serverName = i->server_name;
+ serverInfo->m_isInfoSet = true;
+ pa_threaded_mainloop_signal(serverInfo->m_mainloop, 0);
+}
+
struct SinkInfoStruct
{
AEDeviceInfoList *list;
@@ -656,7 +674,7 @@ bool CDriverMonitor::IsInitialized()
return m_isInit;
}
-bool CDriverMonitor::Start()
+bool CDriverMonitor::Start(bool allowPipeWireCompatServer)
{
if (!SetupContext(nullptr, "KodiDriver", &m_pContext, &m_pMainLoop))
{
@@ -666,6 +684,30 @@ bool CDriverMonitor::Start()
pa_threaded_mainloop_lock(m_pMainLoop);
+ ServerInfoStruct serverInfo;
+ serverInfo.m_mainloop = m_pMainLoop;
+ pa_context_get_server_info(m_pContext, ServerInfoCallback, &serverInfo);
+ while (!serverInfo.m_isInfoSet)
+ pa_threaded_mainloop_wait(m_pMainLoop);
+
+ CLog::Log(LOGINFO, "PulseAudio: Server name: {}", serverInfo.m_serverName);
+
+#ifdef HAS_PIPEWIRE
+ // If Kodi is build with PipeWire support we prefer native PipeWire over the
+ // PulseAudio compatibility layer IF NOT PulseAudio is explicitly selected
+ if (!allowPipeWireCompatServer)
+ {
+ // Check the PulseAudio server name. If it contains PipeWire in any form
+ // it is the compatibility layer provided by PipeWire
+ if (StringUtils::Contains(serverInfo.m_serverName, "pipewire", true))
+ {
+ CLog::Log(LOGINFO, "PulseAudio: Server is PipeWire, bail and use native PipeWire interface");
+ pa_threaded_mainloop_unlock(m_pMainLoop);
+ return false;
+ }
+ }
+#endif
+
m_isInit = true;
std::unique_lock<CCriticalSection> lock(m_sec);
@@ -687,7 +729,7 @@ bool CDriverMonitor::Start()
std::unique_ptr<CDriverMonitor> CAESinkPULSE::m_pMonitor;
-bool CAESinkPULSE::Register()
+bool CAESinkPULSE::Register(bool allowPipeWireCompatServer)
{
// check if pulseaudio is actually available
pa_simple *s;
@@ -708,7 +750,11 @@ bool CAESinkPULSE::Register()
}
m_pMonitor = std::make_unique<CDriverMonitor>();
- m_pMonitor->Start();
+ if (!m_pMonitor->Start(allowPipeWireCompatServer))
+ {
+ m_pMonitor.reset();
+ return false;
+ }
AE::AESinkRegEntry entry;
entry.sinkName = "PULSE";
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h
index 3606a0b4f5..48f73f9a10 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h
@@ -31,7 +31,7 @@ public:
CAESinkPULSE();
~CAESinkPULSE() override;
- static bool Register();
+ static bool Register(bool allowPipeWireCompatServer);
static std::unique_ptr<IAESink> Create(std::string& device, AEAudioFormat& desiredFormat);
static void EnumerateDevicesEx(AEDeviceInfoList &list, bool force = false);
static void Cleanup();
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkStarfish.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkStarfish.cpp
index 0d07b44fa3..d9c8859cc4 100644
--- a/xbmc/cores/AudioEngine/Sinks/AESinkStarfish.cpp
+++ b/xbmc/cores/AudioEngine/Sinks/AESinkStarfish.cpp
@@ -21,10 +21,17 @@ namespace
{
constexpr unsigned int STARFISH_AUDIO_BUFFERS = 8;
constexpr unsigned int AC3_SYNCFRAME_SIZE = 2560;
+constexpr unsigned int DTDHD_MA_MIN_SYNCFRAME_SIZE = 2012 + 2764;
static constexpr auto ms_audioCodecMap = make_map<CAEStreamInfo::DataType, std::string_view>({
{CAEStreamInfo::STREAM_TYPE_AC3, "AC3"},
{CAEStreamInfo::STREAM_TYPE_EAC3, "AC3 PLUS"},
+ {CAEStreamInfo::STREAM_TYPE_DTS_512, "DTS"},
+ {CAEStreamInfo::STREAM_TYPE_DTS_1024, "DTS"},
+ {CAEStreamInfo::STREAM_TYPE_DTS_2048, "DTS"},
+ {CAEStreamInfo::STREAM_TYPE_DTSHD, "DTS"},
+ {CAEStreamInfo::STREAM_TYPE_DTSHD_CORE, "DTS"},
+ {CAEStreamInfo::STREAM_TYPE_DTSHD_MA, "DTS"},
});
} // namespace
@@ -63,6 +70,12 @@ void CAESinkStarfish::EnumerateDevicesEx(AEDeviceInfoList& list, bool force)
info.m_deviceType = AE_DEVTYPE_IEC958;
info.m_streamTypes.emplace_back(CAEStreamInfo::STREAM_TYPE_AC3);
info.m_streamTypes.emplace_back(CAEStreamInfo::STREAM_TYPE_EAC3);
+ info.m_streamTypes.emplace_back(CAEStreamInfo::STREAM_TYPE_DTS_512);
+ info.m_streamTypes.emplace_back(CAEStreamInfo::STREAM_TYPE_DTS_1024);
+ info.m_streamTypes.emplace_back(CAEStreamInfo::STREAM_TYPE_DTS_2048);
+ info.m_streamTypes.emplace_back(CAEStreamInfo::STREAM_TYPE_DTSHD);
+ info.m_streamTypes.emplace_back(CAEStreamInfo::STREAM_TYPE_DTSHD_CORE);
+ info.m_streamTypes.emplace_back(CAEStreamInfo::STREAM_TYPE_DTSHD_MA);
info.m_sampleRates.emplace_back(32000);
info.m_sampleRates.emplace_back(44100);
@@ -89,8 +102,6 @@ bool CAESinkStarfish::Initialize(AEAudioFormat& format, std::string& device)
}
m_format.m_frameSize = 1;
- format = m_format;
-
CVariant payload;
payload["isAudioOnly"] = true;
payload["mediaTransportType"] = "BUFFERSTREAM";
@@ -107,10 +118,10 @@ bool CAESinkStarfish::Initialize(AEAudioFormat& format, std::string& device)
{
case CAEStreamInfo::STREAM_TYPE_AC3:
{
- if (!format.m_streamInfo.m_ac3FrameSize)
- format.m_streamInfo.m_ac3FrameSize = AC3_SYNCFRAME_SIZE;
- format.m_frames = format.m_streamInfo.m_ac3FrameSize;
- m_bufferSize = format.m_frames * STARFISH_AUDIO_BUFFERS;
+ if (!m_format.m_streamInfo.m_frameSize)
+ m_format.m_streamInfo.m_frameSize = AC3_SYNCFRAME_SIZE;
+ m_format.m_frames = m_format.m_streamInfo.m_frameSize;
+ m_bufferSize = m_format.m_frames * STARFISH_AUDIO_BUFFERS;
break;
}
case CAEStreamInfo::STREAM_TYPE_EAC3:
@@ -119,10 +130,30 @@ bool CAESinkStarfish::Initialize(AEAudioFormat& format, std::string& device)
payload["option"]["externalStreamingInfo"]["contents"]["ac3PlusInfo"]["frequency"] =
static_cast<double>(m_format.m_streamInfo.m_sampleRate) / 1000;
- if (!format.m_streamInfo.m_ac3FrameSize)
- format.m_streamInfo.m_ac3FrameSize = AC3_SYNCFRAME_SIZE;
- format.m_frames = format.m_streamInfo.m_ac3FrameSize;
- m_bufferSize = format.m_frames * STARFISH_AUDIO_BUFFERS;
+ if (!m_format.m_streamInfo.m_frameSize)
+ m_format.m_streamInfo.m_frameSize = AC3_SYNCFRAME_SIZE;
+ m_format.m_frames = m_format.m_streamInfo.m_frameSize;
+ m_bufferSize = m_format.m_frames * STARFISH_AUDIO_BUFFERS;
+ break;
+ }
+ case CAEStreamInfo::STREAM_TYPE_DTSHD_CORE:
+ case CAEStreamInfo::STREAM_TYPE_DTS_512:
+ case CAEStreamInfo::STREAM_TYPE_DTS_1024:
+ case CAEStreamInfo::STREAM_TYPE_DTS_2048:
+ case CAEStreamInfo::STREAM_TYPE_DTSHD:
+ case CAEStreamInfo::STREAM_TYPE_DTSHD_MA:
+ {
+ payload["option"]["externalStreamingInfo"]["contents"]["dtsInfo"]["channels"] =
+ m_format.m_streamInfo.m_channels;
+ payload["option"]["externalStreamingInfo"]["contents"]["dtsInfo"]["frequency"] =
+ static_cast<double>(m_format.m_streamInfo.m_sampleRate) / 1000;
+
+ m_format.m_frames = m_format.m_streamInfo.m_frameSize;
+
+ // DTSHD_MA has dynamic frame sizes but we need to ensure that the buffer is large enough
+ if (m_format.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_DTSHD_MA)
+ m_format.m_frames = DTDHD_MA_MIN_SYNCFRAME_SIZE * 2 - 1;
+ m_bufferSize = m_format.m_frames * STARFISH_AUDIO_BUFFERS;
break;
}
default:
@@ -140,7 +171,7 @@ bool CAESinkStarfish::Initialize(AEAudioFormat& format, std::string& device)
m_bufferSize;
// Internal buffer?
payload["option"]["externalStreamingInfo"]["bufferingCtrInfo"]["srcBufferLevelAudio"]["minimum"] =
- format.m_frames;
+ m_format.m_frames;
payload["option"]["externalStreamingInfo"]["bufferingCtrInfo"]["srcBufferLevelAudio"]["maximum"] =
m_bufferSize;
@@ -159,6 +190,8 @@ bool CAESinkStarfish::Initialize(AEAudioFormat& format, std::string& device)
return false;
}
+ format = m_format;
+
return true;
}
diff --git a/xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.cpp b/xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.cpp
index cf1c515def..1d3253e348 100644
--- a/xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.cpp
+++ b/xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.cpp
@@ -10,6 +10,7 @@
#include "AEPackIEC61937.h"
#include "AEStreamInfo.h"
+#include "PackerMAT.h"
#include "utils/log.h"
#include <array>
@@ -17,51 +18,18 @@
#include <stdint.h>
#include <string.h>
-extern "C"
-{
-#include <libavutil/intreadwrite.h>
-}
-
namespace
{
constexpr auto BURST_HEADER_SIZE = 8;
constexpr auto EAC3_MAX_BURST_PAYLOAD_SIZE = 24576 - BURST_HEADER_SIZE;
+} // namespace
-constexpr auto MAT_PKT_OFFSET = 61440;
-constexpr auto MAT_FRAME_SIZE = 61424;
-
-/* magic MAT format values, meaning is unknown at this point */
-constexpr std::array<uint8_t, 20> mat_start_code = {
- 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00,
- 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0,
-};
-
-constexpr std::array<uint8_t, 12> mat_middle_code = {
- 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA, 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0,
-};
-
-constexpr std::array<uint8_t, 16> mat_end_code = {
- 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11,
-};
-
-struct MatCode
-{
- int pos;
- const uint8_t* code;
- unsigned int len;
-};
-
-std::array<MatCode, 3> MatCodes = {{
- {0, mat_start_code.data(), mat_start_code.size()},
- {30708, mat_middle_code.data(), mat_middle_code.size()},
- {MAT_FRAME_SIZE - mat_end_code.size(), mat_end_code.data(), mat_end_code.size()},
-}};
-
-} // unnamed namespace
-
-CAEBitstreamPacker::CAEBitstreamPacker()
+CAEBitstreamPacker::CAEBitstreamPacker(const CAEStreamInfo& info)
{
Reset();
+
+ if (info.m_type == CAEStreamInfo::STREAM_TYPE_TRUEHD)
+ m_packerMAT = std::make_unique<CPackerMAT>();
}
CAEBitstreamPacker::~CAEBitstreamPacker()
@@ -74,7 +42,8 @@ void CAEBitstreamPacker::Pack(CAEStreamInfo &info, uint8_t* data, int size)
switch (info.m_type)
{
case CAEStreamInfo::STREAM_TYPE_TRUEHD:
- PackTrueHD(info, data, size);
+ m_packerMAT->PackTrueHD(data, size);
+ GetDataTrueHD();
break;
case CAEStreamInfo::STREAM_TYPE_DTSHD:
@@ -162,149 +131,27 @@ void CAEBitstreamPacker::Reset()
m_packedBuffer[0] = 0;
}
-/* we need to pack 24 TrueHD audio units into the unknown MAT format before packing into IEC61937 */
-void CAEBitstreamPacker::PackTrueHD(CAEStreamInfo &info, uint8_t* data, int size)
+void CAEBitstreamPacker::GetDataTrueHD()
{
- /* create the buffer if it doesn't already exist */
- if (m_trueHD[0].empty())
+ // limits a bit MAT frames output speed as this is called every 1/1200 seconds and
+ // anyway only is possible obtain a MAT frame every 12 audio units (TrueHD has 24 units
+ // but are send to packer every 12 to reduce latency). As MAT packer can generate more than
+ // one MAT frame at time (but in average only one every 20 ms) this delays the output
+ // a little when thera are more that one frame at queue but still allows the queue to empty.
+ if (m_dataCountTrueHD > 0)
{
- m_trueHD[0].resize(MAT_FRAME_SIZE);
- m_trueHD[1].resize(MAT_FRAME_SIZE);
- m_thd = {};
- }
-
- if (size < 10)
+ m_dataCountTrueHD--;
return;
-
- uint8_t* pBuf = m_trueHD[m_thd.bufferIndex].data();
- const uint8_t* pData = data;
-
- int totalFrameSize = size;
- int dataRem = size;
- int paddingRem = 0;
- int ratebits = 0;
- int nextCodeIdx = 0;
- uint16_t inputTiming = 0;
- bool havePacket = false;
-
- if (AV_RB24(data + 4) == 0xf8726f)
- {
- /* major sync unit, fetch sample rate */
- if (data[7] == 0xba)
- ratebits = data[8] >> 4;
- else if (data[7] == 0xbb)
- ratebits = data[9] >> 4;
- else
- return;
-
- m_thd.samplesPerFrame = 40 << (ratebits & 3);
- }
-
- if (!m_thd.samplesPerFrame)
- return;
-
- inputTiming = AV_RB16(data + 2);
-
- if (m_thd.prevFrameSize)
- {
- uint16_t deltaSamples = inputTiming - m_thd.prevFrameTime;
- /*
- * One multiple-of-48kHz frame is 1/1200 sec and the IEC 61937 rate
- * is 768kHz = 768000*4 bytes/sec.
- * The nominal space per frame is therefore
- * (768000*4 bytes/sec) * (1/1200 sec) = 2560 bytes.
- * For multiple-of-44.1kHz frames: 1/1102.5 sec, 705.6kHz, 2560 bytes.
- *
- * 2560 is divisible by samplesPerFrame.
- */
- int deltaBytes = deltaSamples * 2560 / m_thd.samplesPerFrame;
-
- /* padding needed before this frame */
- paddingRem = deltaBytes - m_thd.prevFrameSize;
-
- // detects stream discontinuities
- if (paddingRem < 0 || paddingRem >= MAT_FRAME_SIZE * 2)
- {
- m_thd = {}; // recovering after seek
- return;
- }
}
- for (nextCodeIdx = 0; nextCodeIdx < static_cast<int>(MatCodes.size()); nextCodeIdx++)
- if (m_thd.bufferFilled <= MatCodes[nextCodeIdx].pos)
- break;
-
- if (nextCodeIdx >= static_cast<int>(MatCodes.size()))
- return;
-
- while (paddingRem || dataRem || MatCodes[nextCodeIdx].pos == m_thd.bufferFilled)
+ if (m_packerMAT->HaveOutput())
{
- if (MatCodes[nextCodeIdx].pos == m_thd.bufferFilled)
- {
- /* time to insert MAT code */
- int codeLen = MatCodes[nextCodeIdx].len;
- int codeLenRemaining = codeLen;
- memcpy(pBuf + MatCodes[nextCodeIdx].pos, MatCodes[nextCodeIdx].code, codeLen);
- m_thd.bufferFilled += codeLen;
-
- nextCodeIdx++;
- if (nextCodeIdx == static_cast<int>(MatCodes.size()))
- {
- nextCodeIdx = 0;
-
- /* this was the last code, move to the next MAT frame */
- havePacket = true;
- m_thd.outputBuffer = pBuf;
- m_thd.bufferIndex ^= 1;
- pBuf = m_trueHD[m_thd.bufferIndex].data();
- m_thd.bufferFilled = 0;
-
- /* inter-frame gap has to be counted as well, add it */
- codeLenRemaining += MAT_PKT_OFFSET - MAT_FRAME_SIZE;
- }
-
- if (paddingRem)
- {
- /* consider the MAT code as padding */
- const int countedAsPadding = std::min(paddingRem, codeLenRemaining);
- paddingRem -= countedAsPadding;
- codeLenRemaining -= countedAsPadding;
- }
- /* count the remainder of the code as part of frame size */
- if (codeLenRemaining)
- totalFrameSize += codeLenRemaining;
- }
-
- if (paddingRem)
- {
- const int paddingLen = std::min(MatCodes[nextCodeIdx].pos - m_thd.bufferFilled, paddingRem);
-
- memset(pBuf + m_thd.bufferFilled, 0, paddingLen);
- m_thd.bufferFilled += paddingLen;
- paddingRem -= paddingLen;
-
- if (paddingRem)
- continue; /* time to insert MAT code */
- }
-
- if (dataRem)
- {
- const int dataLen = std::min(MatCodes[nextCodeIdx].pos - m_thd.bufferFilled, dataRem);
+ const auto& mat = m_packerMAT->GetOutputFrame();
- memcpy(pBuf + m_thd.bufferFilled, pData, dataLen);
- m_thd.bufferFilled += dataLen;
- pData += dataLen;
- dataRem -= dataLen;
- }
+ m_dataSize = CAEPackIEC61937::PackTrueHD(mat.data() + IEC61937_DATA_OFFSET,
+ mat.size() - IEC61937_DATA_OFFSET, m_packedBuffer);
+ m_dataCountTrueHD = 3;
}
-
- m_thd.prevFrameSize = totalFrameSize;
- m_thd.prevFrameTime = inputTiming;
-
- if (!havePacket)
- return;
-
- m_dataSize = CAEPackIEC61937::PackTrueHD(m_thd.outputBuffer, MAT_FRAME_SIZE, m_packedBuffer);
}
void CAEBitstreamPacker::PackDTSHD(CAEStreamInfo &info, uint8_t* data, int size)
diff --git a/xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.h b/xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.h
index 1497c03d68..b7d695b62e 100644
--- a/xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.h
+++ b/xbmc/cores/AudioEngine/Utils/AEBitstreamPacker.h
@@ -12,15 +12,17 @@
#include "AEPackIEC61937.h"
#include <list>
+#include <memory>
#include <stdint.h>
#include <vector>
class CAEStreamInfo;
+class CPackerMAT;
class CAEBitstreamPacker
{
public:
- CAEBitstreamPacker();
+ CAEBitstreamPacker(const CAEStreamInfo& info);
~CAEBitstreamPacker();
void Pack(CAEStreamInfo &info, uint8_t* data, int size);
@@ -32,24 +34,13 @@ public:
static CAEChannelInfo GetOutputChannelMap(const CAEStreamInfo& info);
private:
- void PackTrueHD(CAEStreamInfo &info, uint8_t* data, int size);
+ void GetDataTrueHD();
void PackDTSHD(CAEStreamInfo &info, uint8_t* data, int size);
void PackEAC3(CAEStreamInfo &info, uint8_t* data, int size);
- /* we keep the trueHD and dtsHD buffers separate so that we can handle a fast stream switch */
- std::vector<uint8_t> m_trueHD[2];
+ std::unique_ptr<CPackerMAT> m_packerMAT;
- struct TrueHD
- {
- int prevFrameSize;
- int samplesPerFrame;
- int bufferFilled;
- int bufferIndex;
- uint16_t prevFrameTime;
- uint8_t* outputBuffer;
- };
-
- TrueHD m_thd{};
+ unsigned int m_dataCountTrueHD{0};
std::vector<uint8_t> m_dtsHD;
unsigned int m_dtsHDSize = 0;
diff --git a/xbmc/cores/AudioEngine/Utils/AEPackIEC61937.cpp b/xbmc/cores/AudioEngine/Utils/AEPackIEC61937.cpp
index 411d48103e..43bfbf3c73 100644
--- a/xbmc/cores/AudioEngine/Utils/AEPackIEC61937.cpp
+++ b/xbmc/cores/AudioEngine/Utils/AEPackIEC61937.cpp
@@ -86,7 +86,7 @@ int CAEPackIEC61937::PackDTS_2048(uint8_t *data, unsigned int size, uint8_t *des
return PackDTS(data, size, dest, littleEndian, OUT_FRAMESTOBYTES(DTS3_FRAME_SIZE), IEC61937_TYPE_DTS3);
}
-int CAEPackIEC61937::PackTrueHD(uint8_t *data, unsigned int size, uint8_t *dest)
+int CAEPackIEC61937::PackTrueHD(const uint8_t* data, unsigned int size, uint8_t* dest)
{
if (size == 0)
return OUT_FRAMESTOBYTES(TRUEHD_FRAME_SIZE);
@@ -95,8 +95,8 @@ int CAEPackIEC61937::PackTrueHD(uint8_t *data, unsigned int size, uint8_t *dest)
struct IEC61937Packet *packet = (struct IEC61937Packet*)dest;
packet->m_preamble1 = IEC61937_PREAMBLE1;
packet->m_preamble2 = IEC61937_PREAMBLE2;
- packet->m_type = IEC61937_TYPE_TRUEHD;
- packet->m_length = size;
+ packet->m_type = IEC61937_TYPE_TRUEHD;
+ packet->m_length = 61424;
if (data == NULL)
data = packet->m_data;
diff --git a/xbmc/cores/AudioEngine/Utils/AEPackIEC61937.h b/xbmc/cores/AudioEngine/Utils/AEPackIEC61937.h
index 5a83b65556..7a6e72741c 100644
--- a/xbmc/cores/AudioEngine/Utils/AEPackIEC61937.h
+++ b/xbmc/cores/AudioEngine/Utils/AEPackIEC61937.h
@@ -36,8 +36,8 @@ public:
static int PackDTS_512 (uint8_t *data, unsigned int size, uint8_t *dest, bool littleEndian);
static int PackDTS_1024(uint8_t *data, unsigned int size, uint8_t *dest, bool littleEndian);
static int PackDTS_2048(uint8_t *data, unsigned int size, uint8_t *dest, bool littleEndian);
- static int PackTrueHD (uint8_t *data, unsigned int size, uint8_t *dest);
- static int PackDTSHD (uint8_t *data, unsigned int size, uint8_t *dest, unsigned int period);
+ static int PackTrueHD(const uint8_t* data, unsigned int size, uint8_t* dest);
+ static int PackDTSHD(uint8_t* data, unsigned int size, uint8_t* dest, unsigned int period);
static int PackPause(uint8_t *dest, unsigned int millis, unsigned int framesize, unsigned int samplerate, unsigned int rep_period, unsigned int encodedRate);
private:
diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp
index b045a19d10..8f49fe9cad 100644
--- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp
+++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.cpp
@@ -369,7 +369,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data,
// no need to resync => return true
return true;
}
- m_info.m_ac3FrameSize = fsizeMain;
+ m_info.m_frameSize = fsizeMain;
if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, true))
{
// concatenate the main and dependent frames
@@ -393,7 +393,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data,
m_info.m_channels = AC3Channels[acmod] + lfeon;
m_syncFunc = &CAEStreamParser::SyncAC3;
m_info.m_type = CAEStreamInfo::STREAM_TYPE_AC3;
- m_info.m_ac3FrameSize += m_fsize;
+ m_info.m_frameSize += m_fsize;
m_info.m_repeat = 1;
CLog::Log(LOGINFO, "CAEStreamParser::TrySyncAC3 - AC3 stream detected ({} channels, {}Hz)",
@@ -408,12 +408,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data,
return false;
if (strmtyp != 1 && wantEAC3dependent)
- {
- CLog::Log(LOGDEBUG,
- "CAEStreamParser::TrySyncAC3 - Unexpected stream type: {} (wantEAC3dependent: {})",
- strmtyp, wantEAC3dependent);
return false;
- }
unsigned int framesize = (((data[2] & 0x7) << 8) | data[3]) + 1;
uint8_t fscod = (data[4] >> 6) & 0x3;
@@ -452,7 +447,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data,
// no need to resync => return true
return true;
}
- m_info.m_ac3FrameSize = fsizeMain;
+ m_info.m_frameSize = fsizeMain;
if (TrySyncAC3(data + fsizeMain, size - fsizeMain, resyncing, true))
{
// concatenate the main and dependent frames
@@ -469,7 +464,7 @@ bool CAEStreamParser::TrySyncAC3(uint8_t* data,
m_info.m_channels = AC3Channels[acmod] + lfeon;
m_syncFunc = &CAEStreamParser::SyncAC3;
m_info.m_type = CAEStreamInfo::STREAM_TYPE_EAC3;
- m_info.m_ac3FrameSize += m_fsize;
+ m_info.m_frameSize += m_fsize;
CLog::Log(LOGINFO, "CAEStreamParser::TrySyncAC3 - E-AC3 stream detected ({} channels, {}Hz)",
m_info.m_channels, m_info.m_sampleRate);
@@ -673,6 +668,7 @@ unsigned int CAEStreamParser::SyncDTS(uint8_t* data, unsigned int size)
m_dtsBlocks = dtsBlocks;
m_info.m_channels = DTSChannels[amode] + (lfe ? 1 : 0);
m_syncFunc = &CAEStreamParser::SyncDTS;
+ m_info.m_frameSize = m_fsize;
m_info.m_repeat = 1;
if (dataType == CAEStreamInfo::STREAM_TYPE_DTSHD_MA)
@@ -812,6 +808,7 @@ unsigned int CAEStreamParser::SyncTrueHD(uint8_t* data, unsigned int size)
m_fsize = length;
m_info.m_type = CAEStreamInfo::STREAM_TYPE_TRUEHD;
m_syncFunc = &CAEStreamParser::SyncTrueHD;
+ m_info.m_frameSize = length;
m_info.m_repeat = 1;
return skip;
}
diff --git a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h
index dff809d137..acfa77d987 100644
--- a/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h
+++ b/xbmc/cores/AudioEngine/Utils/AEStreamInfo.h
@@ -45,7 +45,7 @@ public:
bool m_dataIsLE = true;
unsigned int m_dtsPeriod = 0;
unsigned int m_repeat = 0;
- unsigned int m_ac3FrameSize = 0;
+ unsigned int m_frameSize = 0;
};
class CAEStreamParser
diff --git a/xbmc/cores/AudioEngine/Utils/PackerMAT.cpp b/xbmc/cores/AudioEngine/Utils/PackerMAT.cpp
new file mode 100644
index 0000000000..29ee54ea92
--- /dev/null
+++ b/xbmc/cores/AudioEngine/Utils/PackerMAT.cpp
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "PackerMAT.h"
+
+#include "utils/log.h"
+
+#include <array>
+#include <assert.h>
+#include <utility>
+
+extern "C"
+{
+#include <libavutil/common.h>
+#include <libavutil/intreadwrite.h>
+}
+
+namespace
+{
+constexpr uint32_t FORMAT_MAJOR_SYNC = 0xf8726fba;
+
+constexpr auto BURST_HEADER_SIZE = 8;
+constexpr auto MAT_BUFFER_SIZE = 61440;
+constexpr auto MAT_BUFFER_LIMIT = MAT_BUFFER_SIZE - 24; // MAT end code size
+constexpr auto MAT_POS_MIDDLE = 30708 + BURST_HEADER_SIZE; // middle point + IEC header in front
+
+// magic MAT format values, meaning is unknown at this point
+constexpr std::array<uint8_t, 20> mat_start_code = {0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01,
+ 0x01, 0x80, 0x00, 0x56, 0xA5, 0x3B, 0xF4,
+ 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0};
+
+constexpr std::array<uint8_t, 12> mat_middle_code = {0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA,
+ 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0};
+
+constexpr std::array<uint8_t, 24> mat_end_code = {0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+} // namespace
+
+CPackerMAT::CPackerMAT()
+{
+ m_buffer.reserve(MAT_BUFFER_SIZE);
+}
+
+bool CPackerMAT::PackTrueHD(const uint8_t* data, int size)
+{
+ // On a high level, a MAT frame consists of a sequence of padded TrueHD frames
+ // The size of the padded frame can be determined from the frame time/sequence code in the frame header,
+ // since it varies to accommodate spikes in bitrate.
+ // In average all frames are always padded to 2560 bytes, so that 24 frames fit in one MAT frame, however
+ // due to bitrate spikes single sync frames have been observed to use up to twice that size, in which
+ // case they'll be preceded by smaller frames to keep the average bitrate constant.
+ // A constant padding to 2560 bytes can work (this is how the ffmpeg spdifenc module works), however
+ // high-bitrate streams can overshoot this size and therefor require proper handling of dynamic padding.
+
+ TrueHDMajorSyncInfo info;
+
+ // get the ratebits and output timing from the sync frame
+ if (AV_RB32(data + 4) == FORMAT_MAJOR_SYNC)
+ {
+ info = ParseTrueHDMajorSyncHeaders(data, size);
+
+ if (!info.valid)
+ return false;
+
+ m_state.ratebits = info.ratebits;
+ }
+ else if (m_state.prevFrametimeValid == false)
+ {
+ // only start streaming on a major sync frame
+ m_state.numberOfSamplesOffset = 0;
+ return false;
+ }
+
+ const uint16_t frameTime = AV_RB16(data + 2);
+ uint32_t spaceSize = 0;
+ const uint16_t frameSamples = 40 << (m_state.ratebits & 7);
+ m_state.outputTiming += frameSamples;
+
+ if (info.outputTimingPresent)
+ {
+ if (m_state.outputTimingValid && (info.outputTiming != m_state.outputTiming))
+ {
+ CLog::Log(LOGWARNING,
+ "CPackerMAT::PackTrueHD: detected a stream discontinuity -> output timing "
+ "expected: {}, found: {}",
+ m_state.outputTiming, info.outputTiming);
+ }
+ m_state.outputTiming = info.outputTiming;
+ m_state.outputTimingValid = true;
+ }
+
+ // compute final padded size for the previous frame, if any
+ if (m_state.prevFrametimeValid)
+ spaceSize = uint16_t(frameTime - m_state.prevFrametime) * (64 >> (m_state.ratebits & 7));
+
+ // compute padding (ie. difference to the size of the previous frame)
+ assert(!m_state.prevFrametimeValid || spaceSize >= m_state.prevMatFramesize);
+
+ // if for some reason the spaceSize fails, align the actual frame size
+ if (spaceSize < m_state.prevMatFramesize)
+ spaceSize = FFALIGN(m_state.prevMatFramesize, (64 >> (m_state.ratebits & 7)));
+
+ m_state.padding += (spaceSize - m_state.prevMatFramesize);
+
+ // detect seeks and re-initialize internal state i.e. skip stream
+ // until the next major sync frame
+ if (m_state.padding > MAT_BUFFER_SIZE * 5)
+ {
+ CLog::LogF(LOGINFO, "seek detected, re-initializing MAT packer state");
+ m_state = {};
+ m_state.init = true;
+ m_buffer.clear();
+ m_bufferCount = 0;
+ return false;
+ }
+
+ // store frame time of the previous frame
+ m_state.prevFrametime = frameTime;
+ m_state.prevFrametimeValid = true;
+
+ // Write the MAT header into the fresh buffer
+ if (GetCount() == 0)
+ {
+ WriteHeader();
+
+ // initial header, don't count it for the frame size
+ if (m_state.init == false)
+ {
+ m_state.init = true;
+ m_state.matFramesize = 0;
+ }
+ }
+
+ // write padding of the previous frame (if any)
+ while (m_state.padding > 0)
+ {
+ WritePadding();
+
+ assert(m_state.padding == 0 || GetCount() == MAT_BUFFER_SIZE);
+
+ // Buffer is full, submit it
+ if (GetCount() == MAT_BUFFER_SIZE)
+ {
+ FlushPacket();
+
+ // and setup a new buffer
+ WriteHeader();
+ }
+ }
+
+ // count the number of samples in this frame
+ m_state.samples += frameSamples;
+
+ // write actual audio data to the buffer
+ int remaining = FillDataBuffer(data, size, Type::DATA);
+
+ // not all data could be written, or the buffer is full
+ if (remaining || GetCount() == MAT_BUFFER_SIZE)
+ {
+ // flush out old data
+ FlushPacket();
+
+ if (remaining)
+ {
+ // setup a new buffer
+ WriteHeader();
+
+ // and write the remaining data
+ remaining = FillDataBuffer(data + (size - remaining), remaining, Type::DATA);
+
+ assert(remaining == 0);
+ }
+ }
+
+ // store the size of the current MAT frame, so we can add padding later
+ m_state.prevMatFramesize = m_state.matFramesize;
+ m_state.matFramesize = 0;
+
+ return true;
+}
+
+std::vector<uint8_t> CPackerMAT::GetOutputFrame()
+{
+ std::vector<uint8_t> buffer;
+
+ if (m_outputQueue.empty())
+ return {};
+
+ buffer = std::move(m_outputQueue.front());
+
+ m_outputQueue.pop_front();
+
+ return buffer;
+}
+
+void CPackerMAT::WriteHeader()
+{
+ m_buffer.resize(MAT_BUFFER_SIZE);
+
+ // reserve size for the IEC header and the MAT start code
+ const size_t size = BURST_HEADER_SIZE + mat_start_code.size();
+
+ // write MAT start code. IEC header written later, skip space only
+ memcpy(m_buffer.data() + BURST_HEADER_SIZE, mat_start_code.data(), mat_start_code.size());
+ m_bufferCount = size;
+
+ // unless the start code falls into the padding, it's considered part of the current MAT frame
+ // Note that audio frames are not always aligned with MAT frames, so we might already have a partial
+ // frame at this point
+ m_state.matFramesize += size;
+
+ // The MAT metadata counts as padding, if we're scheduled to write any, which mean the start bytes
+ // should reduce any further padding.
+ if (m_state.padding > 0)
+ {
+ // if the header fits into the padding of the last frame, just reduce the amount of needed padding
+ if (m_state.padding > size)
+ {
+ m_state.padding -= size;
+ m_state.matFramesize = 0;
+ }
+ else
+ {
+ // otherwise, consume all padding and set the size of the next MAT frame to the remaining data
+ m_state.matFramesize = (size - m_state.padding);
+ m_state.padding = 0;
+ }
+ }
+}
+
+void CPackerMAT::WritePadding()
+{
+ if (m_state.padding == 0)
+ return;
+
+ if (!m_logPadding && m_state.padding > MAT_BUFFER_SIZE / 2)
+ {
+ m_logPadding = true;
+ CLog::Log(LOGWARNING,
+ "CPackerMAT::WritePadding: a large padding block of {} bytes is required due to "
+ "unusual timestamps",
+ m_state.padding);
+ }
+ else if (m_logPadding && m_state.padding < MAT_BUFFER_SIZE / 2)
+ m_logPadding = false;
+
+ // for padding not writes any data (nullptr) as buffer is already zeroed
+ // only counts/skip bytes
+ const int remaining = FillDataBuffer(nullptr, m_state.padding, Type::PADDING);
+
+ // not all padding could be written to the buffer, write it later
+ if (remaining >= 0)
+ {
+ m_state.padding = remaining;
+ m_state.matFramesize = 0;
+ }
+ else
+ {
+ // more padding then requested was written, eg. there was a MAT middle/end marker
+ // that needed to be written
+ m_state.padding = 0;
+ m_state.matFramesize = -remaining;
+ }
+}
+
+void CPackerMAT::AppendData(const uint8_t* data, int size, Type type)
+{
+ // for padding not write anything, only skip bytes
+ if (type == Type::DATA)
+ memcpy(m_buffer.data() + m_bufferCount, data, size);
+
+ m_state.matFramesize += size;
+ m_bufferCount += size;
+}
+
+int CPackerMAT::FillDataBuffer(const uint8_t* data, int size, Type type)
+{
+ if (GetCount() >= MAT_BUFFER_LIMIT)
+ return size;
+
+ int remaining = size;
+
+ // Write MAT middle marker, if needed
+ // The MAT middle marker always needs to be in the exact same spot, any audio data will be split.
+ // If we're currently writing padding, then the marker will be considered as padding data and
+ // reduce the amount of padding still required.
+ if (GetCount() <= MAT_POS_MIDDLE && GetCount() + size > MAT_POS_MIDDLE)
+ {
+ // write as much data before the middle code as we can
+ int nBytesBefore = MAT_POS_MIDDLE - GetCount();
+ AppendData(data, nBytesBefore, type);
+ remaining -= nBytesBefore;
+
+ // write the MAT middle code
+ AppendData(mat_middle_code.data(), mat_middle_code.size(), Type::DATA);
+
+ // if we're writing padding, deduct the size of the code from it
+ if (type == Type::PADDING)
+ remaining -= mat_middle_code.size();
+
+ // write remaining data after the MAT marker
+ if (remaining > 0)
+ remaining = FillDataBuffer(data + nBytesBefore, remaining, type);
+
+ return remaining;
+ }
+
+ // not enough room in the buffer to write all the data,
+ // write as much as we can and add the MAT footer
+ if (GetCount() + size >= MAT_BUFFER_LIMIT)
+ {
+ // write as much data before the middle code as we can
+ int nBytesBefore = MAT_BUFFER_LIMIT - GetCount();
+ AppendData(data, nBytesBefore, type);
+ remaining -= nBytesBefore;
+
+ // write the MAT end code
+ AppendData(mat_end_code.data(), mat_end_code.size(), Type::DATA);
+
+ assert(GetCount() == MAT_BUFFER_SIZE);
+
+ // MAT markers don't displace padding, so reduce the amount of padding
+ if (type == Type::PADDING)
+ remaining -= mat_end_code.size();
+
+ // any remaining data will be written in future calls
+ return remaining;
+ }
+
+ AppendData(data, size, type);
+
+ return 0;
+}
+
+void CPackerMAT::FlushPacket()
+{
+ if (GetCount() == 0)
+ return;
+
+ assert(GetCount() == MAT_BUFFER_SIZE);
+
+ // normal number of samples per frame
+ const uint16_t frameSamples = 40 << (m_state.ratebits & 7);
+ const uint32_t MATSamples = (frameSamples * 24);
+
+ // push MAT packet to output queue
+ m_outputQueue.emplace_back(std::move(m_buffer));
+
+ // we expect 24 frames per MAT frame, so calculate an offset from that
+ // this is done after delivery, because it modifies the duration of the frame,
+ // eg. the start of the next frame
+ if (MATSamples != m_state.samples)
+ m_state.numberOfSamplesOffset += m_state.samples - MATSamples;
+
+ m_state.samples = 0;
+
+ m_buffer.clear();
+ m_bufferCount = 0;
+}
+
+TrueHDMajorSyncInfo CPackerMAT::ParseTrueHDMajorSyncHeaders(const uint8_t* p, int buffsize) const
+{
+ TrueHDMajorSyncInfo info;
+
+ if (buffsize < 32)
+ return {};
+
+ // parse major sync and look for a restart header
+ int majorSyncSize = 28;
+ if (p[29] & 1) // restart header exists
+ {
+ int extensionSize = p[30] >> 4; // calculate headers size
+ majorSyncSize += 2 + extensionSize * 2;
+ }
+
+ CBitStream bs(p + 4, buffsize - 4);
+
+ bs.SkipBits(32); // format_sync
+
+ info.ratebits = bs.ReadBits(4); // ratebits
+ info.valid = true;
+
+ // (1) 6ch_multichannel_type
+ // (1) 8ch_multichannel_type
+ // (2) reserved
+ // (2) 2ch_presentation_channel_modifier
+ // (2) 6ch_presentation_channel_modifier
+ // (5) 6ch_presentation_channel_assignment
+ // (2) 8ch_presentation_channel_modifier
+ // (13) 8ch_presentation_channel_assignment
+ // (16) signature
+ // (16) flags
+ // (16) reserved
+ // (1) variable_rate
+ // (15) peak_data_rate
+ bs.SkipBits(1 + 1 + 2 + 2 + 2 + 5 + 2 + 13 + 16 + 16 + 16 + 1 + 15);
+
+ const int numSubstreams = bs.ReadBits(4);
+
+ bs.SkipBits(4 + (majorSyncSize - 17) * 8);
+
+ // substream directory
+ for (int i = 0; i < numSubstreams; i++)
+ {
+ int extraSubstreamWord = bs.ReadBits(1);
+ // (1) restart_nonexistent
+ // (1) crc_present
+ // (1) reserved
+ // (12) substream_end_ptr
+ bs.SkipBits(15);
+ if (extraSubstreamWord)
+ bs.SkipBits(16); // drc_gain_update, drc_time_update, reserved
+ }
+
+ // substream segments
+ for (int i = 0; i < numSubstreams; i++)
+ {
+ if (bs.ReadBits(1))
+ { // block_header_exists
+ if (bs.ReadBits(1))
+ { // restart_header_exists
+ bs.SkipBits(14); // restart_sync_word
+ info.outputTiming = bs.ReadBits(16);
+ info.outputTimingPresent = true;
+ // XXX: restart header
+ }
+ // XXX: Block header
+ }
+ // XXX: All blocks, all substreams?
+ break;
+ }
+
+ return info;
+}
diff --git a/xbmc/cores/AudioEngine/Utils/PackerMAT.h b/xbmc/cores/AudioEngine/Utils/PackerMAT.h
new file mode 100644
index 0000000000..d2bd787aca
--- /dev/null
+++ b/xbmc/cores/AudioEngine/Utils/PackerMAT.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include <deque>
+#include <stdint.h>
+#include <vector>
+
+struct TrueHDMajorSyncInfo
+{
+ int ratebits{0};
+ uint16_t outputTiming{0};
+ bool outputTimingPresent{false};
+ bool valid{false};
+};
+
+enum class Type
+{
+ PADDING,
+ DATA,
+};
+
+class CPackerMAT
+{
+public:
+ CPackerMAT();
+ ~CPackerMAT() = default;
+
+ bool PackTrueHD(const uint8_t* data, int size);
+ bool HaveOutput() const { return !m_outputQueue.empty(); }
+ std::vector<uint8_t> GetOutputFrame();
+
+private:
+ struct MATState
+ {
+ bool init; // differentiates the first header
+
+ // audio_sampling_frequency:
+ // 0 -> 48 kHz
+ // 1 -> 96 kHz
+ // 2 -> 192 kHz
+ // 8 -> 44.1 kHz
+ // 9 -> 88.2 kHz
+ // 10 -> 176.4 kHz
+ int ratebits;
+
+ // Output timing obtained parsing TrueHD major sync headers (when available) or
+ // inferred increasing a counter the rest of the time.
+ uint16_t outputTiming;
+ bool outputTimingValid;
+
+ // Input timing of audio unit (obtained of each audio unit) and used to calculate padding
+ // bytes. On the contrary of outputTiming, frametime is present in all audio units.
+ uint16_t prevFrametime;
+ bool prevFrametimeValid;
+
+ uint32_t matFramesize; // size in bytes of current MAT frame
+ uint32_t prevMatFramesize; // size in bytes of previous MAT frame
+
+ uint32_t padding; // padding bytes pending to write
+ uint32_t samples; // number of samples accumulated in current MAT frame
+ int numberOfSamplesOffset; // offset respect number of samples in a standard MAT frame (40 * 24)
+ };
+
+ void WriteHeader();
+ void WritePadding();
+ void AppendData(const uint8_t* data, int size, Type type);
+ uint32_t GetCount() const { return m_bufferCount; }
+ int FillDataBuffer(const uint8_t* data, int size, Type type);
+ void FlushPacket();
+ TrueHDMajorSyncInfo ParseTrueHDMajorSyncHeaders(const uint8_t* p, int buffsize) const;
+
+ MATState m_state{};
+
+ bool m_logPadding{false};
+
+ uint32_t m_bufferCount{0};
+ std::vector<uint8_t> m_buffer;
+ std::deque<std::vector<uint8_t>> m_outputQueue;
+};
+
+class CBitStream
+{
+public:
+ // opens an existing byte array as bitstream
+ CBitStream(const uint8_t* bytes, int _size)
+ {
+ data = bytes;
+ size = _size;
+ }
+
+ // reads bits from bitstream
+ int ReadBits(int bits)
+ {
+ int dat = 0;
+ for (int i = index; i < index + bits; i++)
+ {
+ dat = dat * 2 + getbit(data[i / 8], i % 8);
+ }
+ index += bits;
+ return dat;
+ }
+
+ // skip bits from bitstream
+ void SkipBits(int bits) { index += bits; }
+
+private:
+ uint8_t getbit(uint8_t x, int y) { return (x >> (7 - y)) & 1; }
+
+ const uint8_t* data{nullptr};
+ int size{0};
+ int index{0};
+};
diff --git a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
index a2084261b1..b86fa65414 100644
--- a/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
+++ b/xbmc/cores/DllLoader/exports/emu_msvcrt.cpp
@@ -44,6 +44,7 @@
#endif
#include "CompileInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/cores/RetroPlayer/messages/CMakeLists.txt b/xbmc/cores/RetroPlayer/messages/CMakeLists.txt
index 41eb3d6e2f..4d68b7988a 100644
--- a/xbmc/cores/RetroPlayer/messages/CMakeLists.txt
+++ b/xbmc/cores/RetroPlayer/messages/CMakeLists.txt
@@ -20,8 +20,8 @@ set_target_properties(retroplayer_messages PROPERTIES FOLDER "Generated Messages
INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}
SOURCES "${FLATC_OUTPUTS}")
-if(TARGET flatbuffers::flatbuffers)
- set_property(TARGET flatbuffers::flatbuffers APPEND PROPERTY
+if(TARGET flatbuffers::flatheaders)
+ set_property(TARGET flatbuffers::flatheaders APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}")
- add_dependencies(retroplayer_messages flatbuffers::flatbuffers)
+ add_dependencies(retroplayer_messages flatbuffers::flatheaders)
endif()
diff --git a/xbmc/cores/RetroPlayer/rendering/RenderContext.cpp b/xbmc/cores/RetroPlayer/rendering/RenderContext.cpp
index bc5d50fee6..db954e985e 100644
--- a/xbmc/cores/RetroPlayer/rendering/RenderContext.cpp
+++ b/xbmc/cores/RetroPlayer/rendering/RenderContext.cpp
@@ -184,6 +184,21 @@ int CRenderContext::GUIShaderGetUniCol()
return -1;
}
+int CRenderContext::GUIShaderGetDepth()
+{
+#if defined(HAS_GL)
+ CRenderSystemGL* renderingGL = dynamic_cast<CRenderSystemGL*>(m_rendering);
+ if (renderingGL != nullptr)
+ return static_cast<int>(renderingGL->ShaderGetDepth());
+#elif HAS_GLES >= 2
+ CRenderSystemGLES* renderingGLES = dynamic_cast<CRenderSystemGLES*>(m_rendering);
+ if (renderingGLES != nullptr)
+ return static_cast<int>(renderingGLES->GUIShaderGetDepth());
+#endif
+
+ return -1;
+}
+
CGUIShaderDX* CRenderContext::GetGUIShader()
{
#if defined(HAS_DX)
diff --git a/xbmc/cores/RetroPlayer/rendering/RenderContext.h b/xbmc/cores/RetroPlayer/rendering/RenderContext.h
index 3f0c4c7524..0058c70b12 100644
--- a/xbmc/cores/RetroPlayer/rendering/RenderContext.h
+++ b/xbmc/cores/RetroPlayer/rendering/RenderContext.h
@@ -69,6 +69,7 @@ public:
int GUIShaderGetPos();
int GUIShaderGetCoord0();
int GUIShaderGetUniCol();
+ int GUIShaderGetDepth();
// DirectX rendering functions
CGUIShaderDX* GetGUIShader();
diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.cpp
index 97a9eaa462..8b9886b835 100644
--- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.cpp
+++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererDMA.cpp
@@ -85,6 +85,7 @@ void CRPRendererDMA::Render(uint8_t alpha)
GLint vertLoc = m_context.GUIShaderGetPos();
GLint loc = m_context.GUIShaderGetCoord0();
GLint uniColLoc = m_context.GUIShaderGetUniCol();
+ GLint depthLoc = m_context.GUIShaderGetDepth();
// Setup color values
colour[0] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::R, color);
@@ -122,6 +123,7 @@ void CRPRendererDMA::Render(uint8_t alpha)
glUniform4f(uniColLoc, (colour[0] / 255.0f), (colour[1] / 255.0f), (colour[2] / 255.0f),
(colour[3] / 255.0f));
+ glUniform1f(depthLoc, -1.0f);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0);
glDisableVertexAttribArray(vertLoc);
diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp
index f38e24006c..7929140a8a 100644
--- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp
+++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp
@@ -184,6 +184,7 @@ void CRPRendererGuiTexture::RenderInternal(bool clear, uint8_t alpha)
GLint posLoc = m_context.GUIShaderGetPos();
GLint tex0Loc = m_context.GUIShaderGetCoord0();
GLint uniColLoc = m_context.GUIShaderGetUniCol();
+ GLint depthLoc = m_context.GUIShaderGetDepth();
glGenBuffers(1, &vertexVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
@@ -212,6 +213,7 @@ void CRPRendererGuiTexture::RenderInternal(bool clear, uint8_t alpha)
glUniform4f(uniColLoc, (colour[0] / 255.0f), (colour[1] / 255.0f), (colour[2] / 255.0f),
(colour[3] / 255.0f));
+ glUniform1f(depthLoc, -1.0f);
glGenBuffers(1, &indexVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
@@ -246,6 +248,7 @@ void CRPRendererGuiTexture::RenderInternal(bool clear, uint8_t alpha)
GLint posLoc = m_context.GUIShaderGetPos();
GLint tex0Loc = m_context.GUIShaderGetCoord0();
GLint uniColLoc = m_context.GUIShaderGetUniCol();
+ GLint depthLoc = m_context.GUIShaderGetDepth();
glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, 0, ver);
glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, 0, tex);
@@ -275,6 +278,7 @@ void CRPRendererGuiTexture::RenderInternal(bool clear, uint8_t alpha)
glUniform4f(uniColLoc, (col[0] / 255.0f), (col[1] / 255.0f), (col[2] / 255.0f),
(col[3] / 255.0f));
+ glUniform1f(depthLoc, -1.0f);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
glDisableVertexAttribArray(posLoc);
diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp
index 49ff7f8ca8..c3ac4218dd 100644
--- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp
+++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGL.cpp
@@ -295,6 +295,7 @@ void CRPRendererOpenGL::Render(uint8_t alpha)
PackedVertex vertex[4];
GLint uniColLoc = m_context.GUIShaderGetUniCol();
+ GLint depthLoc = m_context.GUIShaderGetDepth();
// Setup color values
colour[0] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::R, color);
@@ -326,6 +327,7 @@ void CRPRendererOpenGL::Render(uint8_t alpha)
glUniform4f(uniColLoc, (colour[0] / 255.0f), (colour[1] / 255.0f), (colour[2] / 255.0f),
(colour[3] / 255.0f));
+ glUniform1f(depthLoc, -1.0f);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0);
diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp
index b8e4259147..d120ff7862 100644
--- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp
+++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp
@@ -128,8 +128,10 @@ void CRPRendererOpenGLES::DrawBlackBars()
m_context.EnableGUIShader(GL_SHADER_METHOD::DEFAULT);
GLint posLoc = m_context.GUIShaderGetPos();
GLint uniCol = m_context.GUIShaderGetUniCol();
+ GLint depthLoc = m_context.GUIShaderGetDepth();
glUniform4f(uniCol, m_clearColour / 255.0f, m_clearColour / 255.0f, m_clearColour / 255.0f, 1.0f);
+ glUniform1f(depthLoc, -1.0f);
// top quad
if (m_rotatedDestCoords[0].y > 0.0f)
@@ -268,6 +270,7 @@ void CRPRendererOpenGLES::Render(uint8_t alpha)
GLint vertLoc = m_context.GUIShaderGetPos();
GLint loc = m_context.GUIShaderGetCoord0();
GLint uniColLoc = m_context.GUIShaderGetUniCol();
+ GLint depthLoc = m_context.GUIShaderGetDepth();
// Setup color values
colour[0] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::R, color);
@@ -305,6 +308,7 @@ void CRPRendererOpenGLES::Render(uint8_t alpha)
glUniform4f(uniColLoc, (colour[0] / 255.0f), (colour[1] / 255.0f), (colour[2] / 255.0f),
(colour[3] / 255.0f));
+ glUniform1f(depthLoc, -1.0f);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0);
glDisableVertexAttribArray(vertLoc);
diff --git a/xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp b/xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp
index 7864a15261..a6deeddb94 100644
--- a/xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp
+++ b/xbmc/cores/RetroPlayer/savestates/SavestateDatabase.cpp
@@ -9,6 +9,7 @@
#include "SavestateDatabase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "SavestateFlatBuffer.h"
#include "URL.h"
#include "XBDateTime.h"
diff --git a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
index bd89cb4629..9989176bb4 100644
--- a/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
+++ b/xbmc/cores/VideoPlayer/DVDFileInfo.cpp
@@ -11,15 +11,18 @@
#include "DVDInputStreams/DVDInputStream.h"
#include "DVDStreamInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/StackDirectory.h"
#include "guilib/Texture.h"
+#include "network/NetworkFileItemClassify.h"
#include "pictures/Picture.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingsComponent.h"
#include "utils/MemUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#ifdef HAVE_LIBBLURAY
#include "DVDInputStreams/DVDInputStreamBluray.h"
@@ -49,6 +52,8 @@ extern "C" {
#include <libswscale/swscale.h>
}
+using namespace KODI;
+
bool CDVDFileInfo::GetFileDuration(const std::string &path, int& duration)
{
std::unique_ptr<CDVDDemux> demux;
@@ -258,12 +263,12 @@ bool CDVDFileInfo::CanExtract(const CFileItem& fileItem)
URIUtils::IsPVRRecording(fileItem.GetDynPath()) ||
// plugin path not fully resolved
URIUtils::IsPlugin(fileItem.GetDynPath()) || URIUtils::IsUPnP(fileItem.GetPath()) ||
- fileItem.IsInternetStream() || fileItem.IsDiscStub() || fileItem.IsPlayList())
+ NETWORK::IsInternetStream(fileItem) || VIDEO::IsDiscStub(fileItem) || fileItem.IsPlayList())
return false;
// mostly can't extract from discs and files from discs.
- if (URIUtils::IsBluray(fileItem.GetPath()) || fileItem.IsBDFile() || fileItem.IsDVD() ||
- fileItem.IsDiscImage() || fileItem.IsDVDFile(false, true))
+ if (URIUtils::IsBluray(fileItem.GetPath()) || VIDEO::IsBDFile(fileItem) || fileItem.IsDVD() ||
+ fileItem.IsDiscImage() || VIDEO::IsDVDFile(fileItem, false, true))
return false;
// For HTTP/FTP we only allow extraction when on a LAN
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp
index e25e35dcaf..888c7477b5 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDFactoryInputStream.cpp
@@ -9,6 +9,7 @@
#include "DVDFactoryInputStream.h"
#include "DVDInputStream.h"
+#include "network/NetworkFileItemClassify.h"
#ifdef HAVE_LIBBLURAY
#include "DVDInputStreamBluray.h"
#endif
@@ -32,9 +33,12 @@
#include "storage/MediaManager.h"
#include "utils/FileUtils.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
#include <memory>
+using namespace KODI;
+
std::shared_ptr<CDVDInputStream> CDVDFactoryInputStream::CreateInputStream(IVideoPlayer* pPlayer, const CFileItem &fileitem, bool scanforextaudio)
{
using namespace ADDON;
@@ -101,7 +105,7 @@ std::shared_ptr<CDVDInputStream> CDVDFactoryInputStream::CreateInputStream(IVide
}
#endif
- if (fileitem.IsDVDFile(false, true))
+ if (VIDEO::IsDVDFile(fileitem, false, true))
return std::make_shared<CDVDInputStreamNavigator>(pPlayer, fileitem);
else if (URIUtils::IsPVRChannel(file))
return std::make_shared<CInputStreamPVRChannel>(pPlayer, fileitem);
@@ -136,7 +140,7 @@ std::shared_ptr<CDVDInputStream> CDVDFactoryInputStream::CreateInputStream(IVide
CFileItem finalFileitem(fileitem);
- if (finalFileitem.IsInternetStream())
+ if (NETWORK::IsInternetStream(finalFileitem))
{
if (finalFileitem.ContentLookup())
{
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
index a87888c7be..8936399b94 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamBluray.cpp
@@ -27,6 +27,7 @@
#include "utils/URIUtils.h"
#include "utils/XTimeUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include <functional>
#include <limits>
@@ -37,6 +38,7 @@
#define LIBBLURAY_BYTESEEK 0
+using namespace KODI;
using namespace XFILE;
using namespace std::chrono_literals;
@@ -152,7 +154,7 @@ bool CDVDInputStreamBluray::Open()
// Check whether disc is AACS protected
CURL url3(root);
CFileItem base(url3, false);
- openDisc = base.IsProtectedBlurayDisc();
+ openDisc = VIDEO::IsProtectedBlurayDisc(base);
// check for a menu call for an image file
if (StringUtils::EqualsNoCase(filename, "menu"))
@@ -166,7 +168,7 @@ bool CDVDInputStreamBluray::Open()
// Check whether disc is AACS protected
if (!openDisc)
- openDisc = item.IsProtectedBlurayDisc();
+ openDisc = VIDEO::IsProtectedBlurayDisc(item);
if (item.IsDiscImage())
{
@@ -184,7 +186,7 @@ bool CDVDInputStreamBluray::Open()
openStream = true;
}
- else if (m_item.IsProtectedBlurayDisc())
+ else if (VIDEO::IsProtectedBlurayDisc(m_item))
{
openDisc = true;
}
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
index 4214673f08..91603ac1f0 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamFile.cpp
@@ -12,7 +12,9 @@
#include "filesystem/IFile.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
+using namespace KODI;
using namespace XFILE;
CDVDInputStreamFile::CDVDInputStreamFile(const CFileItem& fileitem, unsigned int flags)
@@ -44,8 +46,10 @@ bool CDVDInputStreamFile::Open()
unsigned int flags = m_flags;
// If this file is audio and/or video (= not a subtitle) flag to caller
- if (!m_item.IsSubtitle())
+ if (!VIDEO::IsSubtitle(m_item))
flags |= READ_AUDIO_VIDEO;
+ else
+ flags |= READ_NO_BUFFER; // disable CFileStreamBuffer for subtitles
std::string content = m_item.GetMimeType();
diff --git a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp
index 1f018617ac..3788295b01 100644
--- a/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp
+++ b/xbmc/cores/VideoPlayer/DVDInputStreams/DVDInputStreamStack.cpp
@@ -9,6 +9,7 @@
#include "DVDInputStreamStack.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/File.h"
#include "filesystem/StackDirectory.h"
#include "utils/log.h"
diff --git a/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp b/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp
index 7ac7ec7e71..a8a5e0e35f 100644
--- a/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp
+++ b/xbmc/cores/VideoPlayer/DVDSubtitles/DVDSubtitlesLibass.cpp
@@ -9,6 +9,7 @@
#include "DVDSubtitlesLibass.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "cores/VideoPlayer/Interface/TimingConstants.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/cores/VideoPlayer/VideoPlayer.cpp b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
index b43fe8c622..78e9cc3cdc 100644
--- a/xbmc/cores/VideoPlayer/VideoPlayer.cpp
+++ b/xbmc/cores/VideoPlayer/VideoPlayer.cpp
@@ -17,6 +17,7 @@
#include "DVDDemuxers/DVDFactoryDemuxer.h"
#include "DVDInputStreams/DVDFactoryInputStream.h"
#include "DVDInputStreams/DVDInputStream.h"
+#include "network/NetworkFileItemClassify.h"
#if defined(HAVE_LIBBLURAY)
#include "DVDInputStreams/DVDInputStreamBluray.h"
#endif
@@ -46,6 +47,7 @@
#include "input/actions/Action.h"
#include "input/actions/ActionIDs.h"
#include "messaging/ApplicationMessenger.h"
+#include "network/NetworkFileItemClassify.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -68,6 +70,7 @@
#include <mutex>
#include <utility>
+using namespace KODI;
using namespace std::chrono_literals;
//------------------------------------------------------------------------------
@@ -999,7 +1002,7 @@ void CVideoPlayer::OpenDefaultStreams(bool reset)
CloseStream(m_CurrentAudioID3, false);
// disable demux streams
- if (m_item.IsRemote() && m_pDemuxer)
+ if (NETWORK::IsRemote(m_item) && m_pDemuxer)
{
for (auto &stream : m_SelectionStreams.m_Streams)
{
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.cpp
index 9a8f496f96..2277962600 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.cpp
@@ -116,7 +116,7 @@ CDebugRenderer::CRenderer::CRenderer() : OVERLAY::CRenderer()
{
}
-void CDebugRenderer::CRenderer::Render(int idx)
+void CDebugRenderer::CRenderer::Render(int idx, float depth)
{
std::vector<SElement>& list = m_buffers[idx];
for (std::vector<SElement>::iterator it = list.begin(); it != list.end(); ++it)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.h
index e5a08d306f..7a5c306150 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/DebugRenderer.h
@@ -34,7 +34,7 @@ protected:
{
public:
CRenderer();
- void Render(int idx) override;
+ void Render(int idx, float depth = 1.0f) override;
void CreateSubtitlesStyle();
private:
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
index ed6052864b..e7adf42dce 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererDRMPRIMEGLES.cpp
@@ -224,8 +224,10 @@ void CRendererDRMPRIMEGLES::DrawBlackBars()
renderSystem->EnableGUIShader(ShaderMethodGLES::SM_DEFAULT);
GLint posLoc = renderSystem->GUIShaderGetPos();
GLint uniCol = renderSystem->GUIShaderGetUniCol();
+ GLint depthLoc = renderSystem->GUIShaderGetDepth();
glUniform4f(uniCol, m_clearColour / 255.0f, m_clearColour / 255.0f, m_clearColour / 255.0f, 1.0f);
+ glUniform1f(depthLoc, -1.0f);
GLuint vertexVBO;
glGenBuffers(1, &vertexVBO);
@@ -328,6 +330,7 @@ void CRendererDRMPRIMEGLES::Render(unsigned int flags, int index)
GLint vertLoc = renderSystem->GUIShaderGetPos();
GLint loc = renderSystem->GUIShaderGetCoord0();
+ GLint depthLoc = renderSystem->GUIShaderGetDepth();
// top left
vertex[0].x = m_rotatedDestCoords[0].x;
@@ -374,6 +377,8 @@ void CRendererDRMPRIMEGLES::Render(unsigned int flags, int index)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 4, idx, GL_STATIC_DRAW);
+ glUniform1f(depthLoc, -1.0f);
+
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0);
glDisableVertexAttribArray(vertLoc);
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodec.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodec.cpp
index e06a81cf18..d37d61e08d 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodec.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodec.cpp
@@ -112,8 +112,6 @@ bool CRendererMediaCodec::RenderHook(int index)
CYuvPlane &plane = m_buffers[index].fields[0][0];
CYuvPlane &planef = m_buffers[index].fields[m_currentField][0];
- glDisable(GL_DEPTH_TEST);
-
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_EXTERNAL_OES, plane.id);
@@ -139,6 +137,8 @@ bool CRendererMediaCodec::RenderHook(int index)
glUniform1f(contrastLoc, m_videoSettings.m_Contrast * 0.02f);
GLint brightnessLoc = renderSystem->GUIShaderGetBrightness();
glUniform1f(brightnessLoc, m_videoSettings.m_Brightness * 0.01f - 0.5f);
+ GLint depthLoc = renderSystem->GUIShaderGetDepth();
+ glUniform1f(depthLoc, -1.0f);
glUniformMatrix4fv(renderSystem->GUIShaderGetCoord0Matrix(), 1, GL_FALSE, m_textureMatrix);
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
index d96c29a6b7..c2fa1e125d 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.cpp
@@ -531,9 +531,56 @@ void CLinuxRendererGL::RenderUpdate(int index, int index2, bool clear, unsigned
void CLinuxRendererGL::ClearBackBuffer()
{
//set the entire backbuffer to black
- glClearColor(m_clearColour, m_clearColour, m_clearColour, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- glClearColor(0,0,0,0);
+ //if we do a two pass render, we have to draw a quad. else we might occlude OSD elements.
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_ALL_BACK_TO_FRONT)
+ {
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0xff000000);
+ }
+ else
+ {
+ ClearBackBufferQuad();
+ }
+}
+
+void CLinuxRendererGL::ClearBackBufferQuad()
+{
+ CRect windowRect(0, 0, CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth(),
+ CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight());
+ struct Svertex
+ {
+ float x, y;
+ };
+
+ std::vector<Svertex> vertices{
+ {windowRect.x1, windowRect.y2 * 2},
+ {windowRect.x1, windowRect.y1},
+ {windowRect.x2 * 2, windowRect.y1},
+ };
+
+ glDisable(GL_BLEND);
+
+ m_renderSystem->EnableShader(ShaderMethodGL::SM_DEFAULT);
+ GLint posLoc = m_renderSystem->ShaderGetPos();
+ GLint uniCol = m_renderSystem->ShaderGetUniCol();
+
+ glUniform4f(uniCol, m_clearColour / 255.0f, m_clearColour / 255.0f, m_clearColour / 255.0f, 1.0f);
+
+ GLuint vertexVBO;
+ glGenBuffers(1, &vertexVBO);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(Svertex) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
+
+ glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, sizeof(Svertex), 0);
+ glEnableVertexAttribArray(posLoc);
+
+ glDrawArrays(GL_TRIANGLES, 0, vertices.size());
+
+ glDisableVertexAttribArray(posLoc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDeleteBuffers(1, &vertexVBO);
+
+ m_renderSystem->DisableShader();
}
//draw black bars around the video quad, this is more efficient than glClear()
@@ -1047,8 +1094,6 @@ void CLinuxRendererGL::RenderSinglePass(int index, int field)
LoadShaders(field);
}
- glDisable(GL_DEPTH_TEST);
-
// Y
glActiveTexture(GL_TEXTURE0);
glBindTexture(m_textureTarget, planes[0].id);
@@ -1219,8 +1264,6 @@ void CLinuxRendererGL::RenderToFBO(int index, int field, bool weave /*= false*/)
}
}
- glDisable(GL_DEPTH_TEST);
-
// Y
glActiveTexture(GL_TEXTURE0);
glBindTexture(m_textureTarget, planes[0].id);
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h
index 31a3c273bf..da1b4f628e 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGL.h
@@ -87,6 +87,7 @@ protected:
bool Render(unsigned int flags, int renderBuffer);
void ClearBackBuffer();
+ void ClearBackBufferQuad();
void DrawBlackBars();
bool ValidateRenderer();
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp
index a0ed2c1ab4..97663f9c09 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.cpp
@@ -357,6 +357,63 @@ void CLinuxRendererGLES::Update()
ValidateRenderTarget();
}
+void CLinuxRendererGLES::ClearBackBuffer()
+{
+ //set the entire backbuffer to black
+ //if we do a two pass render, we have to draw a quad. else we might occlude OSD elements.
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_ALL_BACK_TO_FRONT)
+ {
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0xff000000);
+ }
+ else
+ {
+ ClearBackBufferQuad();
+ }
+}
+
+void CLinuxRendererGLES::ClearBackBufferQuad()
+{
+ CRect windowRect(0, 0, CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth(),
+ CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight());
+ struct Svertex
+ {
+ float x, y;
+ };
+
+ std::vector<Svertex> vertices{
+ {windowRect.x1, windowRect.y2 * 2},
+ {windowRect.x1, windowRect.y1},
+ {windowRect.x2 * 2, windowRect.y1},
+ };
+
+ glDisable(GL_BLEND);
+
+ m_renderSystem->EnableGUIShader(ShaderMethodGLES::SM_DEFAULT);
+ GLint posLoc = m_renderSystem->GUIShaderGetPos();
+ GLint uniCol = m_renderSystem->GUIShaderGetUniCol();
+ GLint depthLoc = m_renderSystem->GUIShaderGetDepth();
+
+ glUniform4f(uniCol, m_clearColour / 255.0f, m_clearColour / 255.0f, m_clearColour / 255.0f, 1.0f);
+ glUniform1f(depthLoc, -1);
+
+ GLuint vertexVBO;
+ glGenBuffers(1, &vertexVBO);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(Svertex) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
+
+ glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, sizeof(Svertex), 0);
+ glEnableVertexAttribArray(posLoc);
+
+ glDrawArrays(GL_TRIANGLES, 0, vertices.size());
+
+ glDisableVertexAttribArray(posLoc);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDeleteBuffers(1, &vertexVBO);
+
+ m_renderSystem->DisableGUIShader();
+}
+
void CLinuxRendererGLES::DrawBlackBars()
{
CRect windowRect(0, 0, CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth(),
@@ -399,8 +456,10 @@ void CLinuxRendererGLES::DrawBlackBars()
renderSystem->EnableGUIShader(ShaderMethodGLES::SM_DEFAULT);
GLint posLoc = renderSystem->GUIShaderGetPos();
GLint uniCol = renderSystem->GUIShaderGetUniCol();
+ GLint depthLoc = m_renderSystem->GUIShaderGetDepth();
glUniform4f(uniCol, m_clearColour / 255.0f, m_clearColour / 255.0f, m_clearColour / 255.0f, 1.0f);
+ glUniform1f(depthLoc, -1);
GLuint vertexVBO;
glGenBuffers(1, &vertexVBO);
@@ -431,6 +490,9 @@ void CLinuxRendererGLES::RenderUpdate(int index, int index2, bool clear, unsigne
// if its first pass, just init textures and return
if (ValidateRenderTarget())
{
+ if (clear) //if clear is set, we're expected to overwrite all backbuffer pixels, even if we have nothing to render
+ ClearBackBuffer();
+
return;
}
@@ -455,9 +517,7 @@ void CLinuxRendererGLES::RenderUpdate(int index, int index2, bool clear, unsigne
DrawBlackBars();
else
{
- glClearColor(m_clearColour, m_clearColour, m_clearColour, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- glClearColor(0, 0, 0, 0);
+ ClearBackBuffer();
}
}
@@ -489,7 +549,8 @@ void CLinuxRendererGLES::RenderUpdate(int index, int index2, bool clear, unsigne
}
}
- Render(flags, index);
+ if (!Render(flags, index) && clear)
+ ClearBackBuffer();
VerifyGLState();
glEnable(GL_BLEND);
@@ -783,7 +844,7 @@ bool CLinuxRendererGLES::UploadTexture(int index)
return ret;
}
-void CLinuxRendererGLES::Render(unsigned int flags, int index)
+bool CLinuxRendererGLES::Render(unsigned int flags, int index)
{
// obtain current field, if interlaced
if( flags & RENDER_FLAG_TOP)
@@ -802,7 +863,7 @@ void CLinuxRendererGLES::Render(unsigned int flags, int index)
// call texture load function
if (!UploadTexture(index))
{
- return;
+ return false;
}
if (RenderHook(index))
@@ -832,8 +893,13 @@ void CLinuxRendererGLES::Render(unsigned int flags, int index)
break;
}
}
+ else
+ {
+ return false;
+ }
AfterRenderHook(index);
+ return true;
}
void CLinuxRendererGLES::RenderSinglePass(int index, int field)
@@ -871,8 +937,6 @@ void CLinuxRendererGLES::RenderSinglePass(int index, int field)
LoadShaders(field);
}
- glDisable(GL_DEPTH_TEST);
-
// Y
glActiveTexture(GL_TEXTURE0);
glBindTexture(m_textureTarget, planes[0].id);
@@ -1021,8 +1085,6 @@ void CLinuxRendererGLES::RenderToFBO(int index, int field)
}
}
- glDisable(GL_DEPTH_TEST);
-
// Y
glActiveTexture(GL_TEXTURE0);
glBindTexture(m_textureTarget, planes[0].id);
@@ -1231,6 +1293,9 @@ void CLinuxRendererGLES::RenderFromFBO()
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
+ glDisableVertexAttribArray(loc);
+ glDisableVertexAttribArray(vertLoc);
+
VerifyGLState();
if (m_pVideoFilterShader)
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h
index 31157fe6a5..5fb5118fbd 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/LinuxRendererGLES.h
@@ -91,7 +91,7 @@ protected:
static const int FIELD_TOP{1};
static const int FIELD_BOT{2};
- virtual void Render(unsigned int flags, int index);
+ virtual bool Render(unsigned int flags, int index);
virtual void RenderUpdateVideo(bool clear, unsigned int flags = 0, unsigned int alpha = 255);
int NextYV12Texture();
@@ -212,5 +212,7 @@ protected:
CRect m_viewRect;
private:
+ void ClearBackBuffer();
+ void ClearBackBufferQuad();
void DrawBlackBars();
};
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.cpp
index dfd4b31227..246128003a 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.cpp
@@ -138,7 +138,7 @@ void CRenderer::ReleaseUnused()
}
}
-void CRenderer::Render(int idx)
+void CRenderer::Render(int idx, float depth)
{
std::unique_lock<CCriticalSection> lock(m_section);
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.h
index a6690004e6..a79f601af5 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.h
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRenderer.h
@@ -99,7 +99,7 @@ namespace OVERLAY {
void Notify(const Observable& obs, const ObservableMessage msg) override;
void AddOverlay(std::shared_ptr<CDVDOverlay> o, double pts, int index);
- virtual void Render(int idx);
+ virtual void Render(int idx, float depth = 0.0f);
/*!
* \brief Release resources
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp
index 3caa28e4bf..7f2debce85 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGL.cpp
@@ -293,6 +293,12 @@ void COverlayGlyphGL::Render(SRenderState& state)
GLint posLoc = renderSystem->ShaderGetPos();
GLint colLoc = renderSystem->ShaderGetCol();
GLint tex0Loc = renderSystem->ShaderGetCoord0();
+ GLint depthLoc = renderSystem->ShaderGetDepth();
+ GLint matrixUniformLoc = renderSystem->ShaderGetMatrix();
+
+ CMatrixGL matrix = glMatrixProject.Get();
+ matrix.MultMatrixf(glMatrixModview.Get());
+ glUniformMatrix4fv(matrixUniformLoc, 1, GL_FALSE, matrix);
std::vector<VERTEX> vecVertices(6 * m_vertex.size() / 4);
VERTEX* vertices = vecVertices.data();
@@ -325,6 +331,8 @@ void COverlayGlyphGL::Render(SRenderState& state)
glEnableVertexAttribArray(colLoc);
glEnableVertexAttribArray(tex0Loc);
+ glUniform1f(depthLoc, -1.0f);
+
glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
glDisableVertexAttribArray(posLoc);
@@ -396,6 +404,7 @@ void COverlayTextureGL::Render(SRenderState& state)
GLint posLoc = renderSystem->ShaderGetPos();
GLint tex0Loc = renderSystem->ShaderGetCoord0();
GLint uniColLoc = renderSystem->ShaderGetUniCol();
+ GLint depthLoc = renderSystem->ShaderGetDepth();
GLfloat col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
@@ -451,6 +460,8 @@ void COverlayTextureGL::Render(SRenderState& state)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*4, idx, GL_STATIC_DRAW);
+ glUniform1f(depthLoc, -1.0f);
+
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0);
glDisableVertexAttribArray(posLoc);
diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp
index cf3b31324a..4f4b39b038 100644
--- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp
+++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererGLES.cpp
@@ -352,6 +352,12 @@ void COverlayGlyphGLES::Render(SRenderState& state)
GLint posLoc = renderSystem->GUIShaderGetPos();
GLint colLoc = renderSystem->GUIShaderGetCol();
GLint tex0Loc = renderSystem->GUIShaderGetCoord0();
+ GLint depthLoc = renderSystem->GUIShaderGetDepth();
+ GLint matrixUniformLoc = renderSystem->GUIShaderGetMatrix();
+
+ CMatrixGL matrix = glMatrixProject.Get();
+ matrix.MultMatrixf(glMatrixModview.Get());
+ glUniformMatrix4fv(matrixUniformLoc, 1, GL_FALSE, matrix);
// stack object until VBOs will be used
std::vector<VERTEX> vecVertices(6 * m_vertex.size() / 4);
@@ -381,6 +387,8 @@ void COverlayGlyphGLES::Render(SRenderState& state)
glEnableVertexAttribArray(colLoc);
glEnableVertexAttribArray(tex0Loc);
+ glUniform1f(depthLoc, -1.0f);
+
glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
glDisableVertexAttribArray(posLoc);
@@ -443,6 +451,7 @@ void COverlayTextureGLES::Render(SRenderState& state)
GLint colLoc = renderSystem->GUIShaderGetCol();
GLint tex0Loc = renderSystem->GUIShaderGetCoord0();
GLint uniColLoc = renderSystem->GUIShaderGetUniCol();
+ GLint depthLoc = renderSystem->GUIShaderGetDepth();
GLfloat col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat ver[4][2];
@@ -458,6 +467,7 @@ void COverlayTextureGLES::Render(SRenderState& state)
glEnableVertexAttribArray(tex0Loc);
glUniform4f(uniColLoc, (col[0]), (col[1]), (col[2]), (col[3]));
+ glUniform1f(depthLoc, 1.0f);
// Setup vertex position values
ver[0][0] = ver[3][0] = rd.x1;
ver[0][1] = ver[1][1] = rd.y1;
diff --git a/xbmc/cores/paplayer/AudioDecoder.cpp b/xbmc/cores/paplayer/AudioDecoder.cpp
index 03dc907c0b..96075fd67e 100644
--- a/xbmc/cores/paplayer/AudioDecoder.cpp
+++ b/xbmc/cores/paplayer/AudioDecoder.cpp
@@ -17,11 +17,14 @@
#include "music/tags/MusicInfoTag.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
+#include "utils/URIUtils.h"
#include "utils/log.h"
#include <cmath>
#include <mutex>
+using namespace KODI;
+
CAudioDecoder::CAudioDecoder()
{
m_codec = NULL;
@@ -75,7 +78,7 @@ bool CAudioDecoder::Create(const CFileItem &file, int64_t seekOffset)
filecache = settings->GetInt(CSettings::SETTING_CACHE_HARDDISK);
else if ( file.IsOnDVD() )
filecache = settings->GetInt(CSettings::SETTING_CACHEAUDIO_DVDROM);
- else if ( file.IsOnLAN() )
+ else if (URIUtils::IsOnLAN(file.GetPath()))
filecache = settings->GetInt(CSettings::SETTING_CACHEAUDIO_LAN);
// create our codec
diff --git a/xbmc/cores/paplayer/PAPlayer.cpp b/xbmc/cores/paplayer/PAPlayer.cpp
index 9111464cdf..7dc0566f4e 100644
--- a/xbmc/cores/paplayer/PAPlayer.cpp
+++ b/xbmc/cores/paplayer/PAPlayer.cpp
@@ -20,6 +20,7 @@
#include "cores/DataCacheCore.h"
#include "cores/VideoPlayer/Process/ProcessInfo.h"
#include "messaging/ApplicationMessenger.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
@@ -32,6 +33,7 @@
#include <memory>
#include <mutex>
+using namespace KODI;
using namespace std::chrono_literals;
#define TIME_TO_CACHE_NEXT_FILE 5000 /* 5 seconds before end of song, start caching the next song */
@@ -248,8 +250,8 @@ bool PAPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options)
void PAPlayer::UpdateCrossfadeTime(const CFileItem& file)
{
// we explicitly disable crossfading for audio cds
- if (file.IsCDDA())
- m_upcomingCrossfadeMS = 0;
+ if (MUSIC::IsCDDA(file))
+ m_upcomingCrossfadeMS = 0;
else
m_upcomingCrossfadeMS = m_defaultCrossfadeMS = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_MUSICPLAYER_CROSSFADE) * 1000;
@@ -400,7 +402,7 @@ bool PAPlayer::QueueNextFileEx(const CFileItem &file, bool fadeIn)
si->m_prepareNextAtFrame = 0;
// cd drives don't really like it to be crossfaded or prepared
- if (!file.IsCDDA())
+ if (!MUSIC::IsCDDA(file))
{
if (streamTotalTime >= TIME_TO_CACHE_NEXT_FILE + m_defaultCrossfadeMS)
si->m_prepareNextAtFrame = (int)((streamTotalTime - TIME_TO_CACHE_NEXT_FILE - m_defaultCrossfadeMS) * si->m_audioFormat.m_sampleRate / 1000.0f);
diff --git a/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp b/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
index f9472c027e..fae40d82e9 100644
--- a/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
+++ b/xbmc/cores/playercorefactory/PlayerCoreFactory.cpp
@@ -16,6 +16,7 @@
#include "cores/VideoPlayer/Interface/InputStreamConstants.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "guilib/LocalizeStrings.h"
+#include "music/MusicFileItemClassify.h"
#include "profiles/ProfileManager.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
@@ -25,12 +26,15 @@
#include "utils/StringUtils.h"
#include "utils/XMLUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include <mutex>
#include <sstream>
#define PLAYERCOREFACTORY_XML "playercorefactory.xml"
+using namespace KODI;
+
CPlayerCoreFactory::CPlayerCoreFactory(const CProfileManager& profileManager)
: m_settings(CServiceBroker::GetSettingsComponent()->GetSettings()),
m_profileManager(profileManager)
@@ -141,7 +145,7 @@ void CPlayerCoreFactory::GetPlayers(const CFileItem& item, std::vector<std::stri
// "videodefaultplayer"
if (defaultInputstreamPlayerOverride == ForcedPlayer::VIDEO_DEFAULT ||
(defaultInputstreamPlayerOverride == ForcedPlayer::NONE &&
- (item.IsVideo() || (!item.IsAudio() && !item.IsGame()))))
+ (VIDEO::IsVideo(item) || (!MUSIC::IsAudio(item) && !item.IsGame()))))
{
int idx = GetPlayerIndex("videodefaultplayer");
if (idx > -1)
@@ -161,7 +165,7 @@ void CPlayerCoreFactory::GetPlayers(const CFileItem& item, std::vector<std::stri
// Set audio default player
// Pushback all audio players in case we don't know the type
if (defaultInputstreamPlayerOverride == ForcedPlayer::AUDIO_DEFAULT ||
- (defaultInputstreamPlayerOverride == ForcedPlayer::NONE && item.IsAudio()))
+ (defaultInputstreamPlayerOverride == ForcedPlayer::NONE && MUSIC::IsAudio(item)))
{
int idx = GetPlayerIndex("audiodefaultplayer");
if (idx > -1)
diff --git a/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp b/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
index cad7399346..3bee50aa06 100644
--- a/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
+++ b/xbmc/cores/playercorefactory/PlayerSelectionRule.cpp
@@ -11,18 +11,22 @@
#include "FileItem.h"
#include "ServiceBroker.h"
#include "URL.h"
+#include "music/MusicFileItemClassify.h"
+#include "network/NetworkFileItemClassify.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/RegExp.h"
#include "utils/StreamDetails.h"
#include "utils/StringUtils.h"
-#include "utils/XBMCTinyXML.h"
#include "utils/XMLUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include <algorithm>
+using namespace KODI;
+
CPlayerSelectionRule::CPlayerSelectionRule(TiXmlElement* pRule)
{
Initialize(pRule);
@@ -63,9 +67,11 @@ void CPlayerSelectionRule::Initialize(TiXmlElement* pRule)
m_videoCodec = XMLUtils::GetAttribute(pRule, "videocodec");
m_videoResolution = XMLUtils::GetAttribute(pRule, "videoresolution");
m_videoAspect = XMLUtils::GetAttribute(pRule, "videoaspect");
+ m_hdrType = XMLUtils::GetAttribute(pRule, "hdrtype");
m_bStreamDetails = m_audioCodec.length() > 0 || m_audioChannels.length() > 0 ||
- m_videoCodec.length() > 0 || m_videoResolution.length() > 0 || m_videoAspect.length() > 0;
+ m_videoCodec.length() > 0 || m_videoResolution.length() > 0 ||
+ m_videoAspect.length() > 0 || m_hdrType.length() > 0;
if (m_bStreamDetails && !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MYVIDEOS_EXTRACTFLAGS))
{
@@ -112,22 +118,22 @@ void CPlayerSelectionRule::GetPlayers(const CFileItem& item, std::vector<std::st
if (m_bStreamDetails && !item.HasVideoInfoTag())
return;
- if (m_tAudio >= 0 && (m_tAudio > 0) != item.IsAudio())
+ if (m_tAudio >= 0 && (m_tAudio > 0) != MUSIC::IsAudio(item))
return;
- if (m_tVideo >= 0 && (m_tVideo > 0) != item.IsVideo())
+ if (m_tVideo >= 0 && (m_tVideo > 0) != VIDEO::IsVideo(item))
return;
if (m_tGame >= 0 && (m_tGame > 0) != item.IsGame())
return;
- if (m_tInternetStream >= 0 && (m_tInternetStream > 0) != item.IsInternetStream())
+ if (m_tInternetStream >= 0 && (m_tInternetStream > 0) != NETWORK::IsInternetStream(item))
return;
- if (m_tRemote >= 0 && (m_tRemote > 0) != item.IsRemote())
+ if (m_tRemote >= 0 && (m_tRemote > 0) != NETWORK::IsRemote(item))
return;
- if (m_tBD >= 0 && (m_tBD > 0) != (item.IsBDFile() && item.IsOnDVD()))
+ if (m_tBD >= 0 && (m_tBD > 0) != (VIDEO::IsBDFile(item) && item.IsOnDVD()))
return;
if (m_tDVD >= 0 && (m_tDVD > 0) != item.IsDVD())
return;
- if (m_tDVDFile >= 0 && (m_tDVDFile > 0) != item.IsDVDFile())
+ if (m_tDVDFile >= 0 && (m_tDVDFile > 0) != VIDEO::IsDVDFile(item))
return;
if (m_tDiscImage >= 0 && (m_tDiscImage > 0) != item.IsDiscImage())
return;
@@ -166,6 +172,13 @@ void CPlayerSelectionRule::GetPlayers(const CFileItem& item, std::vector<std::st
if (CompileRegExp(m_videoAspect, regExp) &&
!MatchesRegExp(CStreamDetails::VideoAspectToAspectDescription(streamDetails.GetVideoAspect()), regExp))
return;
+
+ std::string hdrType{streamDetails.GetVideoHdrType()};
+ if (hdrType.length() == 0)
+ hdrType = "none";
+
+ if (CompileRegExp(m_hdrType, regExp) && !MatchesRegExp(hdrType, regExp))
+ return;
}
CURL url(item.GetDynPath());
@@ -194,5 +207,3 @@ void CPlayerSelectionRule::GetPlayers(const CFileItem& item, std::vector<std::st
players.push_back(m_playerName);
}
}
-
-
diff --git a/xbmc/cores/playercorefactory/PlayerSelectionRule.h b/xbmc/cores/playercorefactory/PlayerSelectionRule.h
index b818d8cb45..694d5c9fb6 100644
--- a/xbmc/cores/playercorefactory/PlayerSelectionRule.h
+++ b/xbmc/cores/playercorefactory/PlayerSelectionRule.h
@@ -55,6 +55,7 @@ private:
std::string m_videoCodec;
std::string m_videoResolution;
std::string m_videoAspect;
+ std::string m_hdrType;
std::string m_playerName;
diff --git a/xbmc/dialogs/GUIDialogColorPicker.cpp b/xbmc/dialogs/GUIDialogColorPicker.cpp
index b4bc59c355..58814de392 100644
--- a/xbmc/dialogs/GUIDialogColorPicker.cpp
+++ b/xbmc/dialogs/GUIDialogColorPicker.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogColorPicker.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/SpecialProtocol.h"
#include "guilib/GUIColorManager.h"
#include "guilib/GUIMessage.h"
diff --git a/xbmc/dialogs/GUIDialogContextMenu.cpp b/xbmc/dialogs/GUIDialogContextMenu.cpp
index 36d9fd1043..6ecf3d1195 100644
--- a/xbmc/dialogs/GUIDialogContextMenu.cpp
+++ b/xbmc/dialogs/GUIDialogContextMenu.cpp
@@ -28,6 +28,7 @@
#include "input/actions/Action.h"
#include "input/actions/ActionIDs.h"
#include "media/MediaLockState.h"
+#include "music/MusicFileItemClassify.h"
#include "profiles/ProfileManager.h"
#include "profiles/dialogs/GUIDialogLockSettings.h"
#include "settings/MediaSourceSettings.h"
@@ -39,6 +40,8 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
+using namespace KODI;
+
#define BACKGROUND_IMAGE 999
#define GROUP_LIST 996
#define BUTTON_TEMPLATE 1000
@@ -221,7 +224,7 @@ void CGUIDialogContextMenu::GetContextButtons(const std::string &type, const CFi
// Add buttons to the ContextMenu that should be visible for both sources and autosourced items
// Optical removable drives automatically have the static Eject button added (see CEjectDisk).
// Here we only add the eject button to HDD drives
- if (item && item->IsRemovable() && !item->IsDVD() && !item->IsCDDA())
+ if (item && item->IsRemovable() && !item->IsDVD() && !MUSIC::IsCDDA(*item))
{
buttons.Add(CONTEXT_BUTTON_EJECT_DRIVE, 13420); // Remove safely
}
diff --git a/xbmc/dialogs/GUIDialogContextMenu.h b/xbmc/dialogs/GUIDialogContextMenu.h
index 9ca6b1f22b..10385bd20e 100644
--- a/xbmc/dialogs/GUIDialogContextMenu.h
+++ b/xbmc/dialogs/GUIDialogContextMenu.h
@@ -88,6 +88,7 @@ enum CONTEXT_BUTTON
CONTEXT_BUTTON_PLAY_NEXT,
CONTEXT_BUTTON_NAVIGATE,
CONTEXT_BUTTON_MANAGE_VIDEOVERSIONS,
+ CONTEXT_BUTTON_CHOOSE_PLAYLIST,
};
class CContextButtons : public std::vector< std::pair<size_t, std::string> >
diff --git a/xbmc/dialogs/GUIDialogFileBrowser.cpp b/xbmc/dialogs/GUIDialogFileBrowser.cpp
index 9181313747..8fecfb62b6 100644
--- a/xbmc/dialogs/GUIDialogFileBrowser.cpp
+++ b/xbmc/dialogs/GUIDialogFileBrowser.cpp
@@ -10,6 +10,7 @@
#include "AutoSwitch.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogContextMenu.h"
#include "GUIDialogMediaSource.h"
#include "GUIDialogYesNo.h"
diff --git a/xbmc/dialogs/GUIDialogMediaFilter.cpp b/xbmc/dialogs/GUIDialogMediaFilter.cpp
index 14340c85bb..55b1013967 100644
--- a/xbmc/dialogs/GUIDialogMediaFilter.cpp
+++ b/xbmc/dialogs/GUIDialogMediaFilter.cpp
@@ -10,6 +10,7 @@
#include "DbUrl.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "XBDateTime.h"
diff --git a/xbmc/dialogs/GUIDialogMediaSource.cpp b/xbmc/dialogs/GUIDialogMediaSource.cpp
index 72b80bff53..0afbc2d060 100644
--- a/xbmc/dialogs/GUIDialogMediaSource.cpp
+++ b/xbmc/dialogs/GUIDialogMediaSource.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogMediaSource.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogFileBrowser.h"
#include "GUIDialogYesNo.h"
#include "PasswordManager.h"
diff --git a/xbmc/dialogs/GUIDialogSelect.cpp b/xbmc/dialogs/GUIDialogSelect.cpp
index c6add4bd16..0f99e2765b 100644
--- a/xbmc/dialogs/GUIDialogSelect.cpp
+++ b/xbmc/dialogs/GUIDialogSelect.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/GUIMessage.h"
#include "guilib/LocalizeStrings.h"
#include "input/actions/ActionIDs.h"
diff --git a/xbmc/dialogs/GUIDialogSimpleMenu.cpp b/xbmc/dialogs/GUIDialogSimpleMenu.cpp
index 0d4d11a830..fed153fb16 100644
--- a/xbmc/dialogs/GUIDialogSimpleMenu.cpp
+++ b/xbmc/dialogs/GUIDialogSimpleMenu.cpp
@@ -10,6 +10,7 @@
#include "GUIDialogSimpleMenu.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogSelect.h"
#include "ServiceBroker.h"
#include "URL.h"
@@ -25,8 +26,11 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
+using namespace KODI;
+
namespace
{
class CGetDirectoryItems : public IRunnable
@@ -48,13 +52,18 @@ protected:
};
}
-
-bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item)
+bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item, bool forceSelection /* = false */)
{
if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(CSettings::SETTING_DISC_PLAYBACK) != BD_PLAYBACK_SIMPLE_MENU)
return true;
- if (item.IsBDFile())
+ if (forceSelection && VIDEO::IsBlurayPlaylist(item))
+ {
+ item.SetProperty("save_dyn_path", item.GetDynPath()); // save for screen refresh later
+ item.SetDynPath(item.GetBlurayPath());
+ }
+
+ if (VIDEO::IsBDFile(item))
{
std::string root = URIUtils::GetParentPath(item.GetDynPath());
URIUtils::RemoveSlashAtEnd(root);
@@ -123,10 +132,14 @@ bool CGUIDialogSimpleMenu::ShowPlaySelection(CFileItem& item, const std::string&
if (item_new->m_bIsFolder == false)
{
- std::string original_path = item.GetDynPath();
+ std::string path;
+ if (item.HasProperty("save_dyn_path"))
+ path = item.GetProperty("save_dyn_path").asString();
+ else
+ path = item.GetDynPath(); // If not set above (choose playlist selected)
item.SetDynPath(item_new->GetDynPath());
item.SetProperty("get_stream_details_from_player", true);
- item.SetProperty("original_listitem_url", original_path);
+ item.SetProperty("original_listitem_url", path);
return true;
}
diff --git a/xbmc/dialogs/GUIDialogSimpleMenu.h b/xbmc/dialogs/GUIDialogSimpleMenu.h
index ed476a4d92..bf7ccae980 100644
--- a/xbmc/dialogs/GUIDialogSimpleMenu.h
+++ b/xbmc/dialogs/GUIDialogSimpleMenu.h
@@ -20,7 +20,7 @@ class CGUIDialogSimpleMenu
public:
/*! \brief Show dialog allowing selection of wanted playback item */
- static bool ShowPlaySelection(CFileItem& item);
+ static bool ShowPlaySelection(CFileItem& item, bool forceSelection = false);
static bool ShowPlaySelection(CFileItem& item, const std::string& directory);
protected:
diff --git a/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp b/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
index 98714d38dc..24a0675c40 100644
--- a/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
+++ b/xbmc/dialogs/GUIDialogSmartPlaylistEditor.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSmartPlaylistEditor.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogContextMenu.h"
#include "GUIDialogSelect.h"
#include "GUIDialogSmartPlaylistRule.h"
diff --git a/xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp b/xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
index 671219bc38..9040f48340 100644
--- a/xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
+++ b/xbmc/dialogs/GUIDialogSmartPlaylistRule.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSmartPlaylistRule.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogFileBrowser.h"
#include "GUIDialogSelect.h"
#include "ServiceBroker.h"
diff --git a/xbmc/events/windows/GUIViewStateEventLog.cpp b/xbmc/events/windows/GUIViewStateEventLog.cpp
index 1f6dd6654f..8734f12571 100644
--- a/xbmc/events/windows/GUIViewStateEventLog.cpp
+++ b/xbmc/events/windows/GUIViewStateEventLog.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateEventLog.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/WindowIDs.h"
#include "view/ViewState.h"
#include "windowing/GraphicContext.h"
diff --git a/xbmc/events/windows/GUIWindowEventLog.cpp b/xbmc/events/windows/GUIWindowEventLog.cpp
index fdd9a37b00..90e8c29f71 100644
--- a/xbmc/events/windows/GUIWindowEventLog.cpp
+++ b/xbmc/events/windows/GUIWindowEventLog.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowEventLog.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/favourites/ContextMenus.cpp b/xbmc/favourites/ContextMenus.cpp
index 4ea7af5d41..a81ba5b4cb 100644
--- a/xbmc/favourites/ContextMenus.cpp
+++ b/xbmc/favourites/ContextMenus.cpp
@@ -22,6 +22,7 @@
#include "video/guilib/VideoGUIUtils.h"
using namespace CONTEXTMENU;
+using namespace KODI;
bool CFavouriteContextMenuAction::IsVisible(const CFileItem& item) const
{
@@ -129,7 +130,7 @@ std::string CFavouritesTargetResume::GetLabel(const CFileItem& item) const
{
const std::shared_ptr<CFileItem> targetItem{ResolveFavouriteItem(item)};
if (targetItem)
- return VIDEO_UTILS::GetResumeString(*targetItem);
+ return VIDEO::UTILS::GetResumeString(*targetItem);
return {};
}
@@ -140,7 +141,7 @@ bool CFavouritesTargetResume::IsVisible(const CFileItem& item) const
{
const std::shared_ptr<CFileItem> targetItem{ResolveFavouriteItem(item)};
if (targetItem)
- return VIDEO_UTILS::GetItemResumeInformation(*targetItem).isResumable;
+ return VIDEO::UTILS::GetItemResumeInformation(*targetItem).isResumable;
}
return false;
}
@@ -157,7 +158,7 @@ bool CFavouritesTargetResume::Execute(const std::shared_ptr<CFileItem>& item) co
std::string CFavouritesTargetPlay::GetLabel(const CFileItem& item) const
{
const std::shared_ptr<CFileItem> targetItem{ResolveFavouriteItem(item)};
- if (targetItem && VIDEO_UTILS::GetItemResumeInformation(*targetItem).isResumable)
+ if (targetItem && VIDEO::UTILS::GetItemResumeInformation(*targetItem).isResumable)
return g_localizeStrings.Get(12021); // Play from beginning
return g_localizeStrings.Get(208); // Play
diff --git a/xbmc/favourites/FavouritesService.cpp b/xbmc/favourites/FavouritesService.cpp
index 97f55073c3..a5a78d1a02 100644
--- a/xbmc/favourites/FavouritesService.cpp
+++ b/xbmc/favourites/FavouritesService.cpp
@@ -14,6 +14,7 @@
#include "Util.h"
#include "favourites/FavouritesURL.h"
#include "input/WindowTranslator.h"
+#include "music/MusicFileItemClassify.h"
#include "profiles/ProfileManager.h"
#include "settings/SettingsComponent.h"
#include "utils/ContentUtils.h"
@@ -21,9 +22,12 @@
#include "utils/URIUtils.h"
#include "utils/XBMCTinyXML2.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include <mutex>
+using namespace KODI;
+
namespace
{
bool IsMediasourceOfFavItemUnlocked(const std::shared_ptr<CFileItem>& item)
@@ -71,14 +75,14 @@ bool IsMediasourceOfFavItemUnlocked(const std::shared_ptr<CFileItem>& item)
if (action == CFavouritesURL::Action::PLAY_MEDIA)
{
- if (itemToCheck.IsVideo())
+ if (VIDEO::IsVideo(itemToCheck))
{
if (!profileManager->GetCurrentProfile().videoLocked())
return g_passwordManager.IsMediaFileUnlocked("video", itemToCheck.GetPath());
return false;
}
- else if (itemToCheck.IsAudio())
+ else if (MUSIC::IsAudio(itemToCheck))
{
if (!profileManager->GetCurrentProfile().musicLocked())
return g_passwordManager.IsMediaFileUnlocked("music", itemToCheck.GetPath());
diff --git a/xbmc/favourites/FavouritesService.h b/xbmc/favourites/FavouritesService.h
index ccda06253d..468961ecb3 100644
--- a/xbmc/favourites/FavouritesService.h
+++ b/xbmc/favourites/FavouritesService.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "threads/CriticalSection.h"
#include "utils/EventStream.h"
diff --git a/xbmc/favourites/GUIViewStateFavourites.cpp b/xbmc/favourites/GUIViewStateFavourites.cpp
index 7bb5ff1195..3343167b5c 100644
--- a/xbmc/favourites/GUIViewStateFavourites.cpp
+++ b/xbmc/favourites/GUIViewStateFavourites.cpp
@@ -8,7 +8,7 @@
#include "GUIViewStateFavourites.h"
-#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/WindowIDs.h"
CGUIViewStateFavourites::CGUIViewStateFavourites(const CFileItemList& items) : CGUIViewState(items)
diff --git a/xbmc/favourites/GUIWindowFavourites.cpp b/xbmc/favourites/GUIWindowFavourites.cpp
index 3dabdb009b..de3d25de37 100644
--- a/xbmc/favourites/GUIWindowFavourites.cpp
+++ b/xbmc/favourites/GUIWindowFavourites.cpp
@@ -27,6 +27,8 @@
#include "video/guilib/VideoPlayActionProcessor.h"
#include "video/guilib/VideoSelectActionProcessor.h"
+using namespace KODI;
+
CGUIWindowFavourites::CGUIWindowFavourites()
: CGUIMediaWindow(WINDOW_FAVOURITES, "MyFavourites.xml")
{
@@ -167,7 +169,7 @@ bool CGUIWindowFavourites::OnAction(const CAction& action)
const auto item{std::make_shared<CFileItem>(*target)};
// video play action setting is for files and folders...
- if (item->HasVideoInfoTag() || (item->m_bIsFolder && VIDEO_UTILS::IsItemPlayable(*item)))
+ if (item->HasVideoInfoTag() || (item->m_bIsFolder && VIDEO::UTILS::IsItemPlayable(*item)))
{
CVideoPlayActionProcessor proc{item};
if (proc.ProcessDefaultAction())
diff --git a/xbmc/filesystem/AddonsDirectory.cpp b/xbmc/filesystem/AddonsDirectory.cpp
index 1439ae054b..aba97cae08 100644
--- a/xbmc/filesystem/AddonsDirectory.cpp
+++ b/xbmc/filesystem/AddonsDirectory.cpp
@@ -9,6 +9,7 @@
#include "AddonsDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "addons/AddonDatabase.h"
@@ -789,29 +790,27 @@ void CAddonsDirectory::GenerateAddonListing(const CURL& path,
addon->Version());
bool disabled = CServiceBroker::GetAddonMgr().IsAddonDisabled(addon->ID());
- std::function<bool(bool)> CheckOutdatedOrUpdate = [&](bool checkOutdated) -> bool {
- auto mapEntry = addonsWithUpdate.find(addon->ID());
- if (mapEntry != addonsWithUpdate.end())
- {
- const std::shared_ptr<IAddon>& checkedObject =
- checkOutdated ? mapEntry->second.m_installed : mapEntry->second.m_update;
-
- return (checkedObject->Origin() == addon->Origin() &&
- checkedObject->Version() == addon->Version());
- }
- return false;
- };
-
- bool isUpdate = CheckOutdatedOrUpdate(false); // check if it's an available update
- bool hasUpdate = CheckOutdatedOrUpdate(true); // check if it's an outdated addon
-
+ bool isUpdate{false};
+ bool hasUpdate{false};
std::string validUpdateVersion;
std::string validUpdateOrigin;
- if (hasUpdate)
+
+ auto _ = addonsWithUpdate.find(addon->ID());
+ if (_ != addonsWithUpdate.end())
{
- auto mapEntry = addonsWithUpdate.find(addon->ID());
- validUpdateVersion = mapEntry->second.m_update->Version().asString();
- validUpdateOrigin = mapEntry->second.m_update->Origin();
+ auto [installed, update] = _->second;
+
+ auto CheckAddon = [&addon](const std::shared_ptr<IAddon>& _)
+ { return _->Origin() == addon->Origin() && _->Version() == addon->Version(); };
+
+ isUpdate = CheckAddon(update); // check if listed add-on is update to an installed add-on
+ hasUpdate = CheckAddon(installed); // check if installed add-on has an update available
+
+ if (hasUpdate)
+ {
+ validUpdateVersion = update->Version().asString();
+ validUpdateOrigin = update->Origin();
+ }
}
bool fromOfficialRepo = CAddonRepos::IsFromOfficialRepo(addon, CheckAddonPath::CHOICE_NO);
diff --git a/xbmc/filesystem/AudioBookFileDirectory.cpp b/xbmc/filesystem/AudioBookFileDirectory.cpp
index 4b56c6ccc2..2ca214c74e 100644
--- a/xbmc/filesystem/AudioBookFileDirectory.cpp
+++ b/xbmc/filesystem/AudioBookFileDirectory.cpp
@@ -8,6 +8,7 @@
#include "AudioBookFileDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "TextureDatabase.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/filesystem/BlurayCallback.cpp b/xbmc/filesystem/BlurayCallback.cpp
index 4849eef1a7..72b745381a 100644
--- a/xbmc/filesystem/BlurayCallback.cpp
+++ b/xbmc/filesystem/BlurayCallback.cpp
@@ -9,6 +9,7 @@
#include "BlurayCallback.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "filesystem/File.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/BlurayDirectory.cpp b/xbmc/filesystem/BlurayDirectory.cpp
index b6c339a110..322b662fd9 100644
--- a/xbmc/filesystem/BlurayDirectory.cpp
+++ b/xbmc/filesystem/BlurayDirectory.cpp
@@ -9,6 +9,7 @@
#include "File.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LangInfo.h"
#include "URL.h"
#include "filesystem/BlurayCallback.h"
diff --git a/xbmc/filesystem/CDDADirectory.cpp b/xbmc/filesystem/CDDADirectory.cpp
index 9b6beaaeea..8520347108 100644
--- a/xbmc/filesystem/CDDADirectory.cpp
+++ b/xbmc/filesystem/CDDADirectory.cpp
@@ -10,6 +10,7 @@
#include "File.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "music/MusicDatabase.h"
#include "storage/MediaManager.h"
diff --git a/xbmc/filesystem/DAVDirectory.cpp b/xbmc/filesystem/DAVDirectory.cpp
index 0a203e7807..08905fca31 100644
--- a/xbmc/filesystem/DAVDirectory.cpp
+++ b/xbmc/filesystem/DAVDirectory.cpp
@@ -12,6 +12,7 @@
#include "DAVCommon.h"
#include "DAVFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/Directorization.h b/xbmc/filesystem/Directorization.h
index f413635e6d..d41c71bae9 100644
--- a/xbmc/filesystem/Directorization.h
+++ b/xbmc/filesystem/Directorization.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/CharsetConverter.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/Directory.cpp b/xbmc/filesystem/Directory.cpp
index fbcdb4d0d4..a9cedab793 100644
--- a/xbmc/filesystem/Directory.cpp
+++ b/xbmc/filesystem/Directory.cpp
@@ -12,6 +12,7 @@
#include "DirectoryFactory.h"
#include "FileDirectoryFactory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PasswordManager.h"
#include "ServiceBroker.h"
#include "URL.h"
@@ -19,13 +20,16 @@
#include "dialogs/GUIDialogBusy.h"
#include "guilib/GUIWindowManager.h"
#include "messaging/ApplicationMessenger.h"
+#include "music/MusicFileItemClassify.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/Job.h"
#include "utils/JobManager.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
+using namespace KODI;
using namespace XFILE;
using namespace std::chrono_literals;
@@ -282,7 +286,8 @@ bool CDirectory::GetDirectory(const CURL& url,
// Should any of the files we read be treated as a directory?
// Disable for database folders, as they already contain the extracted items
- if (!(hints.flags & DIR_FLAG_NO_FILE_DIRS) && !items.IsMusicDb() && !items.IsVideoDb() && !items.IsSmartPlayList())
+ if (!(hints.flags & DIR_FLAG_NO_FILE_DIRS) && !MUSIC::IsMusicDb(items) &&
+ !VIDEO::IsVideoDb(items) && !items.IsSmartPlayList())
FilterFileDirectories(items, hints.mask);
// Correct items for path substitution
diff --git a/xbmc/filesystem/DirectoryCache.cpp b/xbmc/filesystem/DirectoryCache.cpp
index f3fd1fb7ae..f1053a904b 100644
--- a/xbmc/filesystem/DirectoryCache.cpp
+++ b/xbmc/filesystem/DirectoryCache.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/EventsDirectory.cpp b/xbmc/filesystem/EventsDirectory.cpp
index d21261944b..bc8cfdf0af 100644
--- a/xbmc/filesystem/EventsDirectory.cpp
+++ b/xbmc/filesystem/EventsDirectory.cpp
@@ -10,6 +10,7 @@
#include "EventsDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "events/EventLog.h"
diff --git a/xbmc/filesystem/FTPDirectory.cpp b/xbmc/filesystem/FTPDirectory.cpp
index 46d3d7d748..2b7117a7a8 100644
--- a/xbmc/filesystem/FTPDirectory.cpp
+++ b/xbmc/filesystem/FTPDirectory.cpp
@@ -11,6 +11,7 @@
#include "CurlFile.h"
#include "FTPParse.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/CharsetConverter.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/File.cpp b/xbmc/filesystem/File.cpp
index fe1e60c090..cfea9ac4a1 100644
--- a/xbmc/filesystem/File.cpp
+++ b/xbmc/filesystem/File.cpp
@@ -386,6 +386,9 @@ bool CFile::Open(const CURL& file, const unsigned int flags)
bool CFile::ShouldUseStreamBuffer(const CURL& url)
{
+ if (m_flags & READ_NO_BUFFER)
+ return false;
+
if (m_flags & READ_CHUNKED || m_pFile->GetChunkSize() > 0)
return true;
diff --git a/xbmc/filesystem/FileDirectoryFactory.cpp b/xbmc/filesystem/FileDirectoryFactory.cpp
index a4e0f3fea6..45852d2707 100644
--- a/xbmc/filesystem/FileDirectoryFactory.cpp
+++ b/xbmc/filesystem/FileDirectoryFactory.cpp
@@ -8,6 +8,8 @@
#include "FileDirectoryFactory.h"
+#include "music/MusicFileItemClassify.h"
+
#if defined(HAS_ISO9660PP)
#include "ISO9660Directory.h"
#endif
@@ -39,6 +41,7 @@
#include "utils/log.h"
using namespace ADDON;
+using namespace KODI;
using namespace KODI::ADDONS;
using namespace XFILE;
using namespace PLAYLIST;
@@ -235,11 +238,11 @@ IFileDirectory* CFileDirectoryFactory::Create(const CURL& url, CFileItem* pItem,
return NULL;
}
- if (pItem->IsAudioBook())
+ if (MUSIC::IsAudioBook(*pItem))
{
if (!pItem->HasMusicInfoTag() || pItem->GetEndOffset() <= 0)
{
- std::unique_ptr<CAudioBookFileDirectory> pDir(new CAudioBookFileDirectory);
+ auto pDir = std::make_unique<CAudioBookFileDirectory>();
if (pDir->ContainsFiles(url))
return pDir.release();
}
diff --git a/xbmc/filesystem/HTTPDirectory.cpp b/xbmc/filesystem/HTTPDirectory.cpp
index 0097b7f15c..1db70696d1 100644
--- a/xbmc/filesystem/HTTPDirectory.cpp
+++ b/xbmc/filesystem/HTTPDirectory.cpp
@@ -10,6 +10,7 @@
#include "CurlFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "settings/AdvancedSettings.h"
diff --git a/xbmc/filesystem/IFileTypes.h b/xbmc/filesystem/IFileTypes.h
index 4f594ca291..1f89350cc9 100644
--- a/xbmc/filesystem/IFileTypes.h
+++ b/xbmc/filesystem/IFileTypes.h
@@ -40,6 +40,9 @@ namespace XFILE
/* indicate that caller want to reopen a file if its already open */
static const unsigned int READ_REOPEN = 0x100;
+/* indicate that caller want open a file without intermediate buffer regardless to file type */
+ static const unsigned int READ_NO_BUFFER = 0x200;
+
struct SNativeIoControl
{
unsigned long int request;
diff --git a/xbmc/filesystem/ISO9660Directory.cpp b/xbmc/filesystem/ISO9660Directory.cpp
index 542f12c577..a396b996b0 100644
--- a/xbmc/filesystem/ISO9660Directory.cpp
+++ b/xbmc/filesystem/ISO9660Directory.cpp
@@ -9,6 +9,7 @@
#include "ISO9660Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/LibraryDirectory.cpp b/xbmc/filesystem/LibraryDirectory.cpp
index 8f814950ae..ec5a16bfc0 100644
--- a/xbmc/filesystem/LibraryDirectory.cpp
+++ b/xbmc/filesystem/LibraryDirectory.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "SmartPlaylistDirectory.h"
#include "URL.h"
diff --git a/xbmc/filesystem/MultiPathDirectory.cpp b/xbmc/filesystem/MultiPathDirectory.cpp
index 4cdcfcc4ce..b57dd98427 100644
--- a/xbmc/filesystem/MultiPathDirectory.cpp
+++ b/xbmc/filesystem/MultiPathDirectory.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory.cpp b/xbmc/filesystem/MusicDatabaseDirectory.cpp
index f998d559f7..0365f86617 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory.cpp
@@ -9,6 +9,7 @@
#include "MusicDatabaseDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "MusicDatabaseDirectory/QueryParams.h"
#include "ServiceBroker.h"
#include "filesystem/File.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp
index 00e1bce6f3..cb143c1ecc 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNode.cpp
@@ -25,6 +25,7 @@
#include "DirectoryNodeSongTop100.h"
#include "DirectoryNodeTop100.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "URL.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp
index f274b59341..013c30bd65 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyAdded.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeAlbumRecentlyAdded.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDatabase.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp
index 77940c27f1..8080d5e7e0 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumRecentlyPlayed.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeAlbumRecentlyPlayed.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDatabase.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp
index 88ffaff77a..753b756ac8 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeAlbumTop100.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeAlbumTop100.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "music/MusicDatabase.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp
index fefeb6d666..cca955e4b7 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDatabase.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp
index fff9228b58..36bacfeb55 100644
--- a/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp
+++ b/xbmc/filesystem/MusicDatabaseDirectory/DirectoryNodeTop100.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTop100.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicFileDirectory.cpp b/xbmc/filesystem/MusicFileDirectory.cpp
index b3c7749c47..51340b54eb 100644
--- a/xbmc/filesystem/MusicFileDirectory.cpp
+++ b/xbmc/filesystem/MusicFileDirectory.cpp
@@ -9,6 +9,7 @@
#include "MusicFileDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/MusicSearchDirectory.cpp b/xbmc/filesystem/MusicSearchDirectory.cpp
index 1d1868ab1a..2f8c8200cc 100644
--- a/xbmc/filesystem/MusicSearchDirectory.cpp
+++ b/xbmc/filesystem/MusicSearchDirectory.cpp
@@ -9,6 +9,7 @@
#include "MusicSearchDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDatabase.h"
diff --git a/xbmc/filesystem/NFSDirectory.cpp b/xbmc/filesystem/NFSDirectory.cpp
index 7feba534c7..6d3588dccc 100644
--- a/xbmc/filesystem/NFSDirectory.cpp
+++ b/xbmc/filesystem/NFSDirectory.cpp
@@ -13,6 +13,7 @@
#endif
#include "FileItem.h"
+#include "FileItemList.h"
#include "NFSDirectory.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/PlaylistDirectory.cpp b/xbmc/filesystem/PlaylistDirectory.cpp
index 8be88dc581..f656c77dab 100644
--- a/xbmc/filesystem/PlaylistDirectory.cpp
+++ b/xbmc/filesystem/PlaylistDirectory.cpp
@@ -9,6 +9,7 @@
#include "PlaylistDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/filesystem/PlaylistFileDirectory.cpp b/xbmc/filesystem/PlaylistFileDirectory.cpp
index 2bdb243680..108c9c9a65 100644
--- a/xbmc/filesystem/PlaylistFileDirectory.cpp
+++ b/xbmc/filesystem/PlaylistFileDirectory.cpp
@@ -9,6 +9,7 @@
#include "PlaylistFileDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/File.h"
#include "playlists/PlayList.h"
diff --git a/xbmc/filesystem/PluginDirectory.cpp b/xbmc/filesystem/PluginDirectory.cpp
index cf3ded1286..4269fa4236 100644
--- a/xbmc/filesystem/PluginDirectory.cpp
+++ b/xbmc/filesystem/PluginDirectory.cpp
@@ -9,6 +9,7 @@
#include "PluginDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "addons/AddonInstaller.h"
diff --git a/xbmc/filesystem/RSSDirectory.cpp b/xbmc/filesystem/RSSDirectory.cpp
index 65bc876c6c..ac0a704221 100644
--- a/xbmc/filesystem/RSSDirectory.cpp
+++ b/xbmc/filesystem/RSSDirectory.cpp
@@ -10,6 +10,7 @@
#include "CurlFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "settings/AdvancedSettings.h"
diff --git a/xbmc/filesystem/ResourceDirectory.cpp b/xbmc/filesystem/ResourceDirectory.cpp
index c3623d0ce0..6526fb56be 100644
--- a/xbmc/filesystem/ResourceDirectory.cpp
+++ b/xbmc/filesystem/ResourceDirectory.cpp
@@ -9,6 +9,7 @@
#include "ResourceDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/Directory.h"
#include "filesystem/ResourceFile.h"
diff --git a/xbmc/filesystem/SmartPlaylistDirectory.cpp b/xbmc/filesystem/SmartPlaylistDirectory.cpp
index a45e796071..b3d361ecc2 100644
--- a/xbmc/filesystem/SmartPlaylistDirectory.cpp
+++ b/xbmc/filesystem/SmartPlaylistDirectory.cpp
@@ -9,6 +9,7 @@
#include "SmartPlaylistDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "filesystem/File.h"
diff --git a/xbmc/filesystem/SourcesDirectory.cpp b/xbmc/filesystem/SourcesDirectory.cpp
index b83ee2ed49..166861e323 100644
--- a/xbmc/filesystem/SourcesDirectory.cpp
+++ b/xbmc/filesystem/SourcesDirectory.cpp
@@ -9,17 +9,22 @@
#include "SourcesDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
#include "guilib/TextureManager.h"
#include "media/MediaLockState.h"
+#include "music/MusicFileItemClassify.h"
+#include "network/NetworkFileItemClassify.h"
#include "profiles/ProfileManager.h"
#include "settings/MediaSourceSettings.h"
#include "storage/MediaManager.h"
#include "utils/FileUtils.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
+using namespace KODI;
using namespace XFILE;
CSourcesDirectory::CSourcesDirectory(void) = default;
@@ -68,12 +73,10 @@ bool CSourcesDirectory::GetDirectory(const VECSOURCES &sources, CFileItemList &i
else if ( pItem->IsPath("special://musicplaylists/")
|| pItem->IsPath("special://videoplaylists/"))
strIcon = "DefaultPlaylist.png";
- else if ( pItem->IsVideoDb()
- || pItem->IsMusicDb()
- || pItem->IsPlugin()
- || pItem->IsPath("musicsearch://"))
+ else if (VIDEO::IsVideoDb(*pItem) || MUSIC::IsMusicDb(*pItem) || pItem->IsPlugin() ||
+ pItem->IsPath("musicsearch://"))
strIcon = "DefaultFolder.png";
- else if (pItem->IsRemote())
+ else if (NETWORK::IsRemote(*pItem))
strIcon = "DefaultNetwork.png";
else if (pItem->IsISO9660())
strIcon = "DefaultDVDRom.png";
@@ -81,7 +84,7 @@ bool CSourcesDirectory::GetDirectory(const VECSOURCES &sources, CFileItemList &i
strIcon = "DefaultDVDFull.png";
else if (pItem->IsBluray())
strIcon = "DefaultBluray.png";
- else if (pItem->IsCDDA())
+ else if (MUSIC::IsCDDA(*pItem))
strIcon = "DefaultCDDA.png";
else if (pItem->IsRemovable() && CServiceBroker::GetGUI()->GetTextureManager().HasTexture("DefaultRemovableDisk.png"))
strIcon = "DefaultRemovableDisk.png";
diff --git a/xbmc/filesystem/SpecialProtocolDirectory.cpp b/xbmc/filesystem/SpecialProtocolDirectory.cpp
index e4a970ea99..d1af8b0345 100644
--- a/xbmc/filesystem/SpecialProtocolDirectory.cpp
+++ b/xbmc/filesystem/SpecialProtocolDirectory.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "SpecialProtocol.h"
#include "URL.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/StackDirectory.cpp b/xbmc/filesystem/StackDirectory.cpp
index 58cbe9dff9..9b6aae53b0 100644
--- a/xbmc/filesystem/StackDirectory.cpp
+++ b/xbmc/filesystem/StackDirectory.cpp
@@ -9,6 +9,7 @@
#include "StackDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "settings/AdvancedSettings.h"
diff --git a/xbmc/filesystem/UDFDirectory.cpp b/xbmc/filesystem/UDFDirectory.cpp
index 236b281303..b22b496d1d 100644
--- a/xbmc/filesystem/UDFDirectory.cpp
+++ b/xbmc/filesystem/UDFDirectory.cpp
@@ -12,6 +12,7 @@
#include "UDFDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "Util.h"
#include "filesystem/UDFBlockInput.h"
diff --git a/xbmc/filesystem/UPnPDirectory.cpp b/xbmc/filesystem/UPnPDirectory.cpp
index 4d6608acfa..2b2af57598 100644
--- a/xbmc/filesystem/UPnPDirectory.cpp
+++ b/xbmc/filesystem/UPnPDirectory.cpp
@@ -13,6 +13,7 @@
#include "UPnPDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "network/upnp/UPnP.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory.cpp b/xbmc/filesystem/VideoDatabaseDirectory.cpp
index 2c9caa7080..4242b095ce 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory.cpp
@@ -10,6 +10,7 @@
#include "File.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "VideoDatabaseDirectory/QueryParams.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp
index b62839c9bc..f181b4514a 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNode.cpp
@@ -24,6 +24,7 @@
#include "DirectoryNodeTitleTvShows.h"
#include "DirectoryNodeTvShowsOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "URL.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp
index 9f629baa69..c75471cb0f 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeEpisodes.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeEpisodes.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp
index 044f8b3c74..f0a652232e 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeInProgressTvShows.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeInProgressTvShows.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "video/VideoDatabase.h"
using namespace XFILE::VIDEODATABASEDIRECTORY;
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp
index 9f415d09da..33d70051d8 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMoviesOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeMoviesOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp
index b71d8f1d2b..9c7290abc5 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeMusicVideosOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeMusicVideosOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
#include "video/VideoDbUrl.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp
index b52ae24dc5..0aeed45edc 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/LocalizeStrings.h"
#include "settings/Settings.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp
index fe50dad926..317c761002 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedEpisodes.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeRecentlyAddedEpisodes.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "video/VideoDatabase.h"
using namespace XFILE::VIDEODATABASEDIRECTORY;
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp
index 202d6f7b4a..41b372beb6 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMovies.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeRecentlyAddedMovies.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "video/VideoDatabase.h"
using namespace XFILE::VIDEODATABASEDIRECTORY;
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp
index d8ba5ef74d..2f57643b43 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeRecentlyAddedMusicVideos.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeRecentlyAddedMusicVideos.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "video/VideoDatabase.h"
using namespace XFILE::VIDEODATABASEDIRECTORY;
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp
index 45a83cee8f..0e82fcca9e 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMovies.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTitleMovies.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp
index 95fe30010b..d35398b153 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleMusicVideos.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTitleMusicVideos.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp
index b1a247ca7f..52f903fffd 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTitleTvShows.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTitleTvShows.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "QueryParams.h"
#include "video/VideoDatabase.h"
diff --git a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp
index 07e5ff4aee..5a490a53d7 100644
--- a/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp
+++ b/xbmc/filesystem/VideoDatabaseDirectory/DirectoryNodeTvShowsOverview.cpp
@@ -9,6 +9,7 @@
#include "DirectoryNodeTvShowsOverview.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "utils/StringUtils.h"
#include "video/VideoDbUrl.h"
diff --git a/xbmc/filesystem/VirtualDirectory.cpp b/xbmc/filesystem/VirtualDirectory.cpp
index 4fb0205d1e..f764645cf9 100644
--- a/xbmc/filesystem/VirtualDirectory.cpp
+++ b/xbmc/filesystem/VirtualDirectory.cpp
@@ -11,6 +11,7 @@
#include "Directory.h"
#include "DirectoryFactory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "SourcesDirectory.h"
#include "URL.h"
diff --git a/xbmc/filesystem/ZeroconfDirectory.cpp b/xbmc/filesystem/ZeroconfDirectory.cpp
index f34b6b2f1f..d05184e394 100644
--- a/xbmc/filesystem/ZeroconfDirectory.cpp
+++ b/xbmc/filesystem/ZeroconfDirectory.cpp
@@ -10,6 +10,7 @@
#include "Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "network/ZeroconfBrowser.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/filesystem/test/TestDirectory.cpp b/xbmc/filesystem/test/TestDirectory.cpp
index e99408c9dc..8f65b06356 100644
--- a/xbmc/filesystem/test/TestDirectory.cpp
+++ b/xbmc/filesystem/test/TestDirectory.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "filesystem/IDirectory.h"
#include "filesystem/SpecialProtocol.h"
diff --git a/xbmc/filesystem/test/TestHTTPDirectory.cpp b/xbmc/filesystem/test/TestHTTPDirectory.cpp
index 773630770b..8288bda46f 100644
--- a/xbmc/filesystem/test/TestHTTPDirectory.cpp
+++ b/xbmc/filesystem/test/TestHTTPDirectory.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/CurlFile.h"
#include "filesystem/HTTPDirectory.h"
diff --git a/xbmc/filesystem/test/TestZipFile.cpp b/xbmc/filesystem/test/TestZipFile.cpp
index 3ff518b8dc..ffb4478cdd 100644
--- a/xbmc/filesystem/test/TestZipFile.cpp
+++ b/xbmc/filesystem/test/TestZipFile.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/games/addons/GameClientProperties.cpp b/xbmc/games/addons/GameClientProperties.cpp
index f3d97858bd..ae081afa92 100644
--- a/xbmc/games/addons/GameClientProperties.cpp
+++ b/xbmc/games/addons/GameClientProperties.cpp
@@ -9,6 +9,7 @@
#include "GameClientProperties.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GameClient.h"
#include "ServiceBroker.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/games/agents/windows/GUIAgentControllerList.cpp b/xbmc/games/agents/windows/GUIAgentControllerList.cpp
index 55bb3e2296..7da49e72d2 100644
--- a/xbmc/games/agents/windows/GUIAgentControllerList.cpp
+++ b/xbmc/games/agents/windows/GUIAgentControllerList.cpp
@@ -9,6 +9,7 @@
#include "GUIAgentControllerList.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIAgentDefines.h"
#include "GUIAgentWindow.h"
#include "ServiceBroker.h"
diff --git a/xbmc/games/controllers/dialogs/ControllerInstaller.cpp b/xbmc/games/controllers/dialogs/ControllerInstaller.cpp
index 9b0fe6fc87..18f7634a01 100644
--- a/xbmc/games/controllers/dialogs/ControllerInstaller.cpp
+++ b/xbmc/games/controllers/dialogs/ControllerInstaller.cpp
@@ -9,6 +9,7 @@
#include "ControllerInstaller.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "addons/Addon.h"
#include "addons/AddonInstaller.h"
diff --git a/xbmc/games/controllers/dialogs/ControllerSelect.cpp b/xbmc/games/controllers/dialogs/ControllerSelect.cpp
index 2ef9941dea..8219731120 100644
--- a/xbmc/games/controllers/dialogs/ControllerSelect.cpp
+++ b/xbmc/games/controllers/dialogs/ControllerSelect.cpp
@@ -9,6 +9,7 @@
#include "ControllerSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogSelect.h"
#include "games/controllers/Controller.h"
diff --git a/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp b/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
index f4c754aee0..08d6b71ffb 100644
--- a/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
+++ b/xbmc/games/dialogs/GUIDialogSelectGameClient.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSelectGameClient.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "dialogs/GUIDialogSelect.h"
#include "filesystem/AddonsDirectory.h"
#include "games/addons/GameClient.h"
diff --git a/xbmc/games/dialogs/osd/DialogGameSaves.cpp b/xbmc/games/dialogs/osd/DialogGameSaves.cpp
index a2c08d606f..239b78ab4e 100644
--- a/xbmc/games/dialogs/osd/DialogGameSaves.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameSaves.cpp
@@ -9,6 +9,7 @@
#include "DialogGameSaves.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "addons/Addon.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/games/dialogs/osd/DialogGameStretchMode.cpp b/xbmc/games/dialogs/osd/DialogGameStretchMode.cpp
index 98c1e077e8..67f4cad1ff 100644
--- a/xbmc/games/dialogs/osd/DialogGameStretchMode.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameStretchMode.cpp
@@ -9,6 +9,7 @@
#include "DialogGameStretchMode.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "cores/RetroPlayer/RetroPlayerUtils.h"
#include "cores/RetroPlayer/guibridge/GUIGameVideoHandle.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/games/dialogs/osd/DialogGameVideoFilter.h b/xbmc/games/dialogs/osd/DialogGameVideoFilter.h
index 237720d65d..6c659da6e0 100644
--- a/xbmc/games/dialogs/osd/DialogGameVideoFilter.h
+++ b/xbmc/games/dialogs/osd/DialogGameVideoFilter.h
@@ -10,6 +10,7 @@
#include "DialogGameVideoSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
namespace KODI
{
diff --git a/xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp b/xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp
index 7037a6b35c..3fe6baa778 100644
--- a/xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameVideoRotation.cpp
@@ -9,6 +9,7 @@
#include "DialogGameVideoRotation.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "guilib/WindowIDs.h"
#include "settings/GameSettings.h"
diff --git a/xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp b/xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp
index a69b26f772..0bf1529244 100644
--- a/xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp
+++ b/xbmc/games/dialogs/osd/DialogGameVideoSelect.cpp
@@ -9,6 +9,7 @@
#include "DialogGameVideoSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "cores/RetroPlayer/guibridge/GUIGameRenderManager.h"
#include "cores/RetroPlayer/guibridge/GUIGameVideoHandle.h"
diff --git a/xbmc/games/dialogs/osd/DialogInGameSaves.h b/xbmc/games/dialogs/osd/DialogInGameSaves.h
index 5c1c3176c7..8fdb7b0b6c 100644
--- a/xbmc/games/dialogs/osd/DialogInGameSaves.h
+++ b/xbmc/games/dialogs/osd/DialogInGameSaves.h
@@ -10,6 +10,7 @@
#include "DialogGameVideoSelect.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/GUIListItem.h"
#include <string>
diff --git a/xbmc/games/ports/guicontrols/GUIActivePortList.cpp b/xbmc/games/ports/guicontrols/GUIActivePortList.cpp
index 851ca86266..f0e89f6e8d 100644
--- a/xbmc/games/ports/guicontrols/GUIActivePortList.cpp
+++ b/xbmc/games/ports/guicontrols/GUIActivePortList.cpp
@@ -9,6 +9,7 @@
#include "GUIActivePortList.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "addons/AddonEvents.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/games/ports/windows/GUIPortList.cpp b/xbmc/games/ports/windows/GUIPortList.cpp
index c0e46e0bac..9db78747be 100644
--- a/xbmc/games/ports/windows/GUIPortList.cpp
+++ b/xbmc/games/ports/windows/GUIPortList.cpp
@@ -9,6 +9,7 @@
#include "GUIPortList.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPortDefines.h"
#include "GUIPortWindow.h"
#include "ServiceBroker.h"
diff --git a/xbmc/games/windows/GUIViewStateWindowGames.cpp b/xbmc/games/windows/GUIViewStateWindowGames.cpp
index e388d8ff83..3f45122ac7 100644
--- a/xbmc/games/windows/GUIViewStateWindowGames.cpp
+++ b/xbmc/games/windows/GUIViewStateWindowGames.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateWindowGames.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "games/GameUtils.h"
#include "guilib/LocalizeStrings.h"
#include "guilib/WindowIDs.h"
diff --git a/xbmc/games/windows/GUIWindowGames.cpp b/xbmc/games/windows/GUIWindowGames.cpp
index a74186db84..2d9eb600db 100644
--- a/xbmc/games/windows/GUIWindowGames.cpp
+++ b/xbmc/games/windows/GUIWindowGames.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowGames.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/guilib/CMakeLists.txt b/xbmc/guilib/CMakeLists.txt
index 3e936cd9b9..5d598cbad3 100644
--- a/xbmc/guilib/CMakeLists.txt
+++ b/xbmc/guilib/CMakeLists.txt
@@ -66,6 +66,7 @@ set(SOURCES DDSImage.cpp
TextureBundle.cpp
TextureBundleXBT.cpp
Texture.cpp
+ TextureBase.cpp
TextureManager.cpp
VisibleEffect.cpp
XBTF.cpp
@@ -148,6 +149,7 @@ set(HEADERS DDSImage.h
LocalizeStrings.h
StereoscopicsManager.h
Texture.h
+ TextureBase.h
TextureBundle.h
TextureBundleXBT.h
TextureManager.h
@@ -210,8 +212,9 @@ if(CORE_SYSTEM_NAME STREQUAL windows OR CORE_SYSTEM_NAME STREQUAL windowsstore)
foreach(shader ${SHADERS_VERTEX})
get_filename_component(file ${shader} NAME_WE)
add_custom_command(OUTPUT ${file}.h
- COMMAND ${FXC} /Fh ${file}.h /E VS /T vs_4_0_level_9_1 /Vn ${file} /Qstrip_reflect
- ${CMAKE_SOURCE_DIR}/system/shaders/${shader}
+ COMMAND windows::FXC
+ ARGS /Fh ${file}.h /E VS /T vs_4_0_level_9_1 /Vn ${file} /Qstrip_reflect
+ ${CMAKE_SOURCE_DIR}/system/shaders/${shader}
DEPENDS ${CMAKE_SOURCE_DIR}/system/shaders/${shader}
COMMENT "FX compile vertex shader ${shader}"
VERBATIM)
@@ -220,8 +223,9 @@ if(CORE_SYSTEM_NAME STREQUAL windows OR CORE_SYSTEM_NAME STREQUAL windowsstore)
foreach(shader ${SHADERS_PIXEL})
get_filename_component(file ${shader} NAME_WE)
add_custom_command(OUTPUT ${file}.h
- COMMAND ${FXC} /Fh ${file}.h /E PS /T ps_4_0_level_9_1 /Vn ${file} /Qstrip_reflect
- ${CMAKE_SOURCE_DIR}/system/shaders/${shader}
+ COMMAND windows::FXC
+ ARGS /Fh ${file}.h /E PS /T ps_4_0_level_9_1 /Vn ${file} /Qstrip_reflect
+ ${CMAKE_SOURCE_DIR}/system/shaders/${shader}
DEPENDS ${CMAKE_SOURCE_DIR}/system/shaders/${shader}
COMMENT "FX compile pixel shader ${shader}"
VERBATIM)
diff --git a/xbmc/guilib/GUIBaseContainer.cpp b/xbmc/guilib/GUIBaseContainer.cpp
index 897459790d..70c7a1a2bd 100644
--- a/xbmc/guilib/GUIBaseContainer.cpp
+++ b/xbmc/guilib/GUIBaseContainer.cpp
@@ -9,6 +9,7 @@
#include "GUIBaseContainer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIListItemLayout.h"
#include "GUIMessage.h"
@@ -285,6 +286,8 @@ void CGUIBaseContainer::Render()
float focusedPos = 0;
std::shared_ptr<CGUIListItem> focusedItem;
int current = offset - cacheBefore;
+
+ std::vector<RENDERITEM> renderitems;
while (pos < end && m_items.size())
{
int itemNo = CorrectOffset(current, 0);
@@ -303,9 +306,9 @@ void CGUIBaseContainer::Render()
else
{
if (m_orientation == VERTICAL)
- RenderItem(origin.x, pos, item.get(), false);
+ renderitems.emplace_back(RENDERITEM{origin.x, pos, item, false});
else
- RenderItem(pos, origin.y, item.get(), false);
+ renderitems.emplace_back(RENDERITEM{pos, origin.y, item, false});
}
}
// increment our position
@@ -316,9 +319,25 @@ void CGUIBaseContainer::Render()
if (focusedItem)
{
if (m_orientation == VERTICAL)
- RenderItem(origin.x, focusedPos, focusedItem.get(), true);
+ renderitems.emplace_back(RENDERITEM{origin.x, focusedPos, focusedItem, true});
else
- RenderItem(focusedPos, origin.y, focusedItem.get(), true);
+ renderitems.emplace_back(RENDERITEM{focusedPos, origin.y, focusedItem, true});
+ }
+
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ {
+ for (auto it = std::crbegin(renderitems); it != std::crend(renderitems); it++)
+ {
+ RenderItem(it->posX, it->posY, it->item.get(), it->focused);
+ }
+ }
+ else
+ {
+ for (const auto& renderitem : renderitems)
+ {
+ RenderItem(renderitem.posX, renderitem.posY, renderitem.item.get(), renderitem.focused);
+ }
}
CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion();
@@ -1044,6 +1063,37 @@ void CGUIBaseContainer::UpdateVisibility(const CGUIListItem *item)
UpdateListProvider();
}
+void CGUIBaseContainer::AssignDepth()
+{
+ std::shared_ptr<CGUIListItem> focusedItem = nullptr;
+ int32_t current = 0;
+
+ for (const auto& item : m_items)
+ {
+ bool focused = (current == GetOffset() + GetCursor());
+ if (focused)
+ {
+ focusedItem = item;
+ }
+ else
+ {
+ if (item->GetFocusedLayout())
+ item->GetFocusedLayout()->AssignDepth();
+ if (item->GetLayout())
+ item->GetLayout()->AssignDepth();
+ }
+ current++;
+ }
+
+ if (focusedItem)
+ {
+ if (focusedItem->GetFocusedLayout())
+ focusedItem->GetFocusedLayout()->AssignDepth();
+ if (focusedItem->GetLayout())
+ focusedItem->GetLayout()->AssignDepth();
+ }
+}
+
void CGUIBaseContainer::UpdateListProvider(bool forceRefresh /* = false */)
{
if (m_listProvider)
diff --git a/xbmc/guilib/GUIBaseContainer.h b/xbmc/guilib/GUIBaseContainer.h
index 38e68cf51d..15f63048fa 100644
--- a/xbmc/guilib/GUIBaseContainer.h
+++ b/xbmc/guilib/GUIBaseContainer.h
@@ -50,6 +50,7 @@ public:
void AllocResources() override;
void FreeResources(bool immediately = false) override;
void UpdateVisibility(const CGUIListItem *item = NULL) override;
+ void AssignDepth() override;
virtual unsigned int GetRows() const;
@@ -213,6 +214,14 @@ protected:
unsigned int m_lastRenderTime;
+ struct RENDERITEM
+ {
+ float posX;
+ float posY;
+ std::shared_ptr<CGUIListItem> item;
+ bool focused;
+ };
+
private:
bool OnContextMenu();
diff --git a/xbmc/guilib/GUIBorderedImage.cpp b/xbmc/guilib/GUIBorderedImage.cpp
index 7c48ddb9e1..0ed3044a11 100644
--- a/xbmc/guilib/GUIBorderedImage.cpp
+++ b/xbmc/guilib/GUIBorderedImage.cpp
@@ -56,9 +56,17 @@ void CGUIBorderedImage::Process(unsigned int currentTime, CDirtyRegionList &dirt
void CGUIBorderedImage::Render()
{
+ bool renderFrontToBack = CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK;
+
+ if (renderFrontToBack)
+ CGUIImage::Render();
+
if (!m_borderImage->GetFileName().empty() && m_texture->ReadyToRender())
- m_borderImage->Render();
- CGUIImage::Render();
+ m_borderImage->Render(-1);
+
+ if (!renderFrontToBack)
+ CGUIImage::Render();
}
CRect CGUIBorderedImage::CalcRenderRegion() const
diff --git a/xbmc/guilib/GUIButtonControl.cpp b/xbmc/guilib/GUIButtonControl.cpp
index f509371689..22ded687b7 100644
--- a/xbmc/guilib/GUIButtonControl.cpp
+++ b/xbmc/guilib/GUIButtonControl.cpp
@@ -110,15 +110,27 @@ void CGUIButtonControl::Process(unsigned int currentTime, CDirtyRegionList &dirt
void CGUIButtonControl::Render()
{
- m_imgFocus->Render();
- m_imgNoFocus->Render();
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ {
+ m_imgNoFocus->Render();
+ m_imgFocus->Render(-1);
+ }
+ else
+ {
+ m_imgFocus->Render(-1);
+ m_imgNoFocus->Render();
+ RenderText();
+ }
- RenderText();
CGUIControl::Render();
}
void CGUIButtonControl::RenderText()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
m_label.Render();
m_label2.Render();
}
diff --git a/xbmc/guilib/GUIControl.cpp b/xbmc/guilib/GUIControl.cpp
index 689c55f257..7ae9728120 100644
--- a/xbmc/guilib/GUIControl.cpp
+++ b/xbmc/guilib/GUIControl.cpp
@@ -180,6 +180,10 @@ void CGUIControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregio
// 3. reset the animation transform
void CGUIControl::DoRender()
{
+ if (IsControlRenderable() &&
+ !m_renderRegion.Intersects(CServiceBroker::GetWinSystem()->GetGfxContext().GetScissors()))
+ return;
+
if (IsVisible() && !m_isCulled)
{
bool hasStereo =
@@ -484,6 +488,11 @@ float CGUIControl::GetHeight() const
return m_height;
}
+void CGUIControl::AssignDepth()
+{
+ m_cachedTransform.depth = CServiceBroker::GetWinSystem()->GetGfxContext().GetDepth();
+}
+
void CGUIControl::MarkDirtyRegion(const unsigned int dirtyState)
{
// if the control is culled, bail
@@ -954,6 +963,24 @@ void CGUIControl::UpdateControlStats()
}
}
+bool CGUIControl::IsControlRenderable()
+{
+ switch (ControlType)
+ {
+ case GUICONTAINER_EPGGRID:
+ case GUICONTAINER_FIXEDLIST:
+ case GUICONTAINER_LIST:
+ case GUICONTAINER_PANEL:
+ case GUICONTAINER_WRAPLIST:
+ case GUICONTROL_GROUP:
+ case GUICONTROL_GROUPLIST:
+ case GUICONTROL_LISTGROUP:
+ return false;
+ default:
+ return true;
+ }
+}
+
void CGUIControl::SetHitRect(const CRect& rect, const UTILS::COLOR::Color& color)
{
m_hitRect = rect;
diff --git a/xbmc/guilib/GUIControl.h b/xbmc/guilib/GUIControl.h
index 4cedee0761..93b5dcf199 100644
--- a/xbmc/guilib/GUIControl.h
+++ b/xbmc/guilib/GUIControl.h
@@ -184,6 +184,7 @@ public:
virtual float GetYPosition() const;
virtual float GetWidth() const;
virtual float GetHeight() const;
+ virtual void AssignDepth();
void MarkDirtyRegion(const unsigned int dirtyState = DIRTY_STATE_CONTROL);
bool IsControlDirty() const { return m_controlDirtyState != 0; }
@@ -306,6 +307,11 @@ public:
};
GUICONTROLTYPES GetControlType() const { return ControlType; }
+ /*! \brief Test whether the control is "drawable" (not a group or similar)
+ \return true if the control has textures/labels it wants to render
+ */
+ bool IsControlRenderable();
+
enum GUIVISIBLE { HIDDEN = 0, DELAYED, VISIBLE };
enum GUISCROLLVALUE { FOCUS = 0, NEVER, ALWAYS };
diff --git a/xbmc/guilib/GUIControlGroup.cpp b/xbmc/guilib/GUIControlGroup.cpp
index 11af2ea89e..61142c7b5d 100644
--- a/xbmc/guilib/GUIControlGroup.cpp
+++ b/xbmc/guilib/GUIControlGroup.cpp
@@ -108,12 +108,26 @@ void CGUIControlGroup::Render()
CPoint pos(GetPosition());
CServiceBroker::GetWinSystem()->GetGfxContext().SetOrigin(pos.x, pos.y);
CGUIControl *focusedControl = NULL;
- for (auto *control : m_children)
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ {
+ for (auto it = m_children.rbegin(); it != m_children.rend(); ++it)
+ {
+ if (m_renderFocusedLast && (*it)->HasFocus())
+ focusedControl = (*it);
+ else
+ (*it)->DoRender();
+ }
+ }
+ else
{
- if (m_renderFocusedLast && control->HasFocus())
- focusedControl = control;
- else
- control->DoRender();
+ for (auto* control : m_children)
+ {
+ if (m_renderFocusedLast && control->HasFocus())
+ focusedControl = control;
+ else
+ control->DoRender();
+ }
}
if (focusedControl)
focusedControl->DoRender();
@@ -286,6 +300,23 @@ bool CGUIControlGroup::CanFocus() const
return false;
}
+void CGUIControlGroup::AssignDepth()
+{
+ CGUIControl* focusedControl = nullptr;
+ if (m_children.size())
+ {
+ for (auto* control : m_children)
+ {
+ if (m_renderFocusedLast && control->HasFocus())
+ focusedControl = control;
+ else
+ control->AssignDepth();
+ }
+ }
+ if (focusedControl)
+ focusedControl->AssignDepth();
+}
+
void CGUIControlGroup::SetInitialVisibility()
{
CGUIControl::SetInitialVisibility();
diff --git a/xbmc/guilib/GUIControlGroup.h b/xbmc/guilib/GUIControlGroup.h
index 5c13466949..73529dda79 100644
--- a/xbmc/guilib/GUIControlGroup.h
+++ b/xbmc/guilib/GUIControlGroup.h
@@ -41,6 +41,7 @@ public:
void FreeResources(bool immediately = false) override;
void DynamicResourceAlloc(bool bOnOff) override;
bool CanFocus() const override;
+ void AssignDepth() override;
EVENT_RESULT SendMouseEvent(const CPoint& point, const KODI::MOUSE::CMouseEvent& event) override;
void UnfocusFromPoint(const CPoint &point) override;
diff --git a/xbmc/guilib/GUIEditControl.cpp b/xbmc/guilib/GUIEditControl.cpp
index fe85f1ac77..adf8835747 100644
--- a/xbmc/guilib/GUIEditControl.cpp
+++ b/xbmc/guilib/GUIEditControl.cpp
@@ -548,6 +548,9 @@ void CGUIEditControl::ProcessText(unsigned int currentTime)
void CGUIEditControl::RenderText()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
m_label.Render();
if (CServiceBroker::GetWinSystem()->GetGfxContext().SetClipRegion(m_clipRect.x1, m_clipRect.y1, m_clipRect.Width(), m_clipRect.Height()))
diff --git a/xbmc/guilib/GUIFadeLabelControl.cpp b/xbmc/guilib/GUIFadeLabelControl.cpp
index 1827c3d0c2..89f994b0f0 100644
--- a/xbmc/guilib/GUIFadeLabelControl.cpp
+++ b/xbmc/guilib/GUIFadeLabelControl.cpp
@@ -128,6 +128,7 @@ void CGUIFadeLabelControl::Process(unsigned int currentTime, CDirtyRegionList &d
m_fadeAnim.Animate(currentTime, true);
m_fadeAnim.RenderAnimation(matrix);
m_fadeMatrix = CServiceBroker::GetWinSystem()->GetGfxContext().AddTransform(matrix);
+ m_fadeMatrix.depth = m_fadeDepth;
if (m_fadeAnim.GetState() == ANIM_STATE_APPLIED)
m_fadeAnim.ResetAnimation();
@@ -170,6 +171,9 @@ bool CGUIFadeLabelControl::UpdateColors(const CGUIListItem* item)
void CGUIFadeLabelControl::Render()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
if (!m_label.font)
{ // nothing to render
CGUIControl::Render();
@@ -243,6 +247,12 @@ bool CGUIFadeLabelControl::OnMessage(CGUIMessage& message)
return CGUIControl::OnMessage(message);
}
+void CGUIFadeLabelControl::AssignDepth()
+{
+ CGUIControl::AssignDepth();
+ m_fadeDepth = m_cachedTransform.depth;
+}
+
std::string CGUIFadeLabelControl::GetDescription() const
{
return (m_currentLabel < m_infoLabels.size()) ? m_infoLabels[m_currentLabel].GetLabel(m_parentID) : "";
diff --git a/xbmc/guilib/GUIFadeLabelControl.h b/xbmc/guilib/GUIFadeLabelControl.h
index 9f5f7abe4b..098a7527d4 100644
--- a/xbmc/guilib/GUIFadeLabelControl.h
+++ b/xbmc/guilib/GUIFadeLabelControl.h
@@ -17,6 +17,7 @@
#include "GUILabel.h"
#include "guilib/guiinfo/GUIInfoLabel.h"
+#include <cstdint>
#include <vector>
/*!
@@ -35,6 +36,7 @@ public:
void Render() override;
bool CanFocus() const override;
bool OnMessage(CGUIMessage& message) override;
+ void AssignDepth() override;
void SetInfo(const std::vector<KODI::GUILIB::GUIINFO::CGUIInfoLabel> &vecInfo);
void SetScrolling(bool scroll) { m_scroll = scroll; }
@@ -74,5 +76,7 @@ protected:
bool m_resetOnLabelChange;
bool m_randomized;
bool m_allLabelsShown = true;
+
+ uint32_t m_fadeDepth{0};
};
diff --git a/xbmc/guilib/GUIFont.cpp b/xbmc/guilib/GUIFont.cpp
index 784dd75971..bf0c014a0a 100644
--- a/xbmc/guilib/GUIFont.cpp
+++ b/xbmc/guilib/GUIFont.cpp
@@ -234,18 +234,18 @@ void CGUIFont::DrawScrollingText(float x,
shadowColors.emplace_back((renderColor & 0xff000000) != 0 ? shadowColor : 0);
for (float dx = -offset; dx < maxWidth; dx += scrollInfo.m_totalWidth)
{
- m_font->DrawTextInternal(context, x + dx + 1, y + 1, shadowColors, text, alignment,
- textPixelWidth, scroll);
- m_font->DrawTextInternal(context, x + dx + scrollInfo.m_textWidth + 1, y + 1, shadowColors,
- scrollInfo.m_suffix, alignment, suffixPixelWidth, scroll);
+ m_font->DrawTextInternal(context, x + 1, y + 1, shadowColors, text, alignment, textPixelWidth,
+ scroll, dx);
+ m_font->DrawTextInternal(context, x + scrollInfo.m_textWidth + 1, y + 1, shadowColors,
+ scrollInfo.m_suffix, alignment, suffixPixelWidth, scroll, dx);
}
}
for (float dx = -offset; dx < maxWidth; dx += scrollInfo.m_totalWidth)
{
- m_font->DrawTextInternal(context, x + dx, y, renderColors, text, alignment, textPixelWidth,
- scroll);
- m_font->DrawTextInternal(context, x + dx + scrollInfo.m_textWidth, y, renderColors,
- scrollInfo.m_suffix, alignment, suffixPixelWidth, scroll);
+ m_font->DrawTextInternal(context, x, y, renderColors, text, alignment, textPixelWidth, scroll,
+ dx);
+ m_font->DrawTextInternal(context, x + scrollInfo.m_textWidth, y, renderColors,
+ scrollInfo.m_suffix, alignment, suffixPixelWidth, scroll, dx);
}
context.RestoreClipRegion();
diff --git a/xbmc/guilib/GUIFontManager.cpp b/xbmc/guilib/GUIFontManager.cpp
index 9170cc0406..93f88666a0 100644
--- a/xbmc/guilib/GUIFontManager.cpp
+++ b/xbmc/guilib/GUIFontManager.cpp
@@ -8,6 +8,7 @@
#include "GUIFontManager.h"
+#include "FileItemList.h"
#include "GUIComponent.h"
#include "GUIFontTTF.h"
#include "GUIWindowManager.h"
diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp
index 50d0e07a44..f9f0eec2a3 100644
--- a/xbmc/guilib/GUIFontTTF.cpp
+++ b/xbmc/guilib/GUIFontTTF.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -369,7 +369,9 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
const vecText& text,
uint32_t alignment,
float maxPixelWidth,
- bool scrolling)
+ bool scrolling,
+ float dx,
+ float dy)
{
if (text.empty())
{
@@ -379,15 +381,40 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
Begin();
uint32_t rawAlignment = alignment;
bool dirtyCache(false);
+
+#if not defined(HAS_DX)
+ // round coordinates to the pixel grid. otherwise, we might sample at the wrong positions.
+ if (!scrolling)
+ x = std::round(x);
+ y = std::round(y);
+#else
+ x += dx;
+ y += dy;
+#endif
+
+#if not defined(HAS_DX)
+ // GL can scissor and shader clip
+ const bool hardwareClipping = true;
+#else
+ // FIXME: remove static (CPU based) clipping for GLES/DX
const bool hardwareClipping = m_renderSystem->ScissorsCanEffectClipping();
+#endif
+
+ // FIXME: remove positional stuff once GLES/DX are brought up to date
CGUIFontCacheStaticPosition staticPos(x, y);
CGUIFontCacheDynamicPosition dynamicPos;
+
+#if not defined(HAS_DX)
+ // dummy positions for the time being
+ dynamicPos = CGUIFontCacheDynamicPosition(0.0f, 0.0f, 0.0f);
+#else
if (hardwareClipping)
{
dynamicPos =
CGUIFontCacheDynamicPosition(context.ScaleFinalXCoord(x, y), context.ScaleFinalYCoord(x, y),
context.ScaleFinalZCoord(x, y));
}
+#endif
CVertexBuffer unusedVertexBuffer;
CVertexBuffer& vertexBuffer =
@@ -425,8 +452,14 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
const std::vector<Glyph> glyphs = GetHarfBuzzShapedGlyphs(text);
// save the origin, which is scaled separately
+#if not defined(HAS_DX)
+ // the origin is now at [0,0], and not at "random" locations anymore. positioning is done in the vertex shader.
+ m_originX = 0;
+ m_originY = 0;
+#else
m_originX = x;
m_originY = y;
+#endif
// cache the ellipses width
if (!m_ellipseCached)
@@ -479,13 +512,13 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
if (!c)
continue;
- float nextWidth;
+ float nextWidth = textWidth;
if ((ch & 0xffff) == static_cast<character_t>('\t'))
- nextWidth = GetTabSpaceLength();
+ nextWidth += GetTabSpaceLength();
else
- nextWidth = textWidth + c->m_advance;
+ nextWidth += c->m_advance;
- if (nextWidth > maxPixelWidth)
+ if (maxPixelWidth > 0 && nextWidth > maxPixelWidth)
{
// Start rendering from the glyph that does not exceed the maximum width
startPosGlyph = std::distance(itRGlyph, glyphs.crend());
@@ -507,13 +540,13 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
if (!c)
continue;
- float nextWidth;
+ float nextWidth = textWidth;
if ((ch & 0xffff) == static_cast<character_t>('\t'))
- nextWidth = GetTabSpaceLength();
+ nextWidth += GetTabSpaceLength();
else
- nextWidth = textWidth + c->m_advance;
+ nextWidth += c->m_advance;
- if (nextWidth > maxPixelWidth)
+ if (maxPixelWidth > 0 && nextWidth > maxPixelWidth)
break;
textWidth = nextWidth;
@@ -677,7 +710,11 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
scrolling, std::chrono::steady_clock::now(), dirtyCache);
CVertexBuffer newVertexBuffer = CreateVertexBuffer(*tempVertices);
vertexBuffer = newVertexBuffer;
+#if not defined(HAS_DX)
+ m_vertexTrans.emplace_back(x, y, 0.0f, &vertexBuffer, context.GetClipRegion(), dx, dy);
+#else
m_vertexTrans.emplace_back(.0f, .0f, .0f, &vertexBuffer, context.GetClipRegion());
+#endif
}
else
{
@@ -691,8 +728,12 @@ void CGUIFontTTF::DrawTextInternal(CGraphicContext& context,
else
{
if (hardwareClipping)
+#if not defined(HAS_DX)
+ m_vertexTrans.emplace_back(x, y, 0.0f, &vertexBuffer, context.GetClipRegion(), dx, dy);
+#else
m_vertexTrans.emplace_back(dynamicPos.m_x, dynamicPos.m_y, dynamicPos.m_z, &vertexBuffer,
context.GetClipRegion());
+#endif
else
/* Append the vertices from the cache to the set collected since the first Begin() call */
m_vertex.insert(m_vertex.end(), vertices->begin(), vertices->end());
@@ -1098,12 +1139,19 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
// posX and posY are relative to our origin, and the textcell is offset
// from our (posX, posY). Plus, these are unscaled quantities compared to the underlying GUI resolution
+#if not defined(HAS_DX)
+ CRect vertex((posX + ch->m_offsetX), (posY + ch->m_offsetY), (posX + ch->m_offsetX + width),
+ (posY + ch->m_offsetY + height));
+#else
CRect vertex((posX + ch->m_offsetX) * context.GetGUIScaleX(),
(posY + ch->m_offsetY) * context.GetGUIScaleY(),
(posX + ch->m_offsetX + width) * context.GetGUIScaleX(),
(posY + ch->m_offsetY + height) * context.GetGUIScaleY());
vertex += CPoint(m_originX, m_originY);
+#endif
CRect texture(ch->m_left, ch->m_top, ch->m_right, ch->m_bottom);
+
+#if defined(HAS_DX)
if (!m_renderSystem->ScissorsCanEffectClipping())
context.ClipRect(vertex, texture);
@@ -1163,6 +1211,14 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
const float tr = texture.x2 * m_textureScaleX;
const float tt = texture.y1 * m_textureScaleY;
const float tb = texture.y2 * m_textureScaleY;
+#else
+ // when scaling by shader, we have to grow the vertex and texture coords
+ // by .5 or we would ommit pixels when animating.
+ const float tl = (texture.x1 - .5f) * m_textureScaleX;
+ const float tr = (texture.x2 + .5f) * m_textureScaleX;
+ const float tt = (texture.y1 - .5f) * m_textureScaleY;
+ const float tb = (texture.y2 + .5f) * m_textureScaleY;
+#endif
vertices.resize(vertices.size() + VERTEX_PER_GLYPH);
SVertex* v = &vertices[vertices.size() - VERTEX_PER_GLYPH];
@@ -1208,29 +1264,38 @@ void CGUIFontTTF::RenderCharacter(CGraphicContext& context,
v[3].v = tb;
#else
// GL / GLES uses triangle strips, not quads, so have to rearrange the vertex order
+ // GL uses vertex shaders to manipulate text rotation/translation/scaling/clipping.
+
+ // nudge position to align with raster grid. messes up kerning, but also avoids
+ // linear filtering (when not scaled/rotated).
+ float xOffset = 0.0f;
+ if (roundX)
+ xOffset = (vertex.x1 - std::floor(vertex.x1));
+ float yOffset = (vertex.y1 - std::floor(vertex.y1));
+
v[0].u = tl;
v[0].v = tt;
- v[0].x = x[0];
- v[0].y = y[0];
- v[0].z = z[0];
+ v[0].x = vertex.x1 - xOffset - 0.5f;
+ v[0].y = vertex.y1 - yOffset - 0.5f;
+ v[0].z = 0;
v[1].u = tl;
v[1].v = tb;
- v[1].x = x[3];
- v[1].y = y[3];
- v[1].z = z[3];
+ v[1].x = vertex.x1 - xOffset - 0.5f;
+ v[1].y = vertex.y2 - yOffset + 0.5f;
+ v[1].z = 0;
v[2].u = tr;
v[2].v = tt;
- v[2].x = x[1];
- v[2].y = y[1];
- v[2].z = z[1];
+ v[2].x = vertex.x2 - xOffset + 0.5f;
+ v[2].y = vertex.y1 - yOffset - 0.5f;
+ v[2].z = 0;
v[3].u = tr;
v[3].v = tb;
- v[3].x = x[2];
- v[3].y = y[2];
- v[3].z = z[2];
+ v[3].x = vertex.x2 - xOffset + 0.5f;
+ v[3].y = vertex.y2 - yOffset + 0.5f;
+ v[3].z = 0;
#endif
}
diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h
index 2ed270343d..02a0ac16df 100644
--- a/xbmc/guilib/GUIFontTTF.h
+++ b/xbmc/guilib/GUIFontTTF.h
@@ -164,7 +164,9 @@ protected:
const vecText& text,
uint32_t alignment,
float maxPixelWidth,
- bool scrolling);
+ bool scrolling,
+ float dx = 0.0f,
+ float dy = 0.0f);
float m_height{0.0f};
@@ -238,16 +240,22 @@ protected:
float m_translateX;
float m_translateY;
float m_translateZ;
+ float m_offsetX; // skews the "raw" mesh before applying UI matrix (useful for scrolling)
+ float m_offsetY;
const CVertexBuffer* m_vertexBuffer;
CRect m_clip;
CTranslatedVertices(float translateX,
float translateY,
float translateZ,
const CVertexBuffer* vertexBuffer,
- const CRect& clip)
+ const CRect& clip,
+ float offsetX = 0.0f,
+ float offsetY = 0.0f)
: m_translateX(translateX),
m_translateY(translateY),
m_translateZ(translateZ),
+ m_offsetX(offsetX),
+ m_offsetY(offsetY),
m_vertexBuffer(vertexBuffer),
m_clip(clip)
{
diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
index 529078811e..603d5086ac 100644
--- a/xbmc/guilib/GUIFontTTFGL.cpp
+++ b/xbmc/guilib/GUIFontTTFGL.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -65,7 +65,18 @@ bool CGUIFontTTFGL::FirstBegin()
internalFormat = GL_R8;
else
internalFormat = GL_LUMINANCE;
+
renderSystem->EnableShader(ShaderMethodGL::SM_FONTS);
+ if (renderSystem->ScissorsCanEffectClipping())
+ {
+ m_scissorClip = true;
+ }
+ else
+ {
+ m_scissorClip = false;
+ renderSystem->ResetScissors();
+ renderSystem->EnableShader(ShaderMethodGL::SM_FONTS_SHADER_CLIP);
+ }
if (m_textureStatus == TEXTURE_REALLOCATED)
{
@@ -129,6 +140,9 @@ bool CGUIFontTTFGL::FirstBegin()
void CGUIFontTTFGL::LastEnd()
{
+ // static vertex arrays are not supported anymore
+ assert(m_vertex.empty());
+
CWinSystemBase* const winSystem = CServiceBroker::GetWinSystem();
if (!winSystem)
return;
@@ -138,7 +152,10 @@ void CGUIFontTTFGL::LastEnd()
GLint posLoc = renderSystem->ShaderGetPos();
GLint colLoc = renderSystem->ShaderGetCol();
GLint tex0Loc = renderSystem->ShaderGetCoord0();
- GLint modelLoc = renderSystem->ShaderGetModel();
+ GLint clipUniformLoc = renderSystem->ShaderGetClip();
+ GLint coordStepUniformLoc = renderSystem->ShaderGetCoordStep();
+ GLint matrixUniformLoc = renderSystem->ShaderGetMatrix();
+ GLint depthLoc = renderSystem->ShaderGetDepth();
CreateStaticVertexBuffers();
@@ -147,44 +164,6 @@ void CGUIFontTTFGL::LastEnd()
glEnableVertexAttribArray(colLoc);
glEnableVertexAttribArray(tex0Loc);
- if (!m_vertex.empty())
- {
-
- // Deal with vertices that had to use software clipping
- std::vector<SVertex> vecVertices(6 * (m_vertex.size() / 4));
- SVertex* vertices = &vecVertices[0];
- for (size_t i = 0; i < m_vertex.size(); i += 4)
- {
- *vertices++ = m_vertex[i];
- *vertices++ = m_vertex[i + 1];
- *vertices++ = m_vertex[i + 2];
-
- *vertices++ = m_vertex[i + 1];
- *vertices++ = m_vertex[i + 3];
- *vertices++ = m_vertex[i + 2];
- }
- vertices = &vecVertices[0];
-
- GLuint VertexVBO;
-
- glGenBuffers(1, &VertexVBO);
- glBindBuffer(GL_ARRAY_BUFFER, VertexVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(SVertex) * vecVertices.size(), &vecVertices[0],
- GL_STATIC_DRAW);
-
- glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, x)));
- glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, r)));
- glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, u)));
-
- glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDeleteBuffers(1, &VertexVBO);
- }
-
if (!m_vertexTrans.empty())
{
// Deal with the vertices that can be hardware clipped and therefore translated
@@ -211,14 +190,59 @@ void CGUIFontTTFGL::LastEnd()
// skip empty clip
if (clip.IsEmpty())
continue;
+ }
+
+ if (m_scissorClip)
+ {
+ // clip using scissors
renderSystem->SetScissors(clip);
}
+ else
+ {
+ // clip using vertex shader
+ renderSystem->ResetScissors();
+
+ float x1 =
+ m_vertexTrans[i].m_clip.x1 - m_vertexTrans[i].m_translateX - m_vertexTrans[i].m_offsetX;
+ float y1 =
+ m_vertexTrans[i].m_clip.y1 - m_vertexTrans[i].m_translateY - m_vertexTrans[i].m_offsetY;
+ float x2 =
+ m_vertexTrans[i].m_clip.x2 - m_vertexTrans[i].m_translateX - m_vertexTrans[i].m_offsetX;
+ float y2 =
+ m_vertexTrans[i].m_clip.y2 - m_vertexTrans[i].m_translateY - m_vertexTrans[i].m_offsetY;
+
+ glUniform4f(clipUniformLoc, x1, y1, x2, y2);
+
+ // setup texture step
+ float stepX = context.GetGUIScaleX() / (static_cast<float>(m_textureWidth));
+ float stepY = context.GetGUIScaleY() / (static_cast<float>(m_textureHeight));
+ glUniform4f(coordStepUniformLoc, stepX, stepY, 1.0f, 1.0f);
+ }
- // Apply the translation to the currently active (top-of-stack) model view matrix
- glMatrixModview.Push();
- glMatrixModview.Get().Translatef(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY,
- m_vertexTrans[i].m_translateZ);
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get());
+ // calculate the fractional offset to the ideal position
+ float fractX =
+ context.ScaleFinalXCoord(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY);
+ float fractY =
+ context.ScaleFinalYCoord(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY);
+ fractX = -fractX + std::round(fractX);
+ fractY = -fractY + std::round(fractY);
+
+ // proj * model * gui * scroll * translation * scaling * correction factor
+ CMatrixGL matrix = glMatrixProject.Get();
+ matrix.MultMatrixf(glMatrixModview.Get());
+ matrix.MultMatrixf(CMatrixGL(context.GetGUIMatrix()));
+ matrix.Translatef(m_vertexTrans[i].m_offsetX, m_vertexTrans[i].m_offsetY, 0.0f);
+ matrix.Translatef(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY, 0.0f);
+ // the gui matrix messes with the scale. correct it here for now.
+ matrix.Scalef(context.GetGUIScaleX(), context.GetGUIScaleY(), 1.0f);
+ // the gui matrix doesn't align to exact pixel coords atm. correct it here for now.
+ matrix.Translatef(fractX, fractY, 0.0f);
+
+ glUniformMatrix4fv(matrixUniformLoc, 1, GL_FALSE, matrix);
+
+ // Apply the depth value of the layer
+ float depth = CServiceBroker::GetWinSystem()->GetGfxContext().GetTransformDepth();
+ glUniform1f(depthLoc, depth);
// Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point
glBindBuffer(GL_ARRAY_BUFFER, m_vertexTrans[i].m_vertexBuffer->bufferHandle);
@@ -245,13 +269,12 @@ void CGUIFontTTFGL::LastEnd()
glDrawElements(GL_TRIANGLES, 6 * count, GL_UNSIGNED_SHORT, 0);
}
-
- glMatrixModview.Pop();
}
+
// Restore the original scissor rectangle
- renderSystem->SetScissors(scissor);
- // Restore the original model view matrix
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get());
+ if (m_scissorClip)
+ renderSystem->SetScissors(scissor);
+
// Unbind GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
diff --git a/xbmc/guilib/GUIFontTTFGL.h b/xbmc/guilib/GUIFontTTFGL.h
index 22fbe6419b..e59a54a23c 100644
--- a/xbmc/guilib/GUIFontTTFGL.h
+++ b/xbmc/guilib/GUIFontTTFGL.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -55,4 +55,6 @@ private:
TextureStatus m_textureStatus{TEXTURE_VOID};
static bool m_staticVertexBufferCreated;
+
+ bool m_scissorClip{false};
};
diff --git a/xbmc/guilib/GUIFontTTFGLES.cpp b/xbmc/guilib/GUIFontTTFGLES.cpp
index c00a601319..3a23a1d1f2 100644
--- a/xbmc/guilib/GUIFontTTFGLES.cpp
+++ b/xbmc/guilib/GUIFontTTFGLES.cpp
@@ -62,6 +62,17 @@ bool CGUIFontTTFGLES::FirstBegin()
GLenum pixformat = GL_ALPHA; // deprecated
GLenum internalFormat = GL_ALPHA;
+ if (renderSystem->ScissorsCanEffectClipping())
+ {
+ m_scissorClip = true;
+ }
+ else
+ {
+ m_scissorClip = false;
+ renderSystem->ResetScissors();
+ renderSystem->EnableGUIShader(ShaderMethodGLES::SM_FONTS_SHADER_CLIP);
+ }
+
if (m_textureStatus == TEXTURE_REALLOCATED)
{
if (glIsTexture(m_nTexture))
@@ -124,6 +135,9 @@ bool CGUIFontTTFGLES::FirstBegin()
void CGUIFontTTFGLES::LastEnd()
{
+ // static vertex arrays are not supported anymore
+ assert(m_vertex.empty());
+
CWinSystemBase* const winSystem = CServiceBroker::GetWinSystem();
if (!winSystem)
return;
@@ -134,7 +148,10 @@ void CGUIFontTTFGLES::LastEnd()
GLint posLoc = renderSystem->GUIShaderGetPos();
GLint colLoc = renderSystem->GUIShaderGetCol();
GLint tex0Loc = renderSystem->GUIShaderGetCoord0();
- GLint modelLoc = renderSystem->GUIShaderGetModel();
+ GLint clipUniformLoc = renderSystem->GUIShaderGetClip();
+ GLint coordStepUniformLoc = renderSystem->GUIShaderGetCoordStep();
+ GLint matrixUniformLoc = renderSystem->GUIShaderGetMatrix();
+ GLint depthLoc = renderSystem->GUIShaderGetDepth();
CreateStaticVertexBuffers();
@@ -143,35 +160,6 @@ void CGUIFontTTFGLES::LastEnd()
glEnableVertexAttribArray(colLoc);
glEnableVertexAttribArray(tex0Loc);
- if (!m_vertex.empty())
- {
- // Deal with vertices that had to use software clipping
- std::vector<SVertex> vecVertices(6 * (m_vertex.size() / 4));
- SVertex* vertices = &vecVertices[0];
-
- for (size_t i = 0; i < m_vertex.size(); i += 4)
- {
- *vertices++ = m_vertex[i];
- *vertices++ = m_vertex[i + 1];
- *vertices++ = m_vertex[i + 2];
-
- *vertices++ = m_vertex[i + 1];
- *vertices++ = m_vertex[i + 3];
- *vertices++ = m_vertex[i + 2];
- }
-
- vertices = &vecVertices[0];
-
- glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<char*>(vertices) + offsetof(SVertex, x));
- glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex),
- reinterpret_cast<char*>(vertices) + offsetof(SVertex, r));
- glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<char*>(vertices) + offsetof(SVertex, u));
-
- glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
- }
-
if (!m_vertexTrans.empty())
{
// Deal with the vertices that can be hardware clipped and therefore translated
@@ -198,14 +186,58 @@ void CGUIFontTTFGLES::LastEnd()
// skip empty clip
if (clip.IsEmpty())
continue;
+ }
+ if (m_scissorClip)
+ {
+ // clip using scissors
renderSystem->SetScissors(clip);
}
+ else
+ {
+ // clip using vertex shader
+ renderSystem->ResetScissors();
+
+ float x1 =
+ m_vertexTrans[i].m_clip.x1 - m_vertexTrans[i].m_translateX - m_vertexTrans[i].m_offsetX;
+ float y1 =
+ m_vertexTrans[i].m_clip.y1 - m_vertexTrans[i].m_translateY - m_vertexTrans[i].m_offsetY;
+ float x2 =
+ m_vertexTrans[i].m_clip.x2 - m_vertexTrans[i].m_translateX - m_vertexTrans[i].m_offsetX;
+ float y2 =
+ m_vertexTrans[i].m_clip.y2 - m_vertexTrans[i].m_translateY - m_vertexTrans[i].m_offsetY;
+
+ glUniform4f(clipUniformLoc, x1, y1, x2, y2);
+
+ // setup texture step
+ float stepX = context.GetGUIScaleX() / (static_cast<float>(m_textureWidth));
+ float stepY = context.GetGUIScaleY() / (static_cast<float>(m_textureHeight));
+ glUniform4f(coordStepUniformLoc, stepX, stepY, 1.0f, 1.0f);
+ }
- // Apply the translation to the currently active (top-of-stack) model view matrix
- glMatrixModview.Push();
- glMatrixModview.Get().Translatef(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY,
- m_vertexTrans[i].m_translateZ);
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get());
+ // calculate the fractional offset to the ideal position
+ float fractX =
+ context.ScaleFinalXCoord(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY);
+ float fractY =
+ context.ScaleFinalYCoord(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY);
+ fractX = -fractX + std::round(fractX);
+ fractY = -fractY + std::round(fractY);
+
+ // proj * model * gui * scroll * translation * scaling * correction factor
+ CMatrixGL matrix = glMatrixProject.Get();
+ matrix.MultMatrixf(glMatrixModview.Get());
+ matrix.MultMatrixf(CMatrixGL(context.GetGUIMatrix()));
+ matrix.Translatef(m_vertexTrans[i].m_offsetX, m_vertexTrans[i].m_offsetY, 0.0f);
+ matrix.Translatef(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY, 0.0f);
+ // the gui matrix messes with the scale. correct it here for now.
+ matrix.Scalef(context.GetGUIScaleX(), context.GetGUIScaleY(), 1.0f);
+ // the gui matrix doesn't align to exact pixel coords atm. correct it here for now.
+ matrix.Translatef(fractX, fractY, 0.0f);
+
+ // Apply the depth value of the layer
+ float depth = CServiceBroker::GetWinSystem()->GetGfxContext().GetTransformDepth();
+ glUniform1f(depthLoc, depth);
+
+ glUniformMatrix4fv(matrixUniformLoc, 1, GL_FALSE, matrix);
// Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point
glBindBuffer(GL_ARRAY_BUFFER, m_vertexTrans[i].m_vertexBuffer->bufferHandle);
@@ -236,9 +268,8 @@ void CGUIFontTTFGLES::LastEnd()
glMatrixModview.Pop();
}
// Restore the original scissor rectangle
- renderSystem->SetScissors(scissor);
- // Restore the original model view matrix
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get());
+ if (m_scissorClip)
+ renderSystem->SetScissors(scissor);
// Unbind GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
diff --git a/xbmc/guilib/GUIFontTTFGLES.h b/xbmc/guilib/GUIFontTTFGLES.h
index ae03da74e6..264d1a7611 100644
--- a/xbmc/guilib/GUIFontTTFGLES.h
+++ b/xbmc/guilib/GUIFontTTFGLES.h
@@ -55,4 +55,5 @@ private:
TextureStatus m_textureStatus{TEXTURE_VOID};
static bool m_staticVertexBufferCreated;
+ bool m_scissorClip{false};
};
diff --git a/xbmc/guilib/GUILabelControl.cpp b/xbmc/guilib/GUILabelControl.cpp
index 9728639b13..5f57fbc3a6 100644
--- a/xbmc/guilib/GUILabelControl.cpp
+++ b/xbmc/guilib/GUILabelControl.cpp
@@ -139,6 +139,9 @@ CRect CGUILabelControl::CalcRenderRegion() const
void CGUILabelControl::Render()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
m_label.Render();
CGUIControl::Render();
}
diff --git a/xbmc/guilib/GUILabelControl.dox b/xbmc/guilib/GUILabelControl.dox
index 8501c93114..44bce19494 100644
--- a/xbmc/guilib/GUILabelControl.dox
+++ b/xbmc/guilib/GUILabelControl.dox
@@ -68,9 +68,7 @@ want to be able to give it more content than will fit on one line, then setting:
<wrapmultiline>true</wrapmultiline>
~~~~~~~~~~~~~
-will cause the text to be cut up (at the spaces in the text) onto multiple lines.
-Note that if a single word is larger than <b>`<width>`</b> then it will not be cut, and
-will still overflow.
+Will cause the text to be cut up onto multiple lines.
--------------------------------------------------------------------------------
diff --git a/xbmc/guilib/GUIListItemLayout.cpp b/xbmc/guilib/GUIListItemLayout.cpp
index 3b0f774d3d..35ff8ac462 100644
--- a/xbmc/guilib/GUIListItemLayout.cpp
+++ b/xbmc/guilib/GUIListItemLayout.cpp
@@ -237,6 +237,11 @@ void CGUIListItemLayout::FreeResources(bool immediately)
m_group.FreeResources(immediately);
}
+void CGUIListItemLayout::AssignDepth()
+{
+ m_group.AssignDepth();
+}
+
#ifdef _DEBUG
void CGUIListItemLayout::DumpTextureUse()
{
diff --git a/xbmc/guilib/GUIListItemLayout.h b/xbmc/guilib/GUIListItemLayout.h
index 69d4c4fa63..7ba75794dd 100644
--- a/xbmc/guilib/GUIListItemLayout.h
+++ b/xbmc/guilib/GUIListItemLayout.h
@@ -34,6 +34,7 @@ public:
void SetInvalid() { m_invalidated = true; }
void FreeResources(bool immediately = false);
void SetParentControl(CGUIControl* control) { m_group.SetParentControl(control); }
+ void AssignDepth();
//#ifdef GUILIB_PYTHON_COMPATIBILITY
void CreateListControlLayouts(float width, float height, bool focused, const CLabelInfo &labelInfo, const CLabelInfo &labelInfo2, const CTextureInfo &texture, const CTextureInfo &textureFocus, float texHeight, float iconWidth, float iconHeight, const std::string &nofocusCondition, const std::string &focusCondition);
diff --git a/xbmc/guilib/GUIListLabel.cpp b/xbmc/guilib/GUIListLabel.cpp
index b3138eb7aa..6797ba99dc 100644
--- a/xbmc/guilib/GUIListLabel.cpp
+++ b/xbmc/guilib/GUIListLabel.cpp
@@ -67,6 +67,9 @@ void CGUIListLabel::Process(unsigned int currentTime, CDirtyRegionList &dirtyreg
void CGUIListLabel::Render()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
m_label.Render();
CGUIControl::Render();
}
diff --git a/xbmc/guilib/GUIMultiImage.cpp b/xbmc/guilib/GUIMultiImage.cpp
index e42dc8b1b3..efc5c18b4b 100644
--- a/xbmc/guilib/GUIMultiImage.cpp
+++ b/xbmc/guilib/GUIMultiImage.cpp
@@ -9,6 +9,7 @@
#include "GUIMultiImage.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIMessage.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
diff --git a/xbmc/guilib/GUIPanelContainer.cpp b/xbmc/guilib/GUIPanelContainer.cpp
index 6d64110402..3c757dc157 100644
--- a/xbmc/guilib/GUIPanelContainer.cpp
+++ b/xbmc/guilib/GUIPanelContainer.cpp
@@ -114,6 +114,7 @@ void CGUIPanelContainer::Render()
std::shared_ptr<CGUIListItem> focusedItem;
int current = (offset - cacheBefore) * m_itemsPerRow;
int col = 0;
+ std::vector<RENDERITEM> renderitems;
while (pos < end && m_items.size())
{
if (current >= (int)m_items.size())
@@ -132,9 +133,11 @@ void CGUIPanelContainer::Render()
else
{
if (m_orientation == VERTICAL)
- RenderItem(origin.x + col * m_layout->Size(HORIZONTAL), pos, item.get(), false);
+ renderitems.emplace_back(
+ RENDERITEM{origin.x + col * m_layout->Size(HORIZONTAL), pos, item, false});
else
- RenderItem(pos, origin.y + col * m_layout->Size(VERTICAL), item.get(), false);
+ renderitems.emplace_back(
+ RENDERITEM{pos, origin.y + col * m_layout->Size(VERTICAL), item, false});
}
}
// increment our position
@@ -151,9 +154,27 @@ void CGUIPanelContainer::Render()
if (focusedItem)
{
if (m_orientation == VERTICAL)
- RenderItem(origin.x + focusedCol * m_layout->Size(HORIZONTAL), focusedPos, focusedItem.get(), true);
+ renderitems.emplace_back(RENDERITEM{origin.x + focusedCol * m_layout->Size(HORIZONTAL),
+ focusedPos, focusedItem, true});
else
- RenderItem(focusedPos, origin.y + focusedCol * m_layout->Size(VERTICAL), focusedItem.get(), true);
+ renderitems.emplace_back(RENDERITEM{
+ focusedPos, origin.y + focusedCol * m_layout->Size(VERTICAL), focusedItem, true});
+ }
+
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ {
+ for (auto it = std::crbegin(renderitems); it != std::crend(renderitems); it++)
+ {
+ RenderItem(it->posX, it->posY, it->item.get(), it->focused);
+ }
+ }
+ else
+ {
+ for (const auto& renderitem : renderitems)
+ {
+ RenderItem(renderitem.posX, renderitem.posY, renderitem.item.get(), renderitem.focused);
+ }
}
CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion();
diff --git a/xbmc/guilib/GUISettingsSliderControl.cpp b/xbmc/guilib/GUISettingsSliderControl.cpp
index 1eb0e0e93e..31fb9832f2 100644
--- a/xbmc/guilib/GUISettingsSliderControl.cpp
+++ b/xbmc/guilib/GUISettingsSliderControl.cpp
@@ -81,6 +81,9 @@ void CGUISettingsSliderControl::Render()
{
m_buttonControl.Render();
CGUISliderControl::Render();
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
m_label.Render();
}
diff --git a/xbmc/guilib/GUISpinControl.cpp b/xbmc/guilib/GUISpinControl.cpp
index 2545985a34..62a8caaaad 100644
--- a/xbmc/guilib/GUISpinControl.cpp
+++ b/xbmc/guilib/GUISpinControl.cpp
@@ -555,6 +555,9 @@ void CGUISpinControl::Render()
void CGUISpinControl::RenderText(float posX, float posY, float width, float height)
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
m_label.SetMaxRect(posX, posY, width, height);
m_label.SetColor(GetTextColor());
m_label.Render();
diff --git a/xbmc/guilib/GUITextBox.cpp b/xbmc/guilib/GUITextBox.cpp
index 898b7bb49e..045de2b3e0 100644
--- a/xbmc/guilib/GUITextBox.cpp
+++ b/xbmc/guilib/GUITextBox.cpp
@@ -197,6 +197,10 @@ void CGUITextBox::Process(unsigned int currentTime, CDirtyRegionList &dirtyregio
void CGUITextBox::Render()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
+
// render the repeat anim as appropriate
if (m_autoScrollRepeatAnim)
CServiceBroker::GetWinSystem()->GetGfxContext().SetTransform(m_cachedTextMatrix);
@@ -389,6 +393,12 @@ void CGUITextBox::ResetAutoScrolling()
m_autoScrollRepeatAnim->ResetAnimation();
}
+void CGUITextBox::AssignDepth()
+{
+ CGUIControl::AssignDepth();
+ m_cachedTextMatrix.depth = m_cachedTransform.depth;
+}
+
unsigned int CGUITextBox::GetRows() const
{
return m_lines.size();
diff --git a/xbmc/guilib/GUITextBox.h b/xbmc/guilib/GUITextBox.h
index 7027731c31..23c6fc11e3 100644
--- a/xbmc/guilib/GUITextBox.h
+++ b/xbmc/guilib/GUITextBox.h
@@ -49,6 +49,7 @@ public:
void SetAutoScrolling(const TiXmlNode *node);
void SetAutoScrolling(int delay, int time, int repeatTime, const std::string &condition = "");
void ResetAutoScrolling();
+ void AssignDepth() override;
bool GetCondition(int condition, int data) const override;
virtual std::string GetLabel(int info) const;
diff --git a/xbmc/guilib/GUITextLayout.cpp b/xbmc/guilib/GUITextLayout.cpp
index 1a300f4bb2..11c671b110 100644
--- a/xbmc/guilib/GUITextLayout.cpp
+++ b/xbmc/guilib/GUITextLayout.cpp
@@ -14,6 +14,9 @@
#include "GUIFont.h"
#include "utils/CharsetConverter.h"
#include "utils/StringUtils.h"
+#include "utils/log.h"
+
+#include <limits>
CGUIString::CGUIString(iString start, iString end, bool carriageReturn)
{
@@ -262,7 +265,7 @@ void CGUITextLayout::UpdateStyled(const vecText& text,
m_colors = colors;
// if we need to wrap the text, then do so
- if (m_wrap && maxWidth > 0)
+ if (m_wrap)
WrapText(text, maxWidth);
else
LineBreakText(text, m_lines);
@@ -540,75 +543,103 @@ void CGUITextLayout::WrapText(const vecText &text, float maxWidth)
if (!m_font)
return;
- int nMaxLines = (m_maxHeight > 0 && m_font->GetLineHeight() > 0)?(int)ceilf(m_maxHeight / m_font->GetLineHeight()):-1;
-
m_lines.clear();
+ if (maxWidth < 0)
+ {
+ CLog::LogF(LOGWARNING, "Cannot wrap the text due to invalid max width value.");
+ return;
+ }
+
+ if (maxWidth == 0) // Unlimited max width
+ {
+ LineBreakText(text, m_lines);
+ return;
+ }
+
std::vector<CGUIString> lines;
LineBreakText(text, lines);
- for (unsigned int i = 0; i < lines.size(); i++)
+ size_t nMaxLines;
+ if (m_maxHeight > 0 && m_font->GetLineHeight() > 0)
+ nMaxLines = static_cast<size_t>(std::ceil(m_maxHeight / m_font->GetLineHeight()));
+ else
+ nMaxLines = std::numeric_limits<size_t>::max();
+
+ // Split lines that exceed the maximum width,
+ // lines can be split by last space char or if there are no spaces by character
+ // to mimics the line behavior of word processors
+ for (const CGUIString& line : lines)
{
- const CGUIString &line = lines[i];
- vecText::const_iterator lastSpace = line.m_text.begin();
+ if (m_lines.size() >= nMaxLines)
+ return;
+
+ if (line.m_text.empty()) // Blank line
+ {
+ m_lines.emplace_back(line);
+ continue;
+ }
+
vecText::const_iterator pos = line.m_text.begin();
- unsigned int lastSpaceInLine = 0;
+ vecText::const_iterator lastBeginPos = line.m_text.begin();
+ vecText::const_iterator lastSpacePos = line.m_text.end();
vecText curLine;
- while (pos != line.m_text.end())
+
+ while (pos < line.m_text.end())
{
// Get the current letter in the string
- character_t letter = *pos;
- // check for a space
- if (CanWrapAtLetter(letter))
+ const character_t& letter = *pos;
+
+ if (CanWrapAtLetter(letter)) // Check for a space char
+ lastSpacePos = pos;
+
+ curLine.emplace_back(letter);
+
+ const float currWidth = m_font->GetTextWidth(curLine);
+
+ if (currWidth > maxWidth)
{
- float width = m_font->GetTextWidth(curLine);
- if (width > maxWidth)
+ if (lastSpacePos > pos) // No space char where split the line, so split by char
{
- if (lastSpace != line.m_text.begin() && lastSpaceInLine > 0)
- {
- CGUIString string(curLine.begin(), curLine.begin() + lastSpaceInLine, false);
- m_lines.push_back(string);
- // check for exceeding our number of lines
- if (nMaxLines > 0 && m_lines.size() >= (size_t)nMaxLines)
- return;
- // skip over spaces
- pos = lastSpace;
- while (pos != line.m_text.end() && IsSpace(*pos))
- ++pos;
- curLine.clear();
- lastSpaceInLine = 0;
- lastSpace = line.m_text.begin();
- continue;
- }
+ // If the pos is equal to lastBeginPos, maxWidth is not large enough to contain 1 character
+ // Push a line with the single character and move on to the next character.
+ if (pos == lastBeginPos)
+ ++pos;
+
+ CGUIString linePart{lastBeginPos, pos, false};
+ m_lines.emplace_back(linePart);
}
- lastSpace = pos;
- lastSpaceInLine = curLine.size();
+ else
+ {
+ CGUIString linePart{lastBeginPos, lastSpacePos, false};
+ m_lines.emplace_back(linePart);
+
+ pos = lastSpacePos + 1;
+ lastSpacePos = line.m_text.end();
+ }
+
+ curLine.clear();
+ lastBeginPos = pos;
+
+ if (m_lines.size() >= nMaxLines)
+ return;
+
+ continue;
}
- curLine.push_back(letter);
+
++pos;
}
- // now add whatever we have left to the string
- float width = m_font->GetTextWidth(curLine);
- if (width > maxWidth)
+
+ // Add the remaining text part
+ if (!curLine.empty())
{
- // too long - put up to the last space on if we can + remove it from what's left.
- if (lastSpace != line.m_text.begin() && lastSpaceInLine > 0)
- {
- CGUIString string(curLine.begin(), curLine.begin() + lastSpaceInLine, false);
- m_lines.push_back(string);
- // check for exceeding our number of lines
- if (nMaxLines > 0 && m_lines.size() >= (size_t)nMaxLines)
- return;
- curLine.erase(curLine.begin(), curLine.begin() + lastSpaceInLine);
- while (curLine.size() && IsSpace(curLine.at(0)))
- curLine.erase(curLine.begin());
- }
+ CGUIString linePart{curLine.begin(), curLine.end(), false};
+ m_lines.emplace_back(linePart);
}
- CGUIString string(curLine.begin(), curLine.end(), true);
- m_lines.push_back(string);
- // check for exceeding our number of lines
- if (nMaxLines > 0 && m_lines.size() >= (size_t)nMaxLines)
- return;
+
+ // Restore carriage return marker for the end of paragraph
+ if (!m_lines.empty())
+ m_lines.back().m_carriageReturn = line.m_carriageReturn;
}
}
diff --git a/xbmc/guilib/GUITexture.cpp b/xbmc/guilib/GUITexture.cpp
index 7f2f51dbbc..7a3e004ad9 100644
--- a/xbmc/guilib/GUITexture.cpp
+++ b/xbmc/guilib/GUITexture.cpp
@@ -9,6 +9,7 @@
#include "GUITexture.h"
#include "GUILargeTextureManager.h"
+#include "Texture.h"
#include "TextureManager.h"
#include "utils/MathUtils.h"
#include "utils/StringUtils.h"
@@ -52,13 +53,20 @@ CGUITexture* CGUITexture::CreateTexture(
void CGUITexture::DrawQuad(const CRect& coords,
UTILS::COLOR::Color color,
CTexture* texture,
- const CRect* texCoords)
+ const CRect* texCoords,
+ const float depth,
+ const bool blending)
{
+ // bail for now if we render front to back
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
+
if (!m_drawQuadFunc)
throw std::runtime_error(
"No GUITexture DrawQuad function available. Did you forget to register?");
- m_drawQuadFunc(coords, color, texture, texCoords);
+ m_drawQuadFunc(coords, color, texture, texCoords, depth, blending);
}
CGUITexture::CGUITexture(
@@ -163,29 +171,54 @@ bool CGUITexture::Process(unsigned int currentTime)
return changed;
}
-void CGUITexture::Render()
+void CGUITexture::Render(int32_t depthOffset, int32_t overrideDepth)
{
if (!m_visible || !m_texture.size())
return;
- // see if we need to clip the image
- if (m_vertex.Width() > m_width || m_vertex.Height() > m_height)
- {
- if (!CServiceBroker::GetWinSystem()->GetGfxContext().SetClipRegion(m_posX, m_posY, m_width, m_height))
- return;
- }
-
// set our draw color
#define MIX_ALPHA(a,c) (((a * (c >> 24)) / 255) << 24) | (c & 0x00ffffff)
// diffuse color
UTILS::COLOR::Color color =
(m_info.diffuseColor) ? (UTILS::COLOR::Color)m_info.diffuseColor : m_diffuseColor;
+ // clang-format off
if (m_alpha != 0xFF)
- color = MIX_ALPHA(m_alpha, color);
+ color = MIX_ALPHA(m_alpha, color);
+ // clang-format on
color = CServiceBroker::GetWinSystem()->GetGfxContext().MergeColor(color);
+ if (overrideDepth >= 0)
+ {
+ m_depth = CServiceBroker::GetWinSystem()->GetGfxContext().GetNormalizedDepth(overrideDepth +
+ depthOffset);
+ }
+ else
+ {
+ m_depth = CServiceBroker::GetWinSystem()->GetGfxContext().GetTransformDepth(depthOffset);
+ }
+
+ bool hasAlpha =
+ (((color >> 24) & 0xFF) != 0xFF || m_texture.m_textures[m_currentFrame]->HasAlpha());
+ if (m_diffuse.size())
+ hasAlpha |= m_diffuse.m_textures[0]->HasAlpha();
+
+ // bail if it is not the appropriate render pass
+ RENDER_ORDER renderOrder = CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder();
+ if (hasAlpha && renderOrder == RENDER_ORDER_FRONT_TO_BACK)
+ return;
+ if (!hasAlpha && renderOrder == RENDER_ORDER_BACK_TO_FRONT)
+ return;
+
+ // see if we need to clip the image
+ if (m_vertex.Width() > m_width || m_vertex.Height() > m_height)
+ {
+ if (!CServiceBroker::GetWinSystem()->GetGfxContext().SetClipRegion(m_posX, m_posY, m_width,
+ m_height))
+ return;
+ }
+
// setup our renderer
Begin(color);
diff --git a/xbmc/guilib/GUITexture.h b/xbmc/guilib/GUITexture.h
index c34dedc259..bbedc3aa21 100644
--- a/xbmc/guilib/GUITexture.h
+++ b/xbmc/guilib/GUITexture.h
@@ -67,8 +67,12 @@ class CGUITexture;
using CreateGUITextureFunc = std::function<CGUITexture*(
float posX, float posY, float width, float height, const CTextureInfo& texture)>;
-using DrawQuadFunc = std::function<void(
- const CRect& coords, UTILS::COLOR::Color color, CTexture* texture, const CRect* texCoords)>;
+using DrawQuadFunc = std::function<void(const CRect& coords,
+ UTILS::COLOR::Color color,
+ CTexture* texture,
+ const CRect* texCoords,
+ const float depth,
+ const bool blending)>;
class CGUITexture
{
@@ -85,10 +89,12 @@ public:
static void DrawQuad(const CRect& coords,
UTILS::COLOR::Color color,
CTexture* texture = nullptr,
- const CRect* texCoords = nullptr);
+ const CRect* texCoords = nullptr,
+ const float depth = 1.0,
+ const bool blending = true);
bool Process(unsigned int currentTime);
- void Render();
+ void Render(int32_t depthOffset = 0, int32_t overrideDepth = -1);
void DynamicResourceAlloc(bool bOnOff);
bool AllocResources();
@@ -172,6 +178,7 @@ protected:
float m_posY;
float m_width;
float m_height;
+ float m_depth{0};
CRect m_vertex; // vertex coords to render
bool m_invalid; // if true, we need to recalculate
diff --git a/xbmc/guilib/GUITextureD3D.cpp b/xbmc/guilib/GUITextureD3D.cpp
index d031cac40a..68ce6f06f7 100644
--- a/xbmc/guilib/GUITextureD3D.cpp
+++ b/xbmc/guilib/GUITextureD3D.cpp
@@ -140,7 +140,9 @@ void CGUITextureD3D::Draw(float *x, float *y, float *z, const CRect &texture, co
void CGUITextureD3D::DrawQuad(const CRect& rect,
UTILS::COLOR::Color color,
CTexture* texture,
- const CRect* texCoords)
+ const CRect* texCoords,
+ const float depth,
+ const bool blending)
{
unsigned numViews = 0;
ID3D11ShaderResourceView* views = nullptr;
diff --git a/xbmc/guilib/GUITextureD3D.h b/xbmc/guilib/GUITextureD3D.h
index a649f85ab1..87fd9a7848 100644
--- a/xbmc/guilib/GUITextureD3D.h
+++ b/xbmc/guilib/GUITextureD3D.h
@@ -21,7 +21,9 @@ public:
static void DrawQuad(const CRect& coords,
UTILS::COLOR::Color color,
CTexture* texture = nullptr,
- const CRect* texCoords = nullptr);
+ const CRect* texCoords = nullptr,
+ const float depth = 1.0,
+ const bool blending = true);
CGUITextureD3D(float posX, float posY, float width, float height, const CTextureInfo& texture);
~CGUITextureD3D() override = default;
diff --git a/xbmc/guilib/GUITextureGL.cpp b/xbmc/guilib/GUITextureGL.cpp
index 6e46aa700a..c2f23ccdfb 100644
--- a/xbmc/guilib/GUITextureGL.cpp
+++ b/xbmc/guilib/GUITextureGL.cpp
@@ -108,6 +108,7 @@ void CGUITextureGL::End()
GLint tex0Loc = m_renderSystem->ShaderGetCoord0();
GLint tex1Loc = m_renderSystem->ShaderGetCoord1();
GLint uniColLoc = m_renderSystem->ShaderGetUniCol();
+ GLint depthLoc = m_renderSystem->ShaderGetDepth();
GLuint VertexVBO;
GLuint IndexVBO;
@@ -116,6 +117,8 @@ void CGUITextureGL::End()
glBindBuffer(GL_ARRAY_BUFFER, VertexVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex)*m_packedVertices.size(), &m_packedVertices[0], GL_STATIC_DRAW);
+ glUniform1f(depthLoc, m_depth);
+
if (uniColLoc >= 0)
{
glUniform4f(uniColLoc,(m_col[0] / 255.0f), (m_col[1] / 255.0f), (m_col[2] / 255.0f), (m_col[3] / 255.0f));
@@ -255,7 +258,9 @@ void CGUITextureGL::Draw(float *x, float *y, float *z, const CRect &texture, con
void CGUITextureGL::DrawQuad(const CRect& rect,
UTILS::COLOR::Color color,
CTexture* texture,
- const CRect* texCoords)
+ const CRect* texCoords,
+ const float depth,
+ const bool blending)
{
CRenderSystemGL *renderSystem = dynamic_cast<CRenderSystemGL*>(CServiceBroker::GetRenderSystem());
if (texture)
@@ -264,8 +269,15 @@ void CGUITextureGL::DrawQuad(const CRect& rect,
texture->BindToUnit(0);
}
- glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND); // Turn Blending On
+ if (blending)
+ {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ }
+ else
+ {
+ glDisable(GL_BLEND);
+ }
VerifyGLState();
@@ -288,6 +300,7 @@ void CGUITextureGL::DrawQuad(const CRect& rect,
GLint posLoc = renderSystem->ShaderGetPos();
GLint tex0Loc = renderSystem->ShaderGetCoord0();
GLint uniColLoc = renderSystem->ShaderGetUniCol();
+ GLint depthLoc = renderSystem->ShaderGetDepth();
// Setup Colors
col[0] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::R, color);
@@ -296,6 +309,7 @@ void CGUITextureGL::DrawQuad(const CRect& rect,
col[3] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A, color);
glUniform4f(uniColLoc, col[0] / 255.0f, col[1] / 255.0f, col[2] / 255.0f, col[3] / 255.0f);
+ glUniform1f(depthLoc, depth);
// bottom left
vertex[0].x = rect.x1;
diff --git a/xbmc/guilib/GUITextureGL.h b/xbmc/guilib/GUITextureGL.h
index 4acba1eb6d..5850586a22 100644
--- a/xbmc/guilib/GUITextureGL.h
+++ b/xbmc/guilib/GUITextureGL.h
@@ -27,7 +27,9 @@ public:
static void DrawQuad(const CRect& coords,
UTILS::COLOR::Color color,
CTexture* texture = nullptr,
- const CRect* texCoords = nullptr);
+ const CRect* texCoords = nullptr,
+ const float depth = 1.0,
+ const bool blending = true);
CGUITextureGL(float posX, float posY, float width, float height, const CTextureInfo& texture);
~CGUITextureGL() override = default;
diff --git a/xbmc/guilib/GUITextureGLES.cpp b/xbmc/guilib/GUITextureGLES.cpp
index d92201ae7f..97fdb28679 100644
--- a/xbmc/guilib/GUITextureGLES.cpp
+++ b/xbmc/guilib/GUITextureGLES.cpp
@@ -114,12 +114,15 @@ void CGUITextureGLES::End()
GLint tex0Loc = m_renderSystem->GUIShaderGetCoord0();
GLint tex1Loc = m_renderSystem->GUIShaderGetCoord1();
GLint uniColLoc = m_renderSystem->GUIShaderGetUniCol();
+ GLint depthLoc = m_renderSystem->GUIShaderGetDepth();
if(uniColLoc >= 0)
{
glUniform4f(uniColLoc,(m_col[0] / 255.0f), (m_col[1] / 255.0f), (m_col[2] / 255.0f), (m_col[3] / 255.0f));
}
+ glUniform1f(depthLoc, m_depth);
+
if(m_diffuse.size())
{
glVertexAttribPointer(tex1Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), (char*)&m_packedVertices[0] + offsetof(PackedVertex, u2));
@@ -234,7 +237,9 @@ void CGUITextureGLES::Draw(float *x, float *y, float *z, const CRect &texture, c
void CGUITextureGLES::DrawQuad(const CRect& rect,
UTILS::COLOR::Color color,
CTexture* texture,
- const CRect* texCoords)
+ const CRect* texCoords,
+ const float depth,
+ const bool blending)
{
CRenderSystemGLES *renderSystem = dynamic_cast<CRenderSystemGLES*>(CServiceBroker::GetRenderSystem());
if (texture)
@@ -243,8 +248,15 @@ void CGUITextureGLES::DrawQuad(const CRect& rect,
texture->BindToUnit(0);
}
- glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND); // Turn Blending On
+ if (blending)
+ {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ }
+ else
+ {
+ glDisable(GL_BLEND);
+ }
VerifyGLState();
@@ -261,6 +273,7 @@ void CGUITextureGLES::DrawQuad(const CRect& rect,
GLint posLoc = renderSystem->GUIShaderGetPos();
GLint tex0Loc = renderSystem->GUIShaderGetCoord0();
GLint uniColLoc= renderSystem->GUIShaderGetUniCol();
+ GLint depthLoc = renderSystem->GUIShaderGetDepth();
glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, 0, ver);
if (texture)
@@ -277,6 +290,7 @@ void CGUITextureGLES::DrawQuad(const CRect& rect,
col[3] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A, color);
glUniform4f(uniColLoc, col[0] / 255.0f, col[1] / 255.0f, col[2] / 255.0f, col[3] / 255.0f);
+ glUniform1f(depthLoc, depth);
ver[0][0] = ver[3][0] = rect.x1;
ver[0][1] = ver[1][1] = rect.y1;
diff --git a/xbmc/guilib/GUITextureGLES.h b/xbmc/guilib/GUITextureGLES.h
index a9b361031b..ad563704e0 100644
--- a/xbmc/guilib/GUITextureGLES.h
+++ b/xbmc/guilib/GUITextureGLES.h
@@ -36,7 +36,9 @@ public:
static void DrawQuad(const CRect& coords,
UTILS::COLOR::Color color,
CTexture* texture = nullptr,
- const CRect* texCoords = nullptr);
+ const CRect* texCoords = nullptr,
+ const float depth = 1.0,
+ const bool blending = true);
CGUITextureGLES(float posX, float posY, float width, float height, const CTextureInfo& texture);
~CGUITextureGLES() override = default;
diff --git a/xbmc/guilib/GUIVideoControl.cpp b/xbmc/guilib/GUIVideoControl.cpp
index a24b20e3cf..ccb066a754 100644
--- a/xbmc/guilib/GUIVideoControl.cpp
+++ b/xbmc/guilib/GUIVideoControl.cpp
@@ -9,6 +9,7 @@
#include "GUIVideoControl.h"
#include "GUIComponent.h"
+#include "GUITexture.h"
#include "GUIWindowManager.h"
#include "ServiceBroker.h"
#include "application/ApplicationComponents.h"
@@ -17,6 +18,7 @@
#include "input/actions/ActionIDs.h"
#include "input/mouse/MouseEvent.h"
#include "utils/ColorUtils.h"
+#include "windowing/GraphicContext.h"
using namespace KODI;
@@ -41,6 +43,9 @@ void CGUIVideoControl::Process(unsigned int currentTime, CDirtyRegionList &dirty
void CGUIVideoControl::Render()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
auto& components = CServiceBroker::GetAppComponents();
const auto appPlayer = components.GetComponent<CApplicationPlayer>();
if (appPlayer->IsRenderingVideo())
@@ -64,7 +69,14 @@ void CGUIVideoControl::Render()
CRect region = GetRenderRegion();
region.Intersect(old);
CServiceBroker::GetWinSystem()->GetGfxContext().SetScissors(region);
- CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0);
+
+ // with dual pass rendering, we need to "clear" with a quad, as we need to conserve the already rendered layers
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_BACK_TO_FRONT)
+ CGUITexture::DrawQuad(region, 0x00000000, nullptr, nullptr, -1.0f, false);
+ else if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_ALL_BACK_TO_FRONT)
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0);
CServiceBroker::GetWinSystem()->GetGfxContext().SetScissors(old);
}
else
diff --git a/xbmc/guilib/GUIWindow.cpp b/xbmc/guilib/GUIWindow.cpp
index ebb133d870..26fae889b7 100644
--- a/xbmc/guilib/GUIWindow.cpp
+++ b/xbmc/guilib/GUIWindow.cpp
@@ -1078,6 +1078,10 @@ void CGUIWindow::ClearBackground()
UTILS::COLOR::Color color = m_clearBackground;
if (color)
CServiceBroker::GetWinSystem()->GetGfxContext().Clear(color);
+ else if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiGeometryClear)
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0xff000000);
+ else
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear();
}
void CGUIWindow::SetID(int id)
diff --git a/xbmc/guilib/GUIWindowManager.cpp b/xbmc/guilib/GUIWindowManager.cpp
index abf7feae25..993a34c7c9 100644
--- a/xbmc/guilib/GUIWindowManager.cpp
+++ b/xbmc/guilib/GUIWindowManager.cpp
@@ -1224,6 +1224,19 @@ void CGUIWindowManager::Process(unsigned int currentTime)
pWindow->DoProcess(currentTime, m_dirtyregions);
}
+ // assign depth values to all active controls
+ if (pWindow)
+ pWindow->AssignDepth();
+
+ std::vector<CGUIWindow*> activeDialogs = m_activeDialogs;
+ stable_sort(activeDialogs.begin(), activeDialogs.end(), RenderOrderSortFunction);
+
+ for (const auto& window : activeDialogs)
+ {
+ if (window->IsDialogRunning())
+ window->AssignDepth();
+ }
+
for (auto& itr : m_dirtyregions)
m_tracker.MarkDirtyRegion(itr);
}
@@ -1250,6 +1263,14 @@ void CGUIWindowManager::MarkDirty(const CRect& rect)
void CGUIWindowManager::RenderPass() const
{
+ if (CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering)
+ RenderPassDual();
+ else
+ RenderPassSingle();
+}
+
+void CGUIWindowManager::RenderPassSingle() const
+{
CGUIWindow* pWindow = GetWindow(GetActiveWindow());
if (pWindow)
{
@@ -1268,6 +1289,40 @@ void CGUIWindowManager::RenderPass() const
}
}
+void CGUIWindowManager::RenderPassDual() const
+{
+ CGUIWindow* pWindow = GetWindow(GetActiveWindow());
+ if (pWindow)
+ pWindow->ClearBackground();
+
+ std::vector<CGUIWindow*> renderList = m_activeDialogs;
+ stable_sort(renderList.begin(), renderList.end(), RenderOrderSortFunction);
+
+ // first the opaque pass, rendering from front to back
+ CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderOrder(RENDER_ORDER_FRONT_TO_BACK);
+ for (auto it = renderList.rbegin(); it != renderList.rend(); ++it)
+ {
+ if ((*it)->IsDialogRunning())
+ (*it)->DoRender();
+ }
+
+ if (pWindow)
+ pWindow->DoRender();
+
+ // now we render all elements with transparency back to front
+ CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderOrder(RENDER_ORDER_BACK_TO_FRONT);
+ if (pWindow)
+ {
+ pWindow->DoRender();
+ }
+
+ for (const auto& window : renderList)
+ {
+ if (window->IsDialogRunning())
+ window->DoRender();
+ }
+}
+
void CGUIWindowManager::RenderEx() const
{
CGUIWindow* pWindow = GetWindow(GetActiveWindow());
@@ -1337,6 +1392,7 @@ bool CGUIWindowManager::Render()
void CGUIWindowManager::AfterRender()
{
+ CServiceBroker::GetWinSystem()->GetGfxContext().ResetDepth();
m_tracker.CleanMarkedRegions();
CGUIWindow* pWindow = GetWindow(GetActiveWindow());
diff --git a/xbmc/guilib/GUIWindowManager.h b/xbmc/guilib/GUIWindowManager.h
index 9bbd281713..b7f2373d77 100644
--- a/xbmc/guilib/GUIWindowManager.h
+++ b/xbmc/guilib/GUIWindowManager.h
@@ -231,6 +231,12 @@ public:
#endif
private:
void RenderPass() const;
+ /*! \brief Render in one back to front pass.
+ */
+ void RenderPassSingle() const;
+ /*! \brief Render opaque elements front to back, and transparent ones back to front
+ */
+ void RenderPassDual() const;
void LoadNotOnDemandWindows();
void UnloadNotOnDemandWindows();
diff --git a/xbmc/guilib/Texture.cpp b/xbmc/guilib/Texture.cpp
index cfc506d48c..af97003663 100644
--- a/xbmc/guilib/Texture.cpp
+++ b/xbmc/guilib/Texture.cpp
@@ -15,6 +15,7 @@
#include "filesystem/File.h"
#include "filesystem/ResourceFile.h"
#include "filesystem/XbtFile.h"
+#include "guilib/TextureBase.h"
#include "guilib/iimage.h"
#include "guilib/imagefactory.h"
#include "utils/URIUtils.h"
@@ -50,70 +51,6 @@ CTexture::~CTexture()
m_pixels = NULL;
}
-void CTexture::Allocate(unsigned int width, unsigned int height, XB_FMT format)
-{
- m_imageWidth = m_originalWidth = width;
- m_imageHeight = m_originalHeight = height;
- m_format = format;
- m_orientation = 0;
-
- m_textureWidth = m_imageWidth;
- m_textureHeight = m_imageHeight;
-
- if (m_format & XB_FMT_DXT_MASK)
- {
- while (GetPitch() < CServiceBroker::GetRenderSystem()->GetMinDXTPitch())
- m_textureWidth += GetBlockSize();
- }
-
- if (!CServiceBroker::GetRenderSystem()->SupportsNPOT((m_format & XB_FMT_DXT_MASK) != 0))
- {
- m_textureWidth = PadPow2(m_textureWidth);
- m_textureHeight = PadPow2(m_textureHeight);
- }
-
- if (m_format & XB_FMT_DXT_MASK)
- {
- // DXT textures must be a multiple of 4 in width and height
- m_textureWidth = ((m_textureWidth + 3) / 4) * 4;
- m_textureHeight = ((m_textureHeight + 3) / 4) * 4;
- }
- else
- {
- // align all textures so that they have an even width
- // in some circumstances when we downsize a thumbnail
- // which has an uneven number of pixels in width
- // we crash in CPicture::ScaleImage in ffmpegs swscale
- // because it tries to access beyond the source memory
- // (happens on osx and ios)
- // UPDATE: don't just update to be on an even width;
- // ffmpegs swscale relies on a 16-byte stride on some systems
- // so the textureWidth needs to be a multiple of 16. see ffmpeg
- // swscale headers for more info.
- m_textureWidth = ((m_textureWidth + 15) / 16) * 16;
- }
-
- // check for max texture size
- #define CLAMP(x, y) { if (x > y) x = y; }
- CLAMP(m_textureWidth, CServiceBroker::GetRenderSystem()->GetMaxTextureSize());
- CLAMP(m_textureHeight, CServiceBroker::GetRenderSystem()->GetMaxTextureSize());
- CLAMP(m_imageWidth, m_textureWidth);
- CLAMP(m_imageHeight, m_textureHeight);
-
- KODI::MEMORY::AlignedFree(m_pixels);
- m_pixels = NULL;
- if (GetPitch() * GetRows() > 0)
- {
- size_t size = GetPitch() * GetRows();
- m_pixels = static_cast<unsigned char*>(KODI::MEMORY::AlignedMalloc(size, 32));
-
- if (m_pixels == nullptr)
- {
- CLog::Log(LOGERROR, "{} - Could not allocate {} bytes. Out of memory.", __FUNCTION__, size);
- }
- }
-}
-
void CTexture::Update(unsigned int width,
unsigned int height,
unsigned int pitch,
@@ -156,39 +93,6 @@ void CTexture::Update(unsigned int width,
LoadToGPU();
}
-void CTexture::ClampToEdge()
-{
- if (m_pixels == nullptr)
- return;
-
- unsigned int imagePitch = GetPitch(m_imageWidth);
- unsigned int imageRows = GetRows(m_imageHeight);
- unsigned int texturePitch = GetPitch(m_textureWidth);
- unsigned int textureRows = GetRows(m_textureHeight);
- if (imagePitch < texturePitch)
- {
- unsigned int blockSize = GetBlockSize();
- unsigned char *src = m_pixels + imagePitch - blockSize;
- unsigned char *dst = m_pixels;
- for (unsigned int y = 0; y < imageRows; y++)
- {
- for (unsigned int x = imagePitch; x < texturePitch; x += blockSize)
- memcpy(dst + x, src, blockSize);
- dst += texturePitch;
- }
- }
-
- if (imageRows < textureRows)
- {
- unsigned char *dst = m_pixels + imageRows * texturePitch;
- for (unsigned int y = imageRows; y < textureRows; y++)
- {
- memcpy(dst, dst - texturePitch, texturePitch);
- dst += texturePitch;
- }
- }
-}
-
std::unique_ptr<CTexture> CTexture::LoadFromFile(const std::string& texturePath,
unsigned int idealWidth,
unsigned int idealHeight,
@@ -397,99 +301,3 @@ bool CTexture::LoadPaletted(unsigned int width,
ClampToEdge();
return true;
}
-
-unsigned int CTexture::PadPow2(unsigned int x)
-{
- --x;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- x |= x >> 8;
- x |= x >> 16;
- return ++x;
-}
-
-bool CTexture::SwapBlueRed(unsigned char* pixels,
- unsigned int height,
- unsigned int pitch,
- unsigned int elements,
- unsigned int offset)
-{
- if (!pixels) return false;
- unsigned char *dst = pixels;
- for (unsigned int y = 0; y < height; y++)
- {
- dst = pixels + (y * pitch);
- for (unsigned int x = 0; x < pitch; x+=elements)
- std::swap(dst[x+offset], dst[x+2+offset]);
- }
- return true;
-}
-
-unsigned int CTexture::GetPitch(unsigned int width) const
-{
- switch (m_format)
- {
- case XB_FMT_DXT1:
- return ((width + 3) / 4) * 8;
- case XB_FMT_DXT3:
- case XB_FMT_DXT5:
- case XB_FMT_DXT5_YCoCg:
- return ((width + 3) / 4) * 16;
- case XB_FMT_A8:
- return width;
- case XB_FMT_RGB8:
- return (((width + 1)* 3 / 4) * 4);
- case XB_FMT_RGBA8:
- case XB_FMT_A8R8G8B8:
- default:
- return width*4;
- }
-}
-
-unsigned int CTexture::GetRows(unsigned int height) const
-{
- switch (m_format)
- {
- case XB_FMT_DXT1:
- return (height + 3) / 4;
- case XB_FMT_DXT3:
- case XB_FMT_DXT5:
- case XB_FMT_DXT5_YCoCg:
- return (height + 3) / 4;
- default:
- return height;
- }
-}
-
-unsigned int CTexture::GetBlockSize() const
-{
- switch (m_format)
- {
- case XB_FMT_DXT1:
- return 8;
- case XB_FMT_DXT3:
- case XB_FMT_DXT5:
- case XB_FMT_DXT5_YCoCg:
- return 16;
- case XB_FMT_A8:
- return 1;
- default:
- return 4;
- }
-}
-
-bool CTexture::HasAlpha() const
-{
- return m_hasAlpha;
-}
-
-void CTexture::SetMipmapping()
-{
- m_mipmapping = true;
-}
-
-bool CTexture::IsMipmapped() const
-{
- return m_mipmapping;
-}
diff --git a/xbmc/guilib/Texture.h b/xbmc/guilib/Texture.h
index 5e32e60f8f..605d56b380 100644
--- a/xbmc/guilib/Texture.h
+++ b/xbmc/guilib/Texture.h
@@ -8,6 +8,7 @@
#pragma once
+#include "guilib/TextureBase.h"
#include "guilib/TextureFormats.h"
#include <cstddef>
@@ -21,17 +22,11 @@ class IImage;
struct COLOR {unsigned char b,g,r,x;}; // Windows GDI expects 4bytes per color
#pragma pack()
-enum class TEXTURE_SCALING
-{
- LINEAR,
- NEAREST,
-};
-
/*!
\ingroup textures
-\brief Base texture class, subclasses of which depend on the render spec (DX, GL etc.)
+\brief Texture loader class, subclasses of which depend on the render spec (DX, GL etc.)
*/
-class CTexture
+class CTexture : public CTextureBase
{
public:
@@ -86,47 +81,17 @@ public:
const unsigned char* pixels,
const COLOR* palette);
- bool HasAlpha() const;
- void SetAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
-
- void SetMipmapping();
- bool IsMipmapped() const;
- void SetScalingMethod(TEXTURE_SCALING scalingMethod) { m_scalingMethod = scalingMethod; }
- TEXTURE_SCALING GetScalingMethod() const { return m_scalingMethod; }
- void SetCacheMemory(bool bCacheMemory) { m_bCacheMemory = bCacheMemory; }
- bool GetCacheMemory() const { return m_bCacheMemory; }
-
- virtual void CreateTextureObject() = 0;
- virtual void DestroyTextureObject() = 0;
- virtual void LoadToGPU() = 0;
- virtual void BindToUnit(unsigned int unit) = 0;
-
- unsigned char* GetPixels() const { return m_pixels; }
- unsigned int GetPitch() const { return GetPitch(m_textureWidth); }
- unsigned int GetRows() const { return GetRows(m_textureHeight); }
- unsigned int GetTextureWidth() const { return m_textureWidth; }
- unsigned int GetTextureHeight() const { return m_textureHeight; }
- unsigned int GetWidth() const { return m_imageWidth; }
- unsigned int GetHeight() const { return m_imageHeight; }
- /*! \brief return the original width of the image, before scaling/cropping */
- unsigned int GetOriginalWidth() const { return m_originalWidth; }
- /*! \brief return the original height of the image, before scaling/cropping */
- unsigned int GetOriginalHeight() const { return m_originalHeight; }
-
- int GetOrientation() const { return m_orientation; }
- void SetOrientation(int orientation) { m_orientation = orientation; }
-
void Update(unsigned int width,
unsigned int height,
unsigned int pitch,
XB_FMT format,
const unsigned char* pixels,
bool loadToGPU);
- void Allocate(unsigned int width, unsigned int height, XB_FMT format);
- void ClampToEdge();
- static unsigned int PadPow2(unsigned int x);
- static bool SwapBlueRed(unsigned char *pixels, unsigned int height, unsigned int pitch, unsigned int elements = 4, unsigned int offset=0);
+ virtual void CreateTextureObject() = 0;
+ virtual void DestroyTextureObject() = 0;
+ virtual void LoadToGPU() = 0;
+ virtual void BindToUnit(unsigned int unit) = 0;
private:
// no copy constructor
@@ -136,25 +101,9 @@ protected:
bool LoadFromFileInMem(unsigned char* buffer, size_t size, const std::string& mimeType,
unsigned int maxWidth, unsigned int maxHeight);
bool LoadFromFileInternal(const std::string& texturePath, unsigned int maxWidth, unsigned int maxHeight, bool requirePixels, const std::string& strMimeType = "");
- bool LoadIImage(IImage* pImage, unsigned char* buffer, unsigned int bufSize, unsigned int width, unsigned int height);
- // helpers for computation of texture parameters for compressed textures
- unsigned int GetPitch(unsigned int width) const;
- unsigned int GetRows(unsigned int height) const;
- unsigned int GetBlockSize() const;
-
- unsigned int m_imageWidth;
- unsigned int m_imageHeight;
- unsigned int m_textureWidth;
- unsigned int m_textureHeight;
- unsigned int m_originalWidth; ///< original image width before scaling or cropping
- unsigned int m_originalHeight; ///< original image height before scaling or cropping
-
- unsigned char* m_pixels;
- bool m_loadedToGPU;
- XB_FMT m_format;
- int m_orientation;
- bool m_hasAlpha = true ;
- bool m_mipmapping = false ;
- TEXTURE_SCALING m_scalingMethod = TEXTURE_SCALING::LINEAR;
- bool m_bCacheMemory = false;
+ bool LoadIImage(IImage* pImage,
+ unsigned char* buffer,
+ unsigned int bufSize,
+ unsigned int width,
+ unsigned int height);
};
diff --git a/xbmc/guilib/TextureBase.cpp b/xbmc/guilib/TextureBase.cpp
new file mode 100644
index 0000000000..5c2c01e22b
--- /dev/null
+++ b/xbmc/guilib/TextureBase.cpp
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "TextureBase.h"
+
+#include "ServiceBroker.h"
+#include "commons/ilog.h"
+#include "guilib/TextureFormats.h"
+#include "rendering/RenderSystem.h"
+#include "utils/MemUtils.h"
+#include "utils/log.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <cstring>
+#include <exception>
+#include <utility>
+
+void CTextureBase::Allocate(uint32_t width, uint32_t height, XB_FMT format)
+{
+ SetKDFormat(format);
+ m_imageWidth = m_originalWidth = width;
+ m_imageHeight = m_originalHeight = height;
+ m_format = format;
+ m_orientation = 0;
+
+ m_textureWidth = m_imageWidth;
+ m_textureHeight = m_imageHeight;
+
+ if (!CServiceBroker::GetRenderSystem()->SupportsNPOT((m_textureFormat & KD_TEX_FMT_TYPE_MASK) !=
+ KD_TEX_FMT_S3TC))
+ {
+ m_textureWidth = PadPow2(m_textureWidth);
+ m_textureHeight = PadPow2(m_textureHeight);
+ }
+
+ if ((m_textureFormat & KD_TEX_FMT_TYPE_MASK) == KD_TEX_FMT_S3TC)
+ {
+ // DXT textures must be a multiple of 4 in width and height
+ m_textureWidth = ((m_textureWidth + 3) / 4) * 4;
+ m_textureHeight = ((m_textureHeight + 3) / 4) * 4;
+ }
+ else
+ {
+ // align all textures so that they have an even width
+ // in some circumstances when we downsize a thumbnail
+ // which has an uneven number of pixels in width
+ // we crash in CPicture::ScaleImage in ffmpegs swscale
+ // because it tries to access beyond the source memory
+ // (happens on osx and ios)
+ // UPDATE: don't just update to be on an even width;
+ // ffmpegs swscale relies on a 16-byte stride on some systems
+ // so the textureWidth needs to be a multiple of 16. see ffmpeg
+ // swscale headers for more info.
+ m_textureWidth = ((m_textureWidth + 15) / 16) * 16;
+ }
+
+ // check for max texture size
+ m_textureWidth = std::min(m_textureWidth, CServiceBroker::GetRenderSystem()->GetMaxTextureSize());
+ m_textureHeight =
+ std::min(m_textureHeight, CServiceBroker::GetRenderSystem()->GetMaxTextureSize());
+ m_imageWidth = std::min(m_imageWidth, m_textureWidth);
+ m_imageHeight = std::min(m_imageHeight, m_textureHeight);
+
+ KODI::MEMORY::AlignedFree(m_pixels);
+ m_pixels = NULL;
+
+ size_t size = GetPitch() * GetRows();
+
+ if (size == 0)
+ return;
+
+ m_pixels = static_cast<unsigned char*>(KODI::MEMORY::AlignedMalloc(size, 32));
+
+ if (m_pixels == nullptr)
+ CLog::Log(LOGERROR, "{} - Could not allocate {} bytes. Out of memory.", __FUNCTION__, size);
+}
+
+uint32_t CTextureBase::PadPow2(uint32_t x)
+{
+ --x;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return ++x;
+}
+
+bool CTextureBase::SwapBlueRed(
+ uint8_t* pixels, uint32_t height, uint32_t pitch, uint32_t elements, uint32_t offset)
+{
+ if (!pixels)
+ return false;
+ uint8_t* dst = pixels;
+ for (uint32_t y = 0; y < height; y++)
+ {
+ dst = pixels + (y * pitch);
+ for (uint32_t x = 0; x < pitch; x += elements)
+ std::swap(dst[x + offset], dst[x + 2 + offset]);
+ }
+ return true;
+}
+
+void CTextureBase::ClampToEdge()
+{
+ if (m_pixels == nullptr)
+ return;
+
+ uint32_t imagePitch = GetPitch(m_imageWidth);
+ uint32_t imageRows = GetRows(m_imageHeight);
+ uint32_t texturePitch = GetPitch(m_textureWidth);
+ uint32_t textureRows = GetRows(m_textureHeight);
+
+ if (imagePitch < texturePitch)
+ {
+ uint32_t blockSize = GetBlockSize();
+ unsigned char* src = m_pixels + imagePitch - blockSize;
+ unsigned char* dst = m_pixels;
+ for (uint32_t y = 0; y < imageRows; y++)
+ {
+ for (uint32_t x = imagePitch; x < texturePitch; x += blockSize)
+ memcpy(dst + x, src, blockSize);
+ dst += texturePitch;
+ }
+ }
+
+ if (imageRows < textureRows)
+ {
+ unsigned char* dst = m_pixels + imageRows * texturePitch;
+ for (uint32_t y = imageRows; y < textureRows; y++)
+ {
+ memcpy(dst, dst - texturePitch, texturePitch);
+ dst += texturePitch;
+ }
+ }
+}
+
+uint32_t CTextureBase::GetPitch(uint32_t width) const
+{
+ uint32_t blockWidth = GetBlockWidth();
+ uint32_t pitch = ((width + blockWidth - 1) / blockWidth) * GetBlockSize();
+
+ // For the GPU, RGB8 needs to be aligned to 32 bit
+ if (m_textureFormat == KD_TEX_FMT_SDR_RGB8)
+ pitch = ((pitch + 3) / 4) * 4;
+
+ return pitch;
+}
+
+uint32_t CTextureBase::GetRows(uint32_t height) const
+{
+ uint32_t blockHeight = GetBlockHeight();
+ return (height + blockHeight - 1) / blockHeight;
+}
+
+uint32_t CTextureBase::GetBlockWidth() const
+{
+ switch (m_textureFormat)
+ {
+ case KD_TEX_FMT_SDR_R8:
+ case KD_TEX_FMT_SDR_RG8:
+ case KD_TEX_FMT_SDR_R5G6B5:
+ case KD_TEX_FMT_SDR_RGB5_A1:
+ case KD_TEX_FMT_SDR_RGBA4:
+ case KD_TEX_FMT_SDR_RGB8:
+ case KD_TEX_FMT_SDR_RGBA8:
+ case KD_TEX_FMT_SDR_BGRA8:
+ case KD_TEX_FMT_HDR_R16f:
+ case KD_TEX_FMT_HDR_RG16f:
+ case KD_TEX_FMT_HDR_R11F_G11F_B10F:
+ case KD_TEX_FMT_HDR_RGB9_E5:
+ case KD_TEX_FMT_HDR_RGB10_A2:
+ case KD_TEX_FMT_HDR_RGBA16f:
+ return 1;
+ case KD_TEX_FMT_YUV_YUYV8:
+ return 2;
+ case KD_TEX_FMT_S3TC_RGB8:
+ case KD_TEX_FMT_S3TC_RGB8_A1:
+ case KD_TEX_FMT_S3TC_RGB8_A4:
+ case KD_TEX_FMT_S3TC_RGBA8:
+ case KD_TEX_FMT_RGTC_R11:
+ case KD_TEX_FMT_RGTC_RG11:
+ case KD_TEX_FMT_BPTC_RGB16F:
+ case KD_TEX_FMT_BPTC_RGBA8:
+ case KD_TEX_FMT_ETC1:
+ case KD_TEX_FMT_ETC2_RGB8:
+ case KD_TEX_FMT_ETC2_RGB8_A1:
+ case KD_TEX_FMT_ETC2_RGBA8:
+ case KD_TEX_FMT_ETC2_R11:
+ case KD_TEX_FMT_ETC2_RG11:
+ case KD_TEX_FMT_ASTC_LDR_4x4:
+ case KD_TEX_FMT_ASTC_HDR_4x4:
+ return 4;
+ case KD_TEX_FMT_ASTC_LDR_5x4:
+ case KD_TEX_FMT_ASTC_LDR_5x5:
+ case KD_TEX_FMT_ASTC_HDR_5x4:
+ case KD_TEX_FMT_ASTC_HDR_5x5:
+ return 5;
+ case KD_TEX_FMT_ASTC_LDR_6x5:
+ case KD_TEX_FMT_ASTC_LDR_6x6:
+ case KD_TEX_FMT_ASTC_HDR_6x5:
+ case KD_TEX_FMT_ASTC_HDR_6x6:
+ return 6;
+ case KD_TEX_FMT_ASTC_LDR_8x5:
+ case KD_TEX_FMT_ASTC_LDR_8x6:
+ case KD_TEX_FMT_ASTC_LDR_8x8:
+ case KD_TEX_FMT_ASTC_HDR_8x5:
+ case KD_TEX_FMT_ASTC_HDR_8x6:
+ case KD_TEX_FMT_ASTC_HDR_8x8:
+ return 8;
+ case KD_TEX_FMT_ASTC_LDR_10x5:
+ case KD_TEX_FMT_ASTC_LDR_10x6:
+ case KD_TEX_FMT_ASTC_LDR_10x8:
+ case KD_TEX_FMT_ASTC_LDR_10x10:
+ case KD_TEX_FMT_ASTC_HDR_10x5:
+ case KD_TEX_FMT_ASTC_HDR_10x6:
+ case KD_TEX_FMT_ASTC_HDR_10x8:
+ case KD_TEX_FMT_ASTC_HDR_10x10:
+ return 10;
+ case KD_TEX_FMT_ASTC_LDR_12x10:
+ case KD_TEX_FMT_ASTC_LDR_12x12:
+ case KD_TEX_FMT_ASTC_HDR_12x10:
+ case KD_TEX_FMT_ASTC_HDR_12x12:
+ return 12;
+ default:
+ return 1;
+ }
+}
+
+uint32_t CTextureBase::GetBlockHeight() const
+{
+ switch (m_textureFormat)
+ {
+ case KD_TEX_FMT_SDR_R8:
+ case KD_TEX_FMT_SDR_RG8:
+ case KD_TEX_FMT_SDR_R5G6B5:
+ case KD_TEX_FMT_SDR_RGB5_A1:
+ case KD_TEX_FMT_SDR_RGBA4:
+ case KD_TEX_FMT_SDR_RGB8:
+ case KD_TEX_FMT_SDR_RGBA8:
+ case KD_TEX_FMT_SDR_BGRA8:
+ case KD_TEX_FMT_HDR_R16f:
+ case KD_TEX_FMT_HDR_RG16f:
+ case KD_TEX_FMT_HDR_R11F_G11F_B10F:
+ case KD_TEX_FMT_HDR_RGB9_E5:
+ case KD_TEX_FMT_HDR_RGB10_A2:
+ case KD_TEX_FMT_HDR_RGBA16f:
+ case KD_TEX_FMT_YUV_YUYV8:
+ return 1;
+ case KD_TEX_FMT_S3TC_RGB8:
+ case KD_TEX_FMT_S3TC_RGB8_A1:
+ case KD_TEX_FMT_S3TC_RGB8_A4:
+ case KD_TEX_FMT_S3TC_RGBA8:
+ case KD_TEX_FMT_RGTC_R11:
+ case KD_TEX_FMT_RGTC_RG11:
+ case KD_TEX_FMT_BPTC_RGB16F:
+ case KD_TEX_FMT_BPTC_RGBA8:
+ case KD_TEX_FMT_ETC1:
+ case KD_TEX_FMT_ETC2_RGB8:
+ case KD_TEX_FMT_ETC2_RGB8_A1:
+ case KD_TEX_FMT_ETC2_RGBA8:
+ case KD_TEX_FMT_ETC2_R11:
+ case KD_TEX_FMT_ETC2_RG11:
+ case KD_TEX_FMT_ASTC_LDR_4x4:
+ case KD_TEX_FMT_ASTC_LDR_5x4:
+ case KD_TEX_FMT_ASTC_HDR_4x4:
+ case KD_TEX_FMT_ASTC_HDR_5x4:
+ return 4;
+ case KD_TEX_FMT_ASTC_LDR_5x5:
+ case KD_TEX_FMT_ASTC_LDR_6x5:
+ case KD_TEX_FMT_ASTC_LDR_8x5:
+ case KD_TEX_FMT_ASTC_LDR_10x5:
+ case KD_TEX_FMT_ASTC_HDR_5x5:
+ case KD_TEX_FMT_ASTC_HDR_6x5:
+ case KD_TEX_FMT_ASTC_HDR_8x5:
+ case KD_TEX_FMT_ASTC_HDR_10x5:
+ return 5;
+ case KD_TEX_FMT_ASTC_LDR_6x6:
+ case KD_TEX_FMT_ASTC_LDR_8x6:
+ case KD_TEX_FMT_ASTC_LDR_10x6:
+ case KD_TEX_FMT_ASTC_HDR_6x6:
+ case KD_TEX_FMT_ASTC_HDR_8x6:
+ case KD_TEX_FMT_ASTC_HDR_10x6:
+ return 6;
+ case KD_TEX_FMT_ASTC_LDR_8x8:
+ case KD_TEX_FMT_ASTC_LDR_10x8:
+ case KD_TEX_FMT_ASTC_HDR_8x8:
+ case KD_TEX_FMT_ASTC_HDR_10x8:
+ return 8;
+ case KD_TEX_FMT_ASTC_LDR_10x10:
+ case KD_TEX_FMT_ASTC_LDR_12x10:
+ case KD_TEX_FMT_ASTC_HDR_10x10:
+ case KD_TEX_FMT_ASTC_HDR_12x10:
+ return 10;
+ case KD_TEX_FMT_ASTC_LDR_12x12:
+ case KD_TEX_FMT_ASTC_HDR_12x12:
+ return 12;
+ default:
+ return 4;
+ }
+}
+
+uint32_t CTextureBase::GetBlockSize() const
+{
+ switch (m_textureFormat)
+ {
+ case KD_TEX_FMT_SDR_R8:
+ return 1;
+ case KD_TEX_FMT_SDR_RG8:
+ case KD_TEX_FMT_SDR_R5G6B5:
+ case KD_TEX_FMT_SDR_RGB5_A1:
+ case KD_TEX_FMT_SDR_RGBA4:
+ case KD_TEX_FMT_HDR_R16f:
+ return 2;
+ case KD_TEX_FMT_SDR_RGB8:
+ return 3;
+ case KD_TEX_FMT_SDR_RGBA8:
+ case KD_TEX_FMT_SDR_BGRA8:
+ case KD_TEX_FMT_HDR_RG16f:
+ case KD_TEX_FMT_HDR_R11F_G11F_B10F:
+ case KD_TEX_FMT_HDR_RGB9_E5:
+ case KD_TEX_FMT_HDR_RGB10_A2:
+ case KD_TEX_FMT_YUV_YUYV8:
+ return 4;
+ case KD_TEX_FMT_HDR_RGBA16f:
+ case KD_TEX_FMT_S3TC_RGB8:
+ case KD_TEX_FMT_S3TC_RGB8_A1:
+ case KD_TEX_FMT_RGTC_R11:
+ case KD_TEX_FMT_ETC1:
+ case KD_TEX_FMT_ETC2_RGB8:
+ case KD_TEX_FMT_ETC2_RGB8_A1:
+ case KD_TEX_FMT_ETC2_R11:
+ return 8;
+ case KD_TEX_FMT_S3TC_RGB8_A4:
+ case KD_TEX_FMT_S3TC_RGBA8:
+ case KD_TEX_FMT_RGTC_RG11:
+ case KD_TEX_FMT_BPTC_RGB16F:
+ case KD_TEX_FMT_BPTC_RGBA8:
+ case KD_TEX_FMT_ETC2_RG11:
+ case KD_TEX_FMT_ETC2_RGBA8:
+ case KD_TEX_FMT_ASTC_LDR_4x4:
+ case KD_TEX_FMT_ASTC_LDR_5x4:
+ case KD_TEX_FMT_ASTC_LDR_5x5:
+ case KD_TEX_FMT_ASTC_LDR_6x5:
+ case KD_TEX_FMT_ASTC_LDR_6x6:
+ case KD_TEX_FMT_ASTC_LDR_8x5:
+ case KD_TEX_FMT_ASTC_LDR_8x6:
+ case KD_TEX_FMT_ASTC_LDR_8x8:
+ case KD_TEX_FMT_ASTC_LDR_10x5:
+ case KD_TEX_FMT_ASTC_LDR_10x6:
+ case KD_TEX_FMT_ASTC_LDR_10x8:
+ case KD_TEX_FMT_ASTC_LDR_10x10:
+ case KD_TEX_FMT_ASTC_LDR_12x10:
+ case KD_TEX_FMT_ASTC_LDR_12x12:
+ case KD_TEX_FMT_ASTC_HDR_4x4:
+ case KD_TEX_FMT_ASTC_HDR_5x4:
+ case KD_TEX_FMT_ASTC_HDR_5x5:
+ case KD_TEX_FMT_ASTC_HDR_6x5:
+ case KD_TEX_FMT_ASTC_HDR_6x6:
+ case KD_TEX_FMT_ASTC_HDR_8x5:
+ case KD_TEX_FMT_ASTC_HDR_8x6:
+ case KD_TEX_FMT_ASTC_HDR_8x8:
+ case KD_TEX_FMT_ASTC_HDR_10x5:
+ case KD_TEX_FMT_ASTC_HDR_10x6:
+ case KD_TEX_FMT_ASTC_HDR_10x8:
+ case KD_TEX_FMT_ASTC_HDR_10x10:
+ case KD_TEX_FMT_ASTC_HDR_12x10:
+ case KD_TEX_FMT_ASTC_HDR_12x12:
+ return 16;
+ default:
+ return 4;
+ }
+}
+
+void CTextureBase::SetKDFormat(XB_FMT xbFMT)
+{
+ switch (xbFMT)
+ {
+ case XB_FMT_DXT1:
+ m_textureFormat = KD_TEX_FMT_S3TC_RGB8;
+ return;
+ case XB_FMT_DXT3:
+ m_textureFormat = KD_TEX_FMT_S3TC_RGB8_A4;
+ return;
+ case XB_FMT_DXT5:
+ m_textureFormat = KD_TEX_FMT_S3TC_RGBA8;
+ return;
+ case XB_FMT_A8R8G8B8:
+ m_textureFormat = KD_TEX_FMT_SDR_BGRA8;
+ return;
+ case XB_FMT_A8:
+ m_textureFormat = KD_TEX_FMT_SDR_R8;
+ m_textureSwizzle = KD_TEX_SWIZ_111R;
+ return;
+ case XB_FMT_RGBA8:
+ m_textureFormat = KD_TEX_FMT_SDR_RGBA8;
+ return;
+ case XB_FMT_RGB8:
+ m_textureFormat = KD_TEX_FMT_SDR_RGB8;
+ return;
+ case XB_FMT_UNKNOWN:
+ case XB_FMT_DXT5_YCoCg:
+ default:
+ m_textureFormat = KD_TEX_FMT_UNKNOWN;
+ return;
+ }
+}
diff --git a/xbmc/guilib/TextureBase.h b/xbmc/guilib/TextureBase.h
new file mode 100644
index 0000000000..bbabe2ae46
--- /dev/null
+++ b/xbmc/guilib/TextureBase.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "guilib/TextureFormats.h"
+
+#include <memory>
+#include <string>
+
+enum class TEXTURE_SCALING
+{
+ LINEAR,
+ NEAREST,
+};
+
+/*!
+\ingroup textures
+\brief Base texture class, which holds the state of the texture, as well as all conversion functions.
+*/
+class CTextureBase
+{
+
+public:
+ CTextureBase() = default;
+ ~CTextureBase() = default;
+
+ bool HasAlpha() const { return m_hasAlpha; }
+ void SetAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
+
+ /*! \brief sets mipmapping. do not use in new code. will be replaced with proper scaling. */
+ void SetMipmapping() { m_mipmapping = true; }
+ /*! \brief return true if we want to mipmap */
+ bool IsMipmapped() const { return m_mipmapping; }
+
+ /*! \brief sets the scaling method. scanout systems might support more than NN/linear. */
+ void SetScalingMethod(TEXTURE_SCALING scalingMethod) { m_scalingMethod = scalingMethod; }
+ /*! \brief returns the scaling method. */
+ TEXTURE_SCALING GetScalingMethod() const { return m_scalingMethod; }
+
+ int32_t GetOrientation() const { return m_orientation; }
+ void SetOrientation(int orientation) { m_orientation = orientation; }
+
+ /*! \brief retains a shadow copy of the texture on the CPU side. */
+ void SetCacheMemory(bool bCacheMemory) { m_bCacheMemory = bCacheMemory; }
+ /*! \brief returns true if a shadow copy is kept on the CPU side. */
+ bool GetCacheMemory() const { return m_bCacheMemory; }
+
+ /*! \brief returns a pointer to the staging texture. */
+ uint8_t* GetPixels() const { return m_pixels; }
+
+ /*! \brief return the size of one row in bytes. */
+ uint32_t GetPitch() const { return GetPitch(m_textureWidth); }
+ /*! \brief return the number of rows (number of blocks in the Y direction). */
+ uint32_t GetRows() const { return GetRows(m_textureHeight); }
+ /*! \brief return the total width of the texture, which might be scaled to fit its displayed size. */
+ uint32_t GetTextureWidth() const { return m_textureWidth; }
+ /*! \brief return the total height of the texture, which might be scaled to fit its displayed size. */
+ uint32_t GetTextureHeight() const { return m_textureHeight; }
+ /*! \brief return the total width of "active" area, which might be equal or lower than the texture width due to alignment. */
+ uint32_t GetWidth() const { return m_imageWidth; }
+ /*! \brief return the total height of "active" area, which might be equal or lower than the texture height due to alignment. */
+ uint32_t GetHeight() const { return m_imageHeight; }
+ /*! \brief return the original width of the image, before scaling/cropping */
+ uint32_t GetOriginalWidth() const { return m_originalWidth; }
+ /*! \brief return the original height of the image, before scaling/cropping */
+ uint32_t GetOriginalHeight() const { return m_originalHeight; }
+
+ // allocates staging texture space.
+ void Allocate(uint32_t width, uint32_t height, XB_FMT format);
+ void ClampToEdge();
+
+ /*! \brief rounds to power of two. deprecated. */
+ static uint32_t PadPow2(uint32_t x);
+ /*! \brief swaps the blue/red channel. deprecated in this form. */
+ static bool SwapBlueRed(
+ uint8_t* pixels, uint32_t height, uint32_t pitch, uint32_t elements = 4, uint32_t offset = 0);
+
+protected:
+ // helpers for computation of texture parameters for compressed textures
+ uint32_t GetPitch(uint32_t width) const;
+ uint32_t GetRows(uint32_t height) const;
+ uint32_t GetBlockWidth() const;
+ uint32_t GetBlockHeight() const;
+ /*! \brief return the size of a compression block (tile) in bytes. */
+ uint32_t GetBlockSize() const;
+
+ void SetKDFormat(XB_FMT xbFMT);
+
+ uint32_t m_imageWidth{0};
+ uint32_t m_imageHeight{0};
+ uint32_t m_textureWidth{0};
+ uint32_t m_textureHeight{0};
+ uint32_t m_originalWidth{0}; ///< original image width before scaling or cropping
+ uint32_t m_originalHeight{0}; ///< original image height before scaling or cropping
+
+ uint8_t* m_pixels{nullptr};
+ bool m_loadedToGPU{false};
+
+ KD_TEX_FMT m_textureFormat{KD_TEX_FMT_UNKNOWN}; // new Kodi texture format
+ KD_TEX_SWIZ m_textureSwizzle{KD_TEX_SWIZ_RGBA};
+ KD_TEX_COL m_textureColorspace{KD_TEX_COL_REC709};
+ KD_TEX_TRANSFER m_textureTransfer{KD_TEX_TRANSFER_SRGB};
+ KD_TEX_ALPHA m_textureAlpha{KD_TEX_ALPHA_STRAIGHT};
+
+ XB_FMT m_format{XB_FMT_UNKNOWN}; // legacy XB format, deprecated
+ int32_t m_orientation{0};
+ bool m_hasAlpha{true};
+ bool m_mipmapping{false};
+ TEXTURE_SCALING m_scalingMethod{TEXTURE_SCALING::LINEAR};
+ bool m_bCacheMemory{false};
+};
diff --git a/xbmc/guilib/TextureFormats.h b/xbmc/guilib/TextureFormats.h
index 2aab71a947..5b7d87c5fb 100644
--- a/xbmc/guilib/TextureFormats.h
+++ b/xbmc/guilib/TextureFormats.h
@@ -25,4 +25,159 @@ enum XB_FMT
XB_FMT_MASK = 0xFFFF,
XB_FMT_OPAQUE = 0x10000,
};
+
+enum KD_TEX_FMT
+{
+ KD_TEX_FMT_UNKNOWN = 0x0000,
+
+ // Legacy XB_FMT formats family
+ KD_TEX_FMT_LEGACY = 0x0000,
+
+ // SDR texture family
+ KD_TEX_FMT_SDR = 0x1000,
+ KD_TEX_FMT_SDR_R8 = 0x1000, // 8bpp, single channel
+ KD_TEX_FMT_SDR_RG8 = 0x1100, // 16bpp, dual channel
+ KD_TEX_FMT_SDR_R5G6B5 = 0x1200, // 16bpp, 5/6 bit per color channel
+ KD_TEX_FMT_SDR_RGB5_A1 = 0x1300, // 16bpp, 5 bit per color channel, pt-alpha
+ KD_TEX_FMT_SDR_RGBA4 = 0x1400, // 16bpp, 4 bit per channel
+ KD_TEX_FMT_SDR_RGB8 = 0x1500, // 24bpp, 8 bit per channel, no alpha (unsuitable for GPUs!)
+ KD_TEX_FMT_SDR_RGBA8 = 0x1600, // 32bpp, 8 bit per channel, RGBA order
+ KD_TEX_FMT_SDR_BGRA8 = 0x1700, // 32bpp, 8 bit per channel, BGRA order
+
+ // HDR texture family
+ KD_TEX_FMT_HDR = 0x2000,
+ KD_TEX_FMT_HDR_R16f = 0x2100, // 16bpp, single channel float
+ KD_TEX_FMT_HDR_RG16f = 0x2200, // 32bpp, dual channel float
+ KD_TEX_FMT_HDR_R11F_G11F_B10F = 0x2300, // 32bpp, 6e5/5e5 per color channel
+ KD_TEX_FMT_HDR_RGB9_E5 = 0x2400, // 32bpp, 9 bit color, shared 5 bit exponent
+ KD_TEX_FMT_HDR_RGB10_A2 = 0x2500, // 32bpp, 10 bit color, 2 bit alpha
+ KD_TEX_FMT_HDR_RGBA16f = 0x2600, // 64bpp, four channel float
+
+ // YUV texture family
+ KD_TEX_FMT_YUV = 0x3000,
+ KD_TEX_FMT_YUV_YUYV8 = 0x3000, // 16bpp, 4:2:2 packed
+
+ // S3TC texture family
+ KD_TEX_FMT_S3TC = 0x4000,
+ KD_TEX_FMT_S3TC_RGB8 = 0x4000, // 4bpp, RGB (BC1)
+ KD_TEX_FMT_S3TC_RGB8_A1 = 0x4100, // 4bpp, RGB, pt-alpha (BC1)
+ KD_TEX_FMT_S3TC_RGB8_A4 = 0x4200, // 8bpp, RGB, 4 bit alpha (BC2)
+ KD_TEX_FMT_S3TC_RGBA8 = 0x4300, // 8bpp, RGBA (BC3)
+
+ // RGTC (LATC) texture family
+ KD_TEX_FMT_RGTC = 0x5000,
+ KD_TEX_FMT_RGTC_R11 = 0x5000, // 4bpp, single channel (BC4)
+ KD_TEX_FMT_RGTC_RG11 = 0x5100, // 8bpp, dual channel (BC5)
+
+ // BPTC texture family
+ KD_TEX_FMT_BPTC = 0x6000,
+ KD_TEX_FMT_BPTC_RGB16F = 0x6000, // 8bpp, HDR (BC6H float)
+ KD_TEX_FMT_BPTC_RGBA8 = 0x6100, // 8bpp, LDR (BC7 unorm)
+
+ // ETC1 texture family
+ KD_TEX_FMT_ETC1 = 0x7000,
+ KD_TEX_FMT_ETC1_RGB8 = 0x7000, // 4bpp, RGB
+
+ // ETC2 texture family
+ KD_TEX_FMT_ETC2 = 0x8000,
+ KD_TEX_FMT_ETC2_R11 = 0x8100, // 4bpp, single channel (EAC)
+ KD_TEX_FMT_ETC2_RG11 = 0x8200, // 8bpp, dual channel (EAC)
+ KD_TEX_FMT_ETC2_RGB8 = 0x8300, // 4bpp, RGB
+ KD_TEX_FMT_ETC2_RGB8_A1 = 0x8400, // 4bpp, RGB, pt-alpha
+ KD_TEX_FMT_ETC2_RGBA8 = 0x8500, // 8bpp, RGB, alpha EAC
+
+ // ASTC LDR texture family
+ // Bitrate varies from 8bpp (4x4 tile) to 0.89bpp (12x12 tile).
+ KD_TEX_FMT_ASTC_LDR = 0x9000,
+ KD_TEX_FMT_ASTC_LDR_4x4 = 0x9000,
+ KD_TEX_FMT_ASTC_LDR_5x4 = 0x9100,
+ KD_TEX_FMT_ASTC_LDR_5x5 = 0x9200,
+ KD_TEX_FMT_ASTC_LDR_6x5 = 0x9300,
+ KD_TEX_FMT_ASTC_LDR_6x6 = 0x9400,
+ KD_TEX_FMT_ASTC_LDR_8x5 = 0x9500,
+ KD_TEX_FMT_ASTC_LDR_8x6 = 0x9600,
+ KD_TEX_FMT_ASTC_LDR_8x8 = 0x9700,
+ KD_TEX_FMT_ASTC_LDR_10x5 = 0x9800,
+ KD_TEX_FMT_ASTC_LDR_10x6 = 0x9900,
+ KD_TEX_FMT_ASTC_LDR_10x8 = 0x9A00,
+ KD_TEX_FMT_ASTC_LDR_10x10 = 0x9B00,
+ KD_TEX_FMT_ASTC_LDR_12x10 = 0x9C00,
+ KD_TEX_FMT_ASTC_LDR_12x12 = 0x9D00,
+
+ // ASTC HDR texture family
+ // Bitrate varies from 8bpp (4x4 tile) to 0.89bpp (12x12 tile).
+ KD_TEX_FMT_ASTC_HDR = 0xA000,
+ KD_TEX_FMT_ASTC_HDR_4x4 = 0xA000,
+ KD_TEX_FMT_ASTC_HDR_5x4 = 0xA100,
+ KD_TEX_FMT_ASTC_HDR_5x5 = 0xA200,
+ KD_TEX_FMT_ASTC_HDR_6x5 = 0xA300,
+ KD_TEX_FMT_ASTC_HDR_6x6 = 0xA400,
+ KD_TEX_FMT_ASTC_HDR_8x5 = 0xA500,
+ KD_TEX_FMT_ASTC_HDR_8x6 = 0xA600,
+ KD_TEX_FMT_ASTC_HDR_8x8 = 0xA700,
+ KD_TEX_FMT_ASTC_HDR_10x5 = 0xA800,
+ KD_TEX_FMT_ASTC_HDR_10x6 = 0xA900,
+ KD_TEX_FMT_ASTC_HDR_10x8 = 0xAA00,
+ KD_TEX_FMT_ASTC_HDR_10x10 = 0xAB00,
+ KD_TEX_FMT_ASTC_HDR_12x10 = 0xAC00,
+ KD_TEX_FMT_ASTC_HDR_12x12 = 0xAD00,
+
+ KD_TEX_FMT_TYPE_MASK = 0xF000,
+
+ KD_TEX_FMT_MASK = 0xFFFF,
+};
+
+// Alpha handling
+enum KD_TEX_ALPHA
+{
+ KD_TEX_ALPHA_STRAIGHT = 0x00000, // Straight (unmultiplied) alpha
+ KD_TEX_ALPHA_OPAQUE = 0x10000, // No alpha
+ KD_TEX_ALPHA_PREMULTIPLIED = 0x20000, // Premultiplied alpha
+
+ KD_TEX_ALPHA_MASK = 0xF0000,
+};
+
+// Texture component swizzle or effect
+enum KD_TEX_SWIZ
+{
+ KD_TEX_SWIZ_RGBA = 0x000000, // No swizzling
+ KD_TEX_SWIZ_RGB1 = 0x100000, // Normal swizzle, ignoring alpha
+ KD_TEX_SWIZ_RRR1 = 0x200000, // Luminance
+ KD_TEX_SWIZ_111R = 0x300000, // Alpha
+ KD_TEX_SWIZ_RRRG = 0x400000, // Luminance-Alpha
+ KD_TEX_SWIZ_RRRR = 0x500000, // Intensity
+ KD_TEX_SWIZ_GGG1 = 0x600000, // Luminance (ETC1/BC1)
+ KD_TEX_SWIZ_111G = 0x700000, // Alpha (ETC1/BC1)
+ KD_TEX_SWIZ_GGGA = 0x800000, // Luminance-Alpha (BC2/BC3)
+ KD_TEX_SWIZ_GGGG = 0x900000, // Intensity (ETC1/BC1)
+
+ KD_TEX_SWIZ_SDF = 0xa00000, // Red channel contains a SDF
+ KD_TEX_SWIZ_RGB_SDF = 0xb00000, // RGB8 texture with a SDF packed in the alpha channel
+ KD_TEX_SWIZ_MSDF = 0xc00000, // Encoded MSDF in the color channels, Alpha is ignored
+
+ KD_TEX_SWIZ_MASK = 0xF00000,
+};
+
+// Color space
+enum KD_TEX_COL
+{
+ KD_TEX_COL_REC709 = 0x0000000, // REC709/sRGB color space
+ KD_TEX_COL_REC2020 = 0x1000000, // REC2020 color space
+
+ KD_TEX_COL_MASK = 0xF000000,
+};
+
+// Transfer function
+enum KD_TEX_TRANSFER
+{
+ KD_TEX_TRANSFER_SRGB = 0x00000000,
+ KD_TEX_TRANSFER_REC709 = 0x10000000,
+ KD_TEX_TRANSFER_HLG = 0x20000000,
+ KD_TEX_TRANSFER_LINEAR = 0x30000000,
+ KD_TEX_TRANSFER_SQUARED = 0x40000000,
+ KD_TEX_TRANSFER_PQ = 0x50000000,
+
+ KD_TEX_TRANSFER_MASK = 0xF0000000,
+};
+
// clang-format on
diff --git a/xbmc/guilib/guiinfo/GUIInfoLabels.h b/xbmc/guilib/guiinfo/GUIInfoLabels.h
index 68faf15e98..ae6f255b31 100644
--- a/xbmc/guilib/guiinfo/GUIInfoLabels.h
+++ b/xbmc/guilib/guiinfo/GUIInfoLabels.h
@@ -149,6 +149,7 @@
#define SYSTEM_INTERNET_STATE 159
#define SYSTEM_HAS_INPUT_HIDDEN 160
#define SYSTEM_HAS_PVR_ADDON 161
+
#define SYSTEM_ALARM_LESS_OR_EQUAL 180
#define SYSTEM_PROFILECOUNT 181
#define SYSTEM_ISFULLSCREEN 182
@@ -483,7 +484,9 @@
#define SYSTEM_MEDIA_AUDIO_CD 754
#define SYSTEM_PLATFORM_DARWIN_TVOS 755
-#define SYSTEM_SUPPORTED_HDR_TYPES 756
+#define SYSTEM_SUPPORTED_HDR_TYPES 756
+#define SYSTEM_PLATFORM_WEBOS 757
+#define SYSTEM_PVR_COUNT 758
#define SLIDESHOW_ISPAUSED 800
#define SLIDESHOW_ISRANDOM 801
@@ -976,6 +979,7 @@ static constexpr unsigned int SYSTEM_LOCALE = 1012;
#define LISTITEM_ISVIDEOEXTRA (LISTITEM_START + 214)
#define LISTITEM_VIDEOVERSION_NAME (LISTITEM_START + 215)
#define LISTITEM_HASVIDEOEXTRAS (LISTITEM_START + 216)
+#define LISTITEM_BACKEND_INSTANCE_NAME (LISTITEM_START + 217)
#define LISTITEM_END (LISTITEM_START + 2500)
diff --git a/xbmc/guilib/guiinfo/LibraryGUIInfo.cpp b/xbmc/guilib/guiinfo/LibraryGUIInfo.cpp
index f7aceadb7f..0ffcafee4b 100644
--- a/xbmc/guilib/guiinfo/LibraryGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/LibraryGUIInfo.cpp
@@ -9,6 +9,7 @@
#include "guilib/guiinfo/LibraryGUIInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/guilib/guiinfo/MusicGUIInfo.cpp b/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
index d19a2ecf83..cb246febda 100644
--- a/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/MusicGUIInfo.cpp
@@ -21,15 +21,18 @@
#include "guilib/guiinfo/GUIInfo.h"
#include "guilib/guiinfo/GUIInfoHelper.h"
#include "guilib/guiinfo/GUIInfoLabels.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicInfoLoader.h"
#include "music/MusicThumbLoader.h"
#include "music/tags/MusicInfoTag.h"
+#include "network/NetworkFileItemClassify.h"
#include "playlists/PlayList.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingsComponent.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+using namespace KODI;
using namespace KODI::GUILIB;
using namespace KODI::GUILIB::GUIINFO;
using namespace MUSIC_INFO;
@@ -38,7 +41,8 @@ bool CMusicGUIInfo::InitCurrentItem(CFileItem *item)
{
const auto& components = CServiceBroker::GetAppComponents();
const auto appPlayer = components.GetComponent<CApplicationPlayer>();
- if (item && (item->IsAudio() || (item->IsInternetStream() && appPlayer->IsPlayingAudio())))
+ if (item &&
+ (MUSIC::IsAudio(*item) || (NETWORK::IsInternetStream(*item) && appPlayer->IsPlayingAudio())))
{
CLog::Log(LOGDEBUG, "CMusicGUIInfo::InitCurrentItem({})", item->GetPath());
@@ -48,7 +52,7 @@ bool CMusicGUIInfo::InitCurrentItem(CFileItem *item)
tag->SetLoaded(true);
// find a thumb for this file.
- if (item->IsInternetStream() && !item->IsMusicDb())
+ if (NETWORK::IsInternetStream(*item) && !MUSIC::IsMusicDb(*item))
{
if (!g_application.m_strPlayListFile.empty())
{
@@ -356,7 +360,7 @@ bool CMusicGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
return true;
case LISTITEM_FILENAME:
case LISTITEM_FILE_EXTENSION:
- if (item->IsMusicDb())
+ if (MUSIC::IsMusicDb(*item))
value = URIUtils::GetFileName(tag->GetURL());
else if (item->HasVideoInfoTag()) // special handling for music videos, which have both a videotag and a musictag
break;
@@ -371,7 +375,7 @@ bool CMusicGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
return true;
case LISTITEM_FOLDERNAME:
case LISTITEM_PATH:
- if (item->IsMusicDb())
+ if (MUSIC::IsMusicDb(*item))
value = URIUtils::GetDirectory(tag->GetURL());
else if (item->HasVideoInfoTag()) // special handling for music videos, which have both a videotag and a musictag
break;
@@ -387,7 +391,7 @@ bool CMusicGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
}
return true;
case LISTITEM_FILENAME_AND_PATH:
- if (item->IsMusicDb())
+ if (MUSIC::IsMusicDb(*item))
value = tag->GetURL();
else if (item->HasVideoInfoTag()) // special handling for music videos, which have both a videotag and a musictag
break;
diff --git a/xbmc/guilib/guiinfo/PicturesGUIInfo.cpp b/xbmc/guilib/guiinfo/PicturesGUIInfo.cpp
index e2af0e1792..e5920850fe 100644
--- a/xbmc/guilib/guiinfo/PicturesGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/PicturesGUIInfo.cpp
@@ -20,11 +20,13 @@
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include <map>
#include <memory>
using namespace KODI::GUILIB::GUIINFO;
+using namespace KODI;
static const std::map<int, int> listitem2slideshow_map =
{
@@ -251,7 +253,7 @@ bool CPicturesGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int conte
case SLIDESHOW_ISVIDEO:
{
CSlideShowDelegator& slideShow = CServiceBroker::GetSlideShowDelegator();
- value = slideShow.GetCurrentSlide() && slideShow.GetCurrentSlide()->IsVideo();
+ value = slideShow.GetCurrentSlide() && VIDEO::IsVideo(*slideShow.GetCurrentSlide());
return true;
}
}
diff --git a/xbmc/guilib/guiinfo/SystemGUIInfo.cpp b/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
index 70794125c4..683937302a 100644
--- a/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/SystemGUIInfo.cpp
@@ -9,6 +9,7 @@
#include "guilib/guiinfo/SystemGUIInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
@@ -25,6 +26,8 @@
#include "guilib/guiinfo/GUIInfoLabels.h"
#include "powermanagement/PowerManager.h"
#include "profiles/ProfileManager.h"
+#include "pvr/PVRManager.h"
+#include "pvr/addons/PVRClients.h"
#include "settings/AdvancedSettings.h"
#include "settings/MediaSettings.h"
#include "settings/SettingUtils.h"
@@ -338,6 +341,12 @@ bool CSystemGUIInfo::GetLabel(std::string& value, const CFileItem *item, int con
value = g_langInfo.GetRegionLocale();
return true;
}
+
+ case SYSTEM_PVR_COUNT:
+ {
+ value = std::to_string(CServiceBroker::GetPVRManager().Clients()->EnabledClientAmount());
+ return true;
+ }
}
return false;
}
@@ -373,6 +382,11 @@ bool CSystemGUIInfo::GetInt(int& value, const CGUIListItem *gitem, int contextWi
case SYSTEM_BATTERY_LEVEL:
value = CServiceBroker::GetPowerManager().BatteryLevel();
return true;
+ case SYSTEM_PVR_COUNT:
+ {
+ value = CServiceBroker::GetPVRManager().Clients()->EnabledClientAmount();
+ return true;
+ }
}
return false;
@@ -451,6 +465,13 @@ bool CSystemGUIInfo::GetBool(bool& value, const CGUIListItem *gitem, int context
value = false;
#endif
return true;
+ case SYSTEM_PLATFORM_WEBOS:
+#if defined(TARGET_WEBOS)
+ value = true;
+#else
+ value = false;
+#endif
+ return true;
case SYSTEM_MEDIA_DVD:
value = CServiceBroker::GetMediaManager().IsDiscInDrive();
return true;
diff --git a/xbmc/guilib/guiinfo/VideoGUIInfo.cpp b/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
index 3c2e32a279..6bec6186b7 100644
--- a/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
+++ b/xbmc/guilib/guiinfo/VideoGUIInfo.cpp
@@ -26,6 +26,7 @@
#include "guilib/guiinfo/GUIInfo.h"
#include "guilib/guiinfo/GUIInfoHelper.h"
#include "guilib/guiinfo/GUIInfoLabels.h"
+#include "network/NetworkFileItemClassify.h"
#include "playlists/PlayList.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingUtils.h"
@@ -35,6 +36,7 @@
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoManagerTypes.h"
#include "video/VideoThumbLoader.h"
@@ -43,6 +45,7 @@
using namespace KODI::GUILIB;
using namespace KODI::GUILIB::GUIINFO;
+using namespace KODI;
CVideoGUIInfo::CVideoGUIInfo()
: m_appPlayer(CServiceBroker::GetAppComponents().GetComponent<CApplicationPlayer>())
@@ -61,10 +64,10 @@ int CVideoGUIInfo::GetPercentPlayed(const CVideoInfoTag* tag) const
bool CVideoGUIInfo::InitCurrentItem(CFileItem *item)
{
- if (item && item->IsVideo())
+ if (item && VIDEO::IsVideo(*item))
{
// special case where .strm is used to start an audio stream
- if (item->IsInternetStream() && m_appPlayer->IsPlayingAudio())
+ if (NETWORK::IsInternetStream(*item) && m_appPlayer->IsPlayingAudio())
return false;
CLog::Log(LOGDEBUG, "CVideoGUIInfo::InitCurrentItem({})", CURL::GetRedacted(item->GetPath()));
@@ -77,7 +80,7 @@ bool CVideoGUIInfo::InitCurrentItem(CFileItem *item)
}
// find a thumb for this stream
- if (item->IsInternetStream())
+ if (NETWORK::IsInternetStream(*item))
{
if (!g_application.m_strPlayListFile.empty())
{
@@ -479,7 +482,7 @@ bool CVideoGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
return true;
case LISTITEM_FILENAME:
case LISTITEM_FILE_EXTENSION:
- if (item->IsVideoDb())
+ if (VIDEO::IsVideoDb(*item))
value = URIUtils::GetFileName(tag->m_strFileNameAndPath);
else if (item->HasMusicInfoTag()) // special handling for music videos, which have both a videotag and a musictag
break;
@@ -494,7 +497,7 @@ bool CVideoGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
return true;
case LISTITEM_FOLDERNAME:
case LISTITEM_PATH:
- if (item->IsVideoDb())
+ if (VIDEO::IsVideoDb(*item))
{
if (item->m_bIsFolder)
value = tag->m_strPath;
@@ -515,7 +518,7 @@ bool CVideoGUIInfo::GetLabel(std::string& value, const CFileItem *item, int cont
}
return true;
case LISTITEM_FILENAME_AND_PATH:
- if (item->IsVideoDb())
+ if (VIDEO::IsVideoDb(*item))
value = tag->m_strFileNameAndPath;
else if (item->HasMusicInfoTag()) // special handling for music videos, which have both a videotag and a musictag
break;
diff --git a/xbmc/guilib/listproviders/DirectoryProvider.cpp b/xbmc/guilib/listproviders/DirectoryProvider.cpp
index 71233786bc..14319ed961 100644
--- a/xbmc/guilib/listproviders/DirectoryProvider.cpp
+++ b/xbmc/guilib/listproviders/DirectoryProvider.cpp
@@ -18,6 +18,7 @@
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
#include "interfaces/AnnouncementManager.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicThumbLoader.h"
#include "pictures/PictureThumbLoader.h"
#include "pvr/PVRManager.h"
@@ -34,6 +35,7 @@
#include "utils/XMLUtils.h"
#include "utils/guilib/GUIContentUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoThumbLoader.h"
#include "video/VideoUtils.h"
@@ -46,6 +48,7 @@
#include <utility>
using namespace XFILE;
+using namespace KODI;
using namespace KODI::MESSAGING;
using namespace PVR;
@@ -133,12 +136,12 @@ public:
std::shared_ptr<CThumbLoader> getThumbLoader(const CGUIStaticItemPtr& item)
{
- if (item->IsVideo())
+ if (VIDEO::IsVideo(*item))
{
initThumbLoader<CVideoThumbLoader>(InfoTagType::VIDEO);
return m_thumbloaders[InfoTagType::VIDEO];
}
- if (item->IsAudio())
+ if (MUSIC::IsAudio(*item))
{
initThumbLoader<CMusicThumbLoader>(InfoTagType::AUDIO);
return m_thumbloaders[InfoTagType::AUDIO];
@@ -596,7 +599,7 @@ bool CDirectoryProvider::OnPlay(const std::shared_ptr<CGUIListItem>& item)
// video play action setting is for files and folders...
if (targetItem.HasVideoInfoTag() ||
- (targetItem.m_bIsFolder && VIDEO_UTILS::IsItemPlayable(targetItem)))
+ (targetItem.m_bIsFolder && VIDEO::UTILS::IsItemPlayable(targetItem)))
{
CVideoPlayActionProcessor proc{std::make_shared<CFileItem>(targetItem)};
if (proc.ProcessDefaultAction())
diff --git a/xbmc/imagefiles/SpecialImageLoaderFactory.cpp b/xbmc/imagefiles/SpecialImageLoaderFactory.cpp
index 8673031797..b35e138742 100644
--- a/xbmc/imagefiles/SpecialImageLoaderFactory.cpp
+++ b/xbmc/imagefiles/SpecialImageLoaderFactory.cpp
@@ -17,6 +17,7 @@
#include "video/VideoGeneratedImageFileLoader.h"
using namespace IMAGE_FILES;
+using namespace KODI;
CSpecialImageLoaderFactory::CSpecialImageLoaderFactory()
{
diff --git a/xbmc/input/keyboard/KeyboardLayoutManager.cpp b/xbmc/input/keyboard/KeyboardLayoutManager.cpp
index 4727a633ed..98ba2c5020 100644
--- a/xbmc/input/keyboard/KeyboardLayoutManager.cpp
+++ b/xbmc/input/keyboard/KeyboardLayoutManager.cpp
@@ -9,6 +9,7 @@
#include "KeyboardLayoutManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/input/keymaps/ButtonTranslator.cpp b/xbmc/input/keymaps/ButtonTranslator.cpp
index a7d3e50e57..34aa0164bd 100644
--- a/xbmc/input/keymaps/ButtonTranslator.cpp
+++ b/xbmc/input/keymaps/ButtonTranslator.cpp
@@ -10,6 +10,7 @@
#include "AppTranslator.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "guilib/WindowIDs.h"
#include "input/WindowTranslator.h"
diff --git a/xbmc/interfaces/AnnouncementManager.cpp b/xbmc/interfaces/AnnouncementManager.cpp
index 2718adf0d5..46fd378615 100644
--- a/xbmc/interfaces/AnnouncementManager.cpp
+++ b/xbmc/interfaces/AnnouncementManager.cpp
@@ -18,6 +18,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include <memory>
#include <mutex>
@@ -26,6 +27,7 @@
#define LOOKUP_PROPERTY "database-lookup"
using namespace ANNOUNCEMENT;
+using namespace KODI::VIDEO;
const std::string CAnnouncementManager::ANNOUNCEMENT_SENDER = "xbmc";
@@ -296,7 +298,7 @@ void CAnnouncementManager::DoAnnounce(AnnouncementFlag flag,
object["item"]["artist"] = item->GetMusicInfoTag()->GetArtist();
}
}
- else if (item->IsVideo())
+ else if (IsVideo(*item))
{
// video item but has no video info tag.
type = "movie";
diff --git a/xbmc/interfaces/builtins/PlayerBuiltins.cpp b/xbmc/interfaces/builtins/PlayerBuiltins.cpp
index d8ff27f1ca..1043f0944f 100644
--- a/xbmc/interfaces/builtins/PlayerBuiltins.cpp
+++ b/xbmc/interfaces/builtins/PlayerBuiltins.cpp
@@ -9,6 +9,7 @@
#include "PlayerBuiltins.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
@@ -23,6 +24,7 @@
#include "guilib/GUIWindowManager.h"
#include "input/actions/Action.h"
#include "input/actions/ActionIDs.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicUtils.h"
#include "playlists/PlayList.h"
#include "pvr/PVRManager.h"
@@ -38,6 +40,7 @@
#include "utils/URIUtils.h"
#include "utils/log.h"
#include "video/PlayerController.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoUtils.h"
#include "video/guilib/VideoGUIUtils.h"
#include "video/guilib/VideoSelectActionProcessor.h"
@@ -48,6 +51,8 @@
#include "Autorun.h"
#endif
+using namespace KODI;
+
/*! \brief Clear current playlist
* \param params (ignored)
*/
@@ -425,8 +430,8 @@ namespace
{
void GetItemsForPlayList(const std::shared_ptr<CFileItem>& item, CFileItemList& queuedItems)
{
- if (VIDEO_UTILS::IsItemPlayable(*item))
- VIDEO_UTILS::GetItemsForPlayList(item, queuedItems);
+ if (VIDEO::UTILS::IsItemPlayable(*item))
+ VIDEO::UTILS::GetItemsForPlayList(item, queuedItems);
else if (MUSIC_UTILS::IsItemPlayable(*item))
MUSIC_UTILS::GetItemsForPlayList(item, queuedItems);
}
@@ -434,9 +439,9 @@ void GetItemsForPlayList(const std::shared_ptr<CFileItem>& item, CFileItemList&
PLAYLIST::Id GetPlayListId(const CFileItem& item)
{
PLAYLIST::Id playlistId{PLAYLIST::TYPE_NONE};
- if (item.IsVideo())
+ if (VIDEO::IsVideo(item))
playlistId = PLAYLIST::TYPE_VIDEO;
- else if (item.IsAudio())
+ else if (MUSIC::IsAudio(item))
playlistId = PLAYLIST::TYPE_MUSIC;
return playlistId;
@@ -477,7 +482,7 @@ int PlayOrQueueMedia(const std::vector<std::string>& params, bool forcePlay)
else if (StringUtils::EqualsNoCase(params[i], "resume"))
{
// force the item to resume (if applicable)
- if (VIDEO_UTILS::GetItemResumeInformation(item).isResumable)
+ if (VIDEO::UTILS::GetItemResumeInformation(item).isResumable)
item.SetStartOffset(STARTOFFSET_RESUME);
else
item.SetStartOffset(0);
@@ -538,7 +543,7 @@ int PlayOrQueueMedia(const std::vector<std::string>& params, bool forcePlay)
bool containsVideo = false;
for (const auto& i : items)
{
- const bool isVideo = i->IsVideo();
+ const bool isVideo = VIDEO::IsVideo(*i);
containsMusic |= !isVideo;
containsVideo |= isVideo;
@@ -556,7 +561,7 @@ int PlayOrQueueMedia(const std::vector<std::string>& params, bool forcePlay)
{
for (int i = items.Size() - 1; i >= 0; i--) //remove music entries
{
- if (!items[i]->IsVideo())
+ if (!VIDEO::IsVideo(*items[i]))
items.Remove(i);
}
}
@@ -615,7 +620,7 @@ int PlayOrQueueMedia(const std::vector<std::string>& params, bool forcePlay)
if (forcePlay)
{
- if ((item.IsAudio() || item.IsVideo()) && !item.IsSmartPlayList() && !item.IsPVR())
+ if ((MUSIC::IsAudio(item) || VIDEO::IsVideo(item)) && !item.IsSmartPlayList() && !item.IsPVR())
{
if (!item.HasProperty("playlist_type_hint"))
item.SetProperty("playlist_type_hint", GetPlayListId(item));
diff --git a/xbmc/interfaces/json-rpc/AddonsOperations.cpp b/xbmc/interfaces/json-rpc/AddonsOperations.cpp
index db6c90a191..3daac8cc0b 100644
--- a/xbmc/interfaces/json-rpc/AddonsOperations.cpp
+++ b/xbmc/interfaces/json-rpc/AddonsOperations.cpp
@@ -11,7 +11,6 @@
#include "JSONUtils.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
-#include "addons/AddonDatabase.h"
#include "addons/AddonManager.h"
#include "addons/PluginSource.h"
#include "addons/addoninfo/AddonInfo.h"
@@ -122,9 +121,8 @@ JSONRPC_STATUS CAddonsOperations::GetAddons(const std::string &method, ITranspor
int start, end;
HandleLimits(parameterObject, result, addons.size(), start, end);
- CAddonDatabase addondb;
for (int index = start; index < end; index++)
- FillDetails(addons.at(index), parameterObject["properties"], result["addons"], addondb, true);
+ FillDetails(addons.at(index), parameterObject["properties"], result["addons"], true);
return OK;
}
@@ -138,8 +136,7 @@ JSONRPC_STATUS CAddonsOperations::GetAddonDetails(const std::string &method, ITr
addon->Type() >= AddonType::MAX_TYPES)
return InvalidParams;
- CAddonDatabase addondb;
- FillDetails(addon, parameterObject["properties"], result["addon"], addondb);
+ FillDetails(addon, parameterObject["properties"], result["addon"], false);
return OK;
}
@@ -272,8 +269,7 @@ static CVariant Serialize(const AddonPtr& addon)
void CAddonsOperations::FillDetails(const std::shared_ptr<ADDON::IAddon>& addon,
const CVariant& fields,
CVariant& result,
- CAddonDatabase& addondb,
- bool append /* = false */)
+ bool append)
{
if (addon.get() == NULL)
return;
diff --git a/xbmc/interfaces/json-rpc/AddonsOperations.h b/xbmc/interfaces/json-rpc/AddonsOperations.h
index 727f418999..cf78a2dba0 100644
--- a/xbmc/interfaces/json-rpc/AddonsOperations.h
+++ b/xbmc/interfaces/json-rpc/AddonsOperations.h
@@ -35,7 +35,6 @@ namespace JSONRPC
static void FillDetails(const std::shared_ptr<ADDON::IAddon>& addon,
const CVariant& fields,
CVariant& result,
- ADDON::CAddonDatabase& addondb,
- bool append = false);
+ bool append);
};
}
diff --git a/xbmc/interfaces/json-rpc/AudioLibrary.cpp b/xbmc/interfaces/json-rpc/AudioLibrary.cpp
index 3d6fa79d79..951cd7ae8d 100644
--- a/xbmc/interfaces/json-rpc/AudioLibrary.cpp
+++ b/xbmc/interfaces/json-rpc/AudioLibrary.cpp
@@ -9,6 +9,7 @@
#include "AudioLibrary.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
#include "Util.h"
diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
index 07426447e1..7a524fd337 100644
--- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp
+++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
@@ -9,6 +9,7 @@
#include "FileItemHandler.h"
#include "AudioLibrary.h"
+#include "FileItemList.h"
#include "FileOperations.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
diff --git a/xbmc/interfaces/json-rpc/FileOperations.cpp b/xbmc/interfaces/json-rpc/FileOperations.cpp
index 4658e99353..a495607ff9 100644
--- a/xbmc/interfaces/json-rpc/FileOperations.cpp
+++ b/xbmc/interfaces/json-rpc/FileOperations.cpp
@@ -10,6 +10,7 @@
#include "AudioLibrary.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "MediaSource.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp
index 0ec809481c..07c8d93222 100644
--- a/xbmc/interfaces/json-rpc/PVROperations.cpp
+++ b/xbmc/interfaces/json-rpc/PVROperations.cpp
@@ -9,6 +9,7 @@
#include "PVROperations.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
#include "pvr/PVRPlaybackState.h"
diff --git a/xbmc/interfaces/json-rpc/PlayerOperations.cpp b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
index 5029549541..d48a9d33c8 100644
--- a/xbmc/interfaces/json-rpc/PlayerOperations.cpp
+++ b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
@@ -10,6 +10,7 @@
#include "AudioLibrary.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
@@ -30,6 +31,7 @@
#include "interfaces/builtins/Builtins.h"
#include "messaging/ApplicationMessenger.h"
#include "music/MusicDatabase.h"
+#include "music/MusicFileItemClassify.h"
#include "pictures/SlideShowDelegator.h"
#include "pvr/PVRManager.h"
#include "pvr/PVRPlaybackState.h"
@@ -55,6 +57,7 @@
#include <map>
#include <tuple>
+using namespace KODI;
using namespace JSONRPC;
using namespace PVR;
@@ -268,7 +271,7 @@ JSONRPC_STATUS CPlayerOperations::GetItem(const std::string &method, ITransportL
}
}
- if (fileItem->IsMusicDb())
+ if (MUSIC::IsMusicDb(*fileItem))
{
CMusicDatabase musicdb;
CFileItemList items;
diff --git a/xbmc/interfaces/json-rpc/PlaylistOperations.cpp b/xbmc/interfaces/json-rpc/PlaylistOperations.cpp
index 61e04ac711..49955bc68f 100644
--- a/xbmc/interfaces/json-rpc/PlaylistOperations.cpp
+++ b/xbmc/interfaces/json-rpc/PlaylistOperations.cpp
@@ -9,6 +9,7 @@
#include "PlaylistOperations.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
diff --git a/xbmc/interfaces/json-rpc/ProfilesOperations.cpp b/xbmc/interfaces/json-rpc/ProfilesOperations.cpp
index adfb010430..17facb7b0e 100644
--- a/xbmc/interfaces/json-rpc/ProfilesOperations.cpp
+++ b/xbmc/interfaces/json-rpc/ProfilesOperations.cpp
@@ -9,6 +9,7 @@
#include "ProfilesOperations.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/interfaces/json-rpc/TextureOperations.cpp b/xbmc/interfaces/json-rpc/TextureOperations.cpp
index d6ffcc8761..d6915314bf 100644
--- a/xbmc/interfaces/json-rpc/TextureOperations.cpp
+++ b/xbmc/interfaces/json-rpc/TextureOperations.cpp
@@ -9,6 +9,7 @@
#include "TextureOperations.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "TextureDatabase.h"
diff --git a/xbmc/interfaces/json-rpc/VideoLibrary.cpp b/xbmc/interfaces/json-rpc/VideoLibrary.cpp
index 0f7499ec0e..cb69a5f002 100644
--- a/xbmc/interfaces/json-rpc/VideoLibrary.cpp
+++ b/xbmc/interfaces/json-rpc/VideoLibrary.cpp
@@ -9,6 +9,7 @@
#include "VideoLibrary.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PVROperations.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
diff --git a/xbmc/interfaces/legacy/Control.cpp b/xbmc/interfaces/legacy/Control.cpp
index 2ad9c2197e..d75778b5f5 100644
--- a/xbmc/interfaces/legacy/Control.cpp
+++ b/xbmc/interfaces/legacy/Control.cpp
@@ -9,6 +9,7 @@
#include "Control.h"
#include "AddonUtils.h"
+#include "FileItemList.h"
#include "LanguageHook.h"
#include "ServiceBroker.h"
#include "WindowException.h"
diff --git a/xbmc/interfaces/legacy/Dialog.cpp b/xbmc/interfaces/legacy/Dialog.cpp
index 55812f9099..9674875ea1 100644
--- a/xbmc/interfaces/legacy/Dialog.cpp
+++ b/xbmc/interfaces/legacy/Dialog.cpp
@@ -7,6 +7,7 @@
*/
#include "Dialog.h"
+#include "FileItemList.h"
#include "LanguageHook.h"
#include "ListItem.h"
#include "ModuleXbmcgui.h"
diff --git a/xbmc/interfaces/legacy/ModuleXbmcplugin.cpp b/xbmc/interfaces/legacy/ModuleXbmcplugin.cpp
index 0af97b71ac..bc399cc1c9 100644
--- a/xbmc/interfaces/legacy/ModuleXbmcplugin.cpp
+++ b/xbmc/interfaces/legacy/ModuleXbmcplugin.cpp
@@ -9,6 +9,7 @@
#include "ModuleXbmcplugin.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/PluginDirectory.h"
namespace XBMCAddon
diff --git a/xbmc/interfaces/legacy/ModuleXbmcvfs.cpp b/xbmc/interfaces/legacy/ModuleXbmcvfs.cpp
index c6858e3617..0d2391523f 100644
--- a/xbmc/interfaces/legacy/ModuleXbmcvfs.cpp
+++ b/xbmc/interfaces/legacy/ModuleXbmcvfs.cpp
@@ -9,6 +9,7 @@
#include "ModuleXbmcvfs.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LanguageHook.h"
#include "URL.h"
#include "Util.h"
diff --git a/xbmc/interfaces/legacy/PlayList.cpp b/xbmc/interfaces/legacy/PlayList.cpp
index d6d19d8866..649bc89892 100644
--- a/xbmc/interfaces/legacy/PlayList.cpp
+++ b/xbmc/interfaces/legacy/PlayList.cpp
@@ -8,6 +8,7 @@
#include "PlayList.h"
+#include "FileItemList.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
#include "playlists/PlayListFactory.h"
diff --git a/xbmc/interfaces/legacy/Player.cpp b/xbmc/interfaces/legacy/Player.cpp
index 4fc961cd88..b3aff2dfd5 100644
--- a/xbmc/interfaces/legacy/Player.cpp
+++ b/xbmc/interfaces/legacy/Player.cpp
@@ -9,6 +9,7 @@
#include "Player.h"
#include "AddonUtils.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "ListItem.h"
diff --git a/xbmc/interfaces/legacy/WindowXML.cpp b/xbmc/interfaces/legacy/WindowXML.cpp
index 65dc6c47f9..b127496783 100644
--- a/xbmc/interfaces/legacy/WindowXML.cpp
+++ b/xbmc/interfaces/legacy/WindowXML.cpp
@@ -8,6 +8,7 @@
#include "WindowXML.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "WindowException.h"
#include "WindowInterceptor.h"
diff --git a/xbmc/music/CMakeLists.txt b/xbmc/music/CMakeLists.txt
index 7909b0266a..f0575d2e8e 100644
--- a/xbmc/music/CMakeLists.txt
+++ b/xbmc/music/CMakeLists.txt
@@ -5,6 +5,7 @@ set(SOURCES Album.cpp
MusicDatabase.cpp
MusicDbUrl.cpp
MusicEmbeddedImageFileLoader.cpp
+ MusicFileItemClassify.cpp
MusicInfoLoader.cpp
MusicLibraryQueue.cpp
MusicThumbLoader.cpp
@@ -18,6 +19,7 @@ set(HEADERS Album.h
MusicDatabase.h
MusicDbUrl.h
MusicEmbeddedImageFileLoader.h
+ MusicFileItemClassify.h
MusicInfoLoader.h
MusicLibraryQueue.h
MusicThumbLoader.h
diff --git a/xbmc/music/ContextMenus.cpp b/xbmc/music/ContextMenus.cpp
index 9d146083bc..22df28acd2 100644
--- a/xbmc/music/ContextMenus.cpp
+++ b/xbmc/music/ContextMenus.cpp
@@ -19,10 +19,12 @@
#include "playlists/PlayListTypes.h"
#include "tags/MusicInfoTag.h"
#include "utils/Variant.h"
+#include "video/VideoFileItemClassify.h"
#include <utility>
using namespace CONTEXTMENU;
+using namespace KODI;
CMusicInfo::CMusicInfo(MediaType mediaType)
: CStaticContextMenuAction(19033), m_mediaType(std::move(mediaType))
@@ -32,8 +34,10 @@ CMusicInfo::CMusicInfo(MediaType mediaType)
bool CMusicInfo::IsVisible(const CFileItem& item) const
{
return (item.HasMusicInfoTag() && item.GetMusicInfoTag()->GetType() == m_mediaType) ||
- (m_mediaType == MediaTypeArtist && item.IsVideoDb() && item.HasProperty("artist_musicid")) ||
- (m_mediaType == MediaTypeAlbum && item.IsVideoDb() && item.HasProperty("album_musicid"));
+ (m_mediaType == MediaTypeArtist && VIDEO::IsVideoDb(item) &&
+ item.HasProperty("artist_musicid")) ||
+ (m_mediaType == MediaTypeAlbum && VIDEO::IsVideoDb(item) &&
+ item.HasProperty("album_musicid"));
}
bool CMusicInfo::Execute(const std::shared_ptr<CFileItem>& item) const
diff --git a/xbmc/music/GUIViewStateMusic.cpp b/xbmc/music/GUIViewStateMusic.cpp
index f14f5015e4..a34d9170a2 100644
--- a/xbmc/music/GUIViewStateMusic.cpp
+++ b/xbmc/music/GUIViewStateMusic.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateMusic.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "filesystem/MusicDatabaseDirectory.h"
@@ -23,8 +24,10 @@
#include "utils/FileExtensionProvider.h"
#include "utils/SortUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "view/ViewStateSettings.h"
+using namespace KODI;
using namespace XFILE;
using namespace MUSICDATABASEDIRECTORY;
@@ -503,7 +506,8 @@ CGUIViewStateWindowMusicNav::CGUIViewStateWindowMusicNav(const CFileItemList& it
}
else
{
- if (items.IsVideoDb() && items.Size() > (settings->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS)?1:0))
+ if (VIDEO::IsVideoDb(items) &&
+ items.Size() > (settings->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS) ? 1 : 0))
{
XFILE::VIDEODATABASEDIRECTORY::CQueryParams params;
XFILE::CVideoDatabaseDirectory::GetQueryParams(items[settings->GetBool(CSettings::SETTING_FILELISTS_SHOWPARENTDIRITEMS) ? 1 : 0]->GetPath(), params);
diff --git a/xbmc/music/MusicDatabase.cpp b/xbmc/music/MusicDatabase.cpp
index b5ba07ef8a..a98db00388 100644
--- a/xbmc/music/MusicDatabase.cpp
+++ b/xbmc/music/MusicDatabase.cpp
@@ -11,6 +11,7 @@
#include "Album.h"
#include "Artist.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
diff --git a/xbmc/music/MusicFileItemClassify.cpp b/xbmc/music/MusicFileItemClassify.cpp
new file mode 100644
index 0000000000..01ff4f6abe
--- /dev/null
+++ b/xbmc/music/MusicFileItemClassify.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005-2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "music/MusicFileItemClassify.h"
+
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "utils/FileExtensionProvider.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+
+namespace KODI::MUSIC
+{
+
+bool IsAudio(const CFileItem& item)
+{
+ /* check preset mime type */
+ if (StringUtils::StartsWithNoCase(item.GetMimeType(), "audio/"))
+ return true;
+
+ if (item.HasMusicInfoTag())
+ return true;
+
+ if (item.HasVideoInfoTag())
+ return false;
+
+ if (item.HasPictureInfoTag())
+ return false;
+
+ if (item.HasGameInfoTag())
+ return false;
+
+ if (IsCDDA(item))
+ return true;
+
+ if (StringUtils::StartsWithNoCase(item.GetMimeType(), "application/"))
+ { /* check for some standard types */
+ std::string extension = item.GetMimeType().substr(12);
+ if (StringUtils::EqualsNoCase(extension, "ogg") ||
+ StringUtils::EqualsNoCase(extension, "mp4") || StringUtils::EqualsNoCase(extension, "mxf"))
+ return true;
+ }
+
+ //! @todo If the file is a zip file, ask the game clients if any support this
+ // file before assuming it is audio
+
+ return URIUtils::HasExtension(item.GetPath(),
+ CServiceBroker::GetFileExtensionProvider().GetMusicExtensions());
+}
+
+bool IsAudioBook(const CFileItem& item)
+{
+ return item.IsType(".m4b") || item.IsType(".mka");
+}
+
+bool IsCDDA(const CFileItem& item)
+{
+ return URIUtils::IsCDDA(item.GetPath());
+}
+
+bool IsCUESheet(const CFileItem& item)
+{
+ return URIUtils::HasExtension(item.GetPath(), ".cue");
+}
+
+bool IsLyrics(const CFileItem& item)
+{
+ return URIUtils::HasExtension(item.GetPath(), ".cdg|.lrc");
+}
+
+bool IsMusicDb(const CFileItem& item)
+{
+ return URIUtils::IsMusicDb(item.GetPath());
+}
+
+} // namespace KODI::MUSIC
diff --git a/xbmc/music/MusicFileItemClassify.h b/xbmc/music/MusicFileItemClassify.h
new file mode 100644
index 0000000000..5202bdabdf
--- /dev/null
+++ b/xbmc/music/MusicFileItemClassify.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+class CFileItem;
+
+namespace KODI::MUSIC
+{
+
+//! \brief Check whether an item is an audio item.
+//! \details Note that this returns true for anything with a music info tag,
+//! so that may include eg. folders.
+bool IsAudio(const CFileItem& item);
+
+//! \brief Check whether an item is an audio book item.
+bool IsAudioBook(const CFileItem& item);
+
+//! \brief Check whether an item is an audio cd item.
+bool IsCDDA(const CFileItem& item);
+
+//! \brief Check whether an item is a cue sheet.
+bool IsCUESheet(const CFileItem& item);
+
+//! \brief Check whether an item is a lyrics file.
+bool IsLyrics(const CFileItem& item);
+
+//! \brief Check whether an item is a music database item.
+bool IsMusicDb(const CFileItem& item);
+
+} // namespace KODI::MUSIC
diff --git a/xbmc/music/MusicInfoLoader.cpp b/xbmc/music/MusicInfoLoader.cpp
index 7cfa0352ff..a6bff1a36e 100644
--- a/xbmc/music/MusicInfoLoader.cpp
+++ b/xbmc/music/MusicInfoLoader.cpp
@@ -11,14 +11,17 @@
#include "Album.h"
#include "Artist.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "MusicDatabase.h"
#include "MusicThumbLoader.h"
#include "ServiceBroker.h"
#include "filesystem/File.h"
#include "filesystem/MusicDatabaseDirectory/DirectoryNode.h"
#include "filesystem/MusicDatabaseDirectory/QueryParams.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "music/tags/MusicInfoTagLoaderFactory.h"
+#include "network/NetworkFileItemClassify.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/Archive.h"
@@ -26,8 +29,9 @@
#include "utils/URIUtils.h"
#include "utils/log.h"
-using namespace XFILE;
+using namespace KODI;
using namespace MUSIC_INFO;
+using namespace XFILE;
// HACK until we make this threadable - specify 1 thread only for now
CMusicInfoLoader::CMusicInfoLoader() : CBackgroundInfoLoader()
@@ -71,8 +75,8 @@ void CMusicInfoLoader::OnLoaderStart()
bool CMusicInfoLoader::LoadAdditionalTagInfo(CFileItem* pItem)
{
- if (!pItem || (pItem->m_bIsFolder && !pItem->IsAudio()) ||
- pItem->IsPlayList() || pItem->IsNFO() || pItem->IsInternetStream())
+ if (!pItem || (pItem->m_bIsFolder && !MUSIC::IsAudio(*pItem)) || pItem->IsPlayList() ||
+ pItem->IsNFO() || NETWORK::IsInternetStream(*pItem))
return false;
if (pItem->GetProperty("hasfullmusictag") == "true")
@@ -145,11 +149,11 @@ bool CMusicInfoLoader::LoadItem(CFileItem* pItem)
bool CMusicInfoLoader::LoadItemCached(CFileItem* pItem)
{
- if ((pItem->m_bIsFolder && !pItem->IsAudio()) ||
- pItem->IsPlayList() || pItem->IsSmartPlayList() ||
+ if ((pItem->m_bIsFolder && !MUSIC::IsAudio(*pItem)) || pItem->IsPlayList() ||
+ pItem->IsSmartPlayList() ||
StringUtils::StartsWithNoCase(pItem->GetPath(), "newplaylist://") ||
- StringUtils::StartsWithNoCase(pItem->GetPath(), "newsmartplaylist://") ||
- pItem->IsNFO() || (pItem->IsInternetStream() && !pItem->IsMusicDb()))
+ StringUtils::StartsWithNoCase(pItem->GetPath(), "newsmartplaylist://") || pItem->IsNFO() ||
+ (NETWORK::IsInternetStream(*pItem) && !MUSIC::IsMusicDb(*pItem)))
return false;
// Get thumb for item
@@ -163,14 +167,14 @@ bool CMusicInfoLoader::LoadItemLookup(CFileItem* pItem)
if (m_pProgressCallback && !pItem->m_bIsFolder)
m_pProgressCallback->SetProgressAdvance();
- if ((pItem->m_bIsFolder && !pItem->IsAudio()) || //
+ if ((pItem->m_bIsFolder && !MUSIC::IsAudio(*pItem)) || //
pItem->IsPlayList() || pItem->IsSmartPlayList() || //
StringUtils::StartsWithNoCase(pItem->GetPath(), "newplaylist://") || //
StringUtils::StartsWithNoCase(pItem->GetPath(), "newsmartplaylist://") || //
- pItem->IsNFO() || (pItem->IsInternetStream() && !pItem->IsMusicDb()))
+ pItem->IsNFO() || (NETWORK::IsInternetStream(*pItem) && !MUSIC::IsMusicDb(*pItem)))
return false;
- if ((!pItem->HasMusicInfoTag() || !pItem->GetMusicInfoTag()->Loaded()) && pItem->IsAudio())
+ if ((!pItem->HasMusicInfoTag() || !pItem->GetMusicInfoTag()->Loaded()) && MUSIC::IsAudio(*pItem))
{
// first check the cached item
CFileItemPtr mapItem = (*m_mapFileItems)[pItem->GetPath()];
@@ -210,7 +214,7 @@ bool CMusicInfoLoader::LoadItemLookup(CFileItem* pItem)
if (!it->second[0].strThumb.empty())
pItem->SetArt("thumb", it->second[0].strThumb);
}
- else if (pItem->IsMusicDb())
+ else if (MUSIC::IsMusicDb(*pItem))
{ // a music db item that doesn't have tag loaded - grab details from the database
XFILE::MUSICDATABASEDIRECTORY::CQueryParams param;
XFILE::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(pItem->GetPath(),param);
@@ -222,7 +226,9 @@ bool CMusicInfoLoader::LoadItemLookup(CFileItem* pItem)
pItem->SetArt("thumb", song.strThumb);
}
}
- else if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MUSICFILES_USETAGS) || pItem->IsCDDA())
+ else if (CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_MUSICFILES_USETAGS) ||
+ MUSIC::IsCDDA(*pItem))
{ // Nothing found, load tag from file,
// always try to load cddb info
// get correct tag parser
diff --git a/xbmc/music/MusicUtils.cpp b/xbmc/music/MusicUtils.cpp
index 0b0d13e556..c3e6b71625 100644
--- a/xbmc/music/MusicUtils.cpp
+++ b/xbmc/music/MusicUtils.cpp
@@ -9,6 +9,7 @@
#include "MusicUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
@@ -28,7 +29,9 @@
#include "media/MediaType.h"
#include "music/MusicDatabase.h"
#include "music/MusicDbUrl.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
+#include "network/NetworkFileItemClassify.h"
#include "playlists/PlayList.h"
#include "playlists/PlayListFactory.h"
#include "profiles/ProfileManager.h"
@@ -40,10 +43,13 @@
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "view/GUIViewState.h"
#include <memory>
+using namespace KODI;
+using namespace KODI::VIDEO;
using namespace MUSIC_INFO;
using namespace XFILE;
using namespace std::chrono_literals;
@@ -500,7 +506,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
if (item->IsParentFolder() || !item->CanQueue() || item->IsRAR() || item->IsZIP())
return;
- if (item->IsMusicDb() && item->m_bIsFolder && !item->IsParentFolder())
+ if (MUSIC::IsMusicDb(*item) && item->m_bIsFolder && !item->IsParentFolder())
{
// we have a music database folder, just grab the "all" item underneath it
XFILE::CMusicDatabaseDirectory dir;
@@ -596,7 +602,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
GetItemsForPlaylist((*playList)[i]);
}
}
- else if (item->IsInternetStream() && !item->IsMusicDb())
+ else if (NETWORK::IsInternetStream(*item) && !MUSIC::IsMusicDb(*item))
{
// just queue the internet stream, it will be expanded on play
m_queuedItems.Add(item);
@@ -606,7 +612,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
// python files can be played
m_queuedItems.Add(item);
}
- else if (!item->IsNFO() && (item->IsAudio() || item->IsVideo()))
+ else if (!item->IsNFO() && (MUSIC::IsAudio(*item) || IsVideo(*item)))
{
const auto itemCheck = m_queuedItems.Get(item->GetPath());
if (!itemCheck || itemCheck->GetStartOffset() != item->GetStartOffset())
@@ -873,7 +879,7 @@ bool IsItemPlayable(const CFileItem& item)
return false;
// Exclude all video library items
- if (item.IsVideoDb() || StringUtils::StartsWithNoCase(item.GetPath(), "library://video/"))
+ if (IsVideoDb(item) || StringUtils::StartsWithNoCase(item.GetPath(), "library://video/"))
return false;
// Exclude other components
@@ -913,7 +919,7 @@ bool IsItemPlayable(const CFileItem& item)
return false;
if (item.m_bIsFolder &&
- (item.IsMusicDb() || StringUtils::StartsWithNoCase(item.GetPath(), "library://music/")))
+ (MUSIC::IsMusicDb(item) || StringUtils::StartsWithNoCase(item.GetPath(), "library://music/")))
{
// Exclude top level nodes - eg can't play 'genres' just a specific genre etc
const XFILE::MUSICDATABASEDIRECTORY::NODE_TYPE node =
@@ -926,7 +932,7 @@ bool IsItemPlayable(const CFileItem& item)
if (item.HasMusicInfoTag() && item.CanQueue())
return true;
- else if (!item.m_bIsFolder && item.IsAudio())
+ else if (!item.m_bIsFolder && MUSIC::IsAudio(item))
return true;
else if (item.m_bIsFolder)
{
diff --git a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp
index d1559f77fd..acf730f777 100644
--- a/xbmc/music/dialogs/GUIDialogMusicInfo.cpp
+++ b/xbmc/music/dialogs/GUIDialogMusicInfo.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogMusicInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
@@ -26,6 +27,7 @@
#include "input/actions/ActionIDs.h"
#include "messaging/helpers/DialogOKHelper.h"
#include "music/MusicDatabase.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicLibraryQueue.h"
#include "music/MusicThumbLoader.h"
#include "music/MusicUtils.h"
@@ -47,6 +49,7 @@
using namespace XFILE;
using namespace MUSIC_INFO;
using namespace MUSICDATABASEDIRECTORY;
+using namespace KODI;
using namespace KODI::MESSAGING;
#define CONTROL_BTN_REFRESH 6
@@ -989,7 +992,7 @@ void CGUIDialogMusicInfo::ShowFor(CFileItem* pItem)
// We have a folder album/artist info dialog only shown for db items
// or for music video with artist/album in music library
- if (pItem->IsMusicDb())
+ if (MUSIC::IsMusicDb(*pItem))
{
if (!pItem->HasMusicInfoTag() || pItem->GetMusicInfoTag()->GetDatabaseId() < 1)
{
diff --git a/xbmc/music/dialogs/GUIDialogSongInfo.cpp b/xbmc/music/dialogs/GUIDialogSongInfo.cpp
index 045fdce052..c0101d0ff3 100644
--- a/xbmc/music/dialogs/GUIDialogSongInfo.cpp
+++ b/xbmc/music/dialogs/GUIDialogSongInfo.cpp
@@ -22,6 +22,7 @@
#include "input/actions/Action.h"
#include "input/actions/ActionIDs.h"
#include "music/MusicDatabase.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicUtils.h"
#include "music/tags/MusicInfoTag.h"
#include "music/windows/GUIWindowMusicBase.h"
@@ -31,6 +32,8 @@
#include "storage/MediaManager.h"
#include "utils/FileUtils.h"
+using namespace KODI;
+
#define CONTROL_BTN_REFRESH 6
#define CONTROL_USERRATING 7
#define CONTROL_BTN_PLAY 8
@@ -41,8 +44,6 @@
#define TIME_TO_BUSY_DIALOG 500
-
-
class CGetSongInfoJob : public CJob
{
public:
@@ -375,7 +376,7 @@ void CGUIDialogSongInfo::OnGetArt()
if (type == "thumb")
{ // Local thumb type art held in <filename>.tbn (for non-library items)
localThumb = m_song->GetUserMusicThumb(true);
- if (m_song->IsMusicDb())
+ if (MUSIC::IsMusicDb(*m_song))
{
CFileItem item(m_song->GetMusicInfoTag()->GetURL(), false);
localThumb = item.GetUserMusicThumb(true);
@@ -495,7 +496,7 @@ void CGUIDialogSongInfo::ShowFor(CFileItem* pItem)
{
if (pItem->m_bIsFolder)
return;
- if (!pItem->IsMusicDb())
+ if (!MUSIC::IsMusicDb(*pItem))
pItem->LoadMusicTag();
if (!pItem->HasMusicInfoTag())
return;
diff --git a/xbmc/music/dialogs/GUIDialogSongInfo.h b/xbmc/music/dialogs/GUIDialogSongInfo.h
index 274f1acc0f..7aba18a52a 100644
--- a/xbmc/music/dialogs/GUIDialogSongInfo.h
+++ b/xbmc/music/dialogs/GUIDialogSongInfo.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/GUIDialog.h"
#include "threads/Event.h"
diff --git a/xbmc/music/infoscanner/MusicInfoScanner.cpp b/xbmc/music/infoscanner/MusicInfoScanner.cpp
index f828b44914..1e57245c5c 100644
--- a/xbmc/music/infoscanner/MusicInfoScanner.cpp
+++ b/xbmc/music/infoscanner/MusicInfoScanner.cpp
@@ -9,6 +9,7 @@
#include "MusicInfoScanner.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "MusicAlbumInfo.h"
@@ -36,6 +37,7 @@
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
#include "interfaces/AnnouncementManager.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicLibraryQueue.h"
#include "music/MusicThumbLoader.h"
#include "music/MusicUtils.h"
@@ -55,6 +57,7 @@
#include <algorithm>
#include <utility>
+using namespace KODI;
using namespace MUSIC_INFO;
using namespace XFILE;
using namespace MUSICDATABASEDIRECTORY;
@@ -577,7 +580,7 @@ CInfoScanner::INFO_RET CMusicInfoScanner::ScanTags(const CFileItemList& items,
if (CUtil::ExcludeFileOrFolder(pItem->GetPath(), regexps))
continue;
- if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsPicture() || pItem->IsLyrics())
+ if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsPicture() || MUSIC::IsLyrics(*pItem))
continue;
m_currentItem++;
@@ -1271,7 +1274,7 @@ int CMusicInfoScanner::GetPathHash(const CFileItemList &items, std::string &hash
digest.Update((unsigned char *)&pItem->m_dwSize, sizeof(pItem->m_dwSize));
KODI::TIME::FileTime time = pItem->m_dateTime;
digest.Update((unsigned char*)&time, sizeof(KODI::TIME::FileTime));
- if (pItem->IsAudio() && !pItem->IsPlayList() && !pItem->IsNFO())
+ if (MUSIC::IsAudio(*pItem) && !pItem->IsPlayList() && !pItem->IsNFO())
count++;
}
hash = digest.Finalize();
@@ -2331,7 +2334,7 @@ int CMusicInfoScanner::CountFiles(const CFileItemList &items, bool recursive)
if (recursive && pItem->m_bIsFolder)
count+=CountFilesRecursively(pItem->GetPath());
- else if (pItem->IsAudio() && !pItem->IsPlayList() && !pItem->IsNFO())
+ else if (MUSIC::IsAudio(*pItem) && !pItem->IsPlayList() && !pItem->IsNFO())
count++;
}
return count;
diff --git a/xbmc/music/tags/MusicInfoTagLoaderFactory.cpp b/xbmc/music/tags/MusicInfoTagLoaderFactory.cpp
index 562068ee95..523b0bf233 100644
--- a/xbmc/music/tags/MusicInfoTagLoaderFactory.cpp
+++ b/xbmc/music/tags/MusicInfoTagLoaderFactory.cpp
@@ -18,9 +18,12 @@
#include "addons/AudioDecoder.h"
#include "addons/ExtsMimeSupportList.h"
#include "addons/addoninfo/AddonType.h"
+#include "music/MusicFileItemClassify.h"
+#include "network/NetworkFileItemClassify.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
+using namespace KODI;
using namespace KODI::ADDONS;
using namespace MUSIC_INFO;
@@ -31,10 +34,10 @@ CMusicInfoTagLoaderFactory::~CMusicInfoTagLoaderFactory() = default;
IMusicInfoTagLoader* CMusicInfoTagLoaderFactory::CreateLoader(const CFileItem& item)
{
// dont try to read the tags for streams & shoutcast
- if (item.IsInternetStream())
+ if (NETWORK::IsInternetStream(item))
return NULL;
- if (item.IsMusicDb())
+ if (MUSIC::IsMusicDb(item))
return new CMusicInfoTagLoaderDatabase();
std::string strExtension = URIUtils::GetExtension(item.GetPath());
diff --git a/xbmc/music/test/CMakeLists.txt b/xbmc/music/test/CMakeLists.txt
new file mode 100644
index 0000000000..8edd785ff6
--- /dev/null
+++ b/xbmc/music/test/CMakeLists.txt
@@ -0,0 +1,3 @@
+set(SOURCES TestMusicFileItemClassify.cpp)
+
+core_add_test_library(music_test)
diff --git a/xbmc/music/test/TestMusicFileItemClassify.cpp b/xbmc/music/test/TestMusicFileItemClassify.cpp
new file mode 100644
index 0000000000..134052afb5
--- /dev/null
+++ b/xbmc/music/test/TestMusicFileItemClassify.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "games/tags/GameInfoTag.h"
+#include "music/MusicFileItemClassify.h"
+#include "music/tags/MusicInfoTag.h"
+#include "pictures/PictureInfoTag.h"
+#include "utils/FileExtensionProvider.h"
+#include "video/VideoInfoTag.h"
+
+#include <array>
+
+#include <gtest/gtest.h>
+
+using namespace KODI;
+
+struct AudioClassifyTest
+{
+ AudioClassifyTest(const std::string& path,
+ bool res = true,
+ const std::string& mime = "",
+ int tag_type = 0)
+ : item(path, false), result(res)
+ {
+ if (!mime.empty())
+ item.SetMimeType(mime);
+ switch (tag_type)
+ {
+ case 1:
+ item.GetVideoInfoTag()->m_strFileNameAndPath = path;
+ break;
+ case 2:
+ item.GetGameInfoTag()->SetGameClient("some_client");
+ break;
+ case 3:
+ item.GetMusicInfoTag()->SetPlayCount(1);
+ break;
+ case 4:
+ item.GetPictureInfoTag()->SetInfo("foo", "bar");
+ break;
+ default:
+ break;
+ }
+ }
+
+ CFileItem item;
+ bool result;
+};
+
+class AudioTest : public testing::WithParamInterface<AudioClassifyTest>, public testing::Test
+{
+};
+
+TEST_P(AudioTest, IsAudio)
+{
+ EXPECT_EQ(MUSIC::IsAudio(GetParam().item), GetParam().result);
+}
+
+const auto audio_tests = std::array{
+ AudioClassifyTest{"/home/user/song.avi", true, "audio/mp3"},
+ AudioClassifyTest{"/home/user/song.avi", false, "", 1},
+ AudioClassifyTest{"/home/user/song.avi", false, "", 2},
+ AudioClassifyTest{"/home/user/song.avi", true, "", 3},
+ AudioClassifyTest{"/home/user/song.avi", false, "", 4},
+ AudioClassifyTest{"cdda://1"},
+ AudioClassifyTest{"/home/user/song.avi", true, "application/ogg"},
+ AudioClassifyTest{"/home/user/video.not", true, "application/mp4"},
+ AudioClassifyTest{"/home/user/video.not", true, "application/mxf"},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestMusicFileItemClassify, AudioTest, testing::ValuesIn(audio_tests));
+
+TEST(TestMusicFileItemClassify, MusicExtensions)
+{
+ const auto& exts = CServiceBroker::GetFileExtensionProvider().GetMusicExtensions();
+ for (const auto& ext : StringUtils::Split(exts, "|"))
+ {
+ if (!ext.empty())
+ {
+ EXPECT_TRUE(MUSIC::IsAudio(CFileItem(ext, false)));
+ }
+ }
+}
+
+struct SimpleDefinition
+{
+ std::string path;
+ bool folder;
+ bool result;
+};
+
+class AudioBookTest : public testing::WithParamInterface<SimpleDefinition>, public testing::Test
+{
+};
+
+TEST_P(AudioBookTest, IsAudioBook)
+{
+ EXPECT_EQ(MUSIC::IsAudioBook(CFileItem(GetParam().path, GetParam().folder)), GetParam().result);
+}
+
+const auto audiobook_tests = std::array{
+ SimpleDefinition{"/home/user/test.m4b", false, true},
+ SimpleDefinition{"/home/user/test.m4b", true, true},
+ SimpleDefinition{"/home/user/test.mka", false, true},
+ SimpleDefinition{"/home/user/test.mka", true, true},
+ SimpleDefinition{"/home/user/test.not", false, false},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestMusicFileItemClassify,
+ AudioBookTest,
+ testing::ValuesIn(audiobook_tests));
+
+class CuesheetTest : public testing::WithParamInterface<SimpleDefinition>, public testing::Test
+{
+};
+
+TEST_P(CuesheetTest, IsCUESheet)
+{
+ EXPECT_EQ(MUSIC::IsCUESheet(CFileItem(GetParam().path, GetParam().folder)), GetParam().result);
+}
+
+const auto cuesheet_tests = std::array{
+ SimpleDefinition{"/home/user/test.cue", false, true},
+ SimpleDefinition{"/home/user/test.cue/", true, false},
+ SimpleDefinition{"/home/user/test.foo", false, false},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestMusicFileItemClassify,
+ CuesheetTest,
+ testing::ValuesIn(cuesheet_tests));
+
+class LyricsTest : public testing::WithParamInterface<SimpleDefinition>, public testing::Test
+{
+};
+
+TEST_P(LyricsTest, IsLyrics)
+{
+ EXPECT_EQ(MUSIC::IsLyrics(CFileItem(GetParam().path, GetParam().folder)), GetParam().result);
+}
+
+const auto lyrics_tests = std::array{
+ SimpleDefinition{"/home/user/test.lrc", false, true},
+ SimpleDefinition{"/home/user/test.cdg", false, true},
+ SimpleDefinition{"/home/user/test.not", false, false},
+ SimpleDefinition{"/home/user/test.lrc/", true, false},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestMusicFileItemClassify, LyricsTest, testing::ValuesIn(lyrics_tests));
+
+class CDDATest : public testing::WithParamInterface<SimpleDefinition>, public testing::Test
+{
+};
+
+TEST_P(CDDATest, IsCDDA)
+{
+ EXPECT_EQ(MUSIC::IsCDDA(CFileItem(GetParam().path, GetParam().folder)), GetParam().result);
+}
+
+const auto cdda_tests = std::array{
+ SimpleDefinition{"cdda://1", false, true},
+ SimpleDefinition{"cdda://1/", true, true},
+ SimpleDefinition{"cdda://1/", true, true},
+ SimpleDefinition{"/home/foo/yo.cdda", false, false},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestMusicFileItemClassify, CDDATest, testing::ValuesIn(cdda_tests));
+
+class MusicDbTest : public testing::WithParamInterface<SimpleDefinition>, public testing::Test
+{
+};
+
+TEST_P(MusicDbTest, IsMusicDb)
+{
+ EXPECT_EQ(MUSIC::IsMusicDb(CFileItem(GetParam().path, GetParam().folder)), GetParam().result);
+}
+
+const auto musicdb_tests = std::array{
+ SimpleDefinition{"musicdb://1", false, true},
+ SimpleDefinition{"musicdb://1/", true, true},
+ SimpleDefinition{"/home/foo/musicdb/yo.mp3", false, false},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestMusicFileItemClassify, MusicDbTest, testing::ValuesIn(musicdb_tests));
diff --git a/xbmc/music/windows/GUIWindowMusicBase.cpp b/xbmc/music/windows/GUIWindowMusicBase.cpp
index 9dc4e2dddd..5ace8dcfe4 100644
--- a/xbmc/music/windows/GUIWindowMusicBase.cpp
+++ b/xbmc/music/windows/GUIWindowMusicBase.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
@@ -22,6 +23,9 @@
#include "application/Application.h"
#include "application/ApplicationComponents.h"
#include "application/ApplicationPlayer.h"
+#include "music/MusicFileItemClassify.h"
+#include "network/NetworkFileItemClassify.h"
+#include "video/VideoFileItemClassify.h"
#ifdef HAS_CDDA_RIPPER
#include "cdrip/CDDARipper.h"
#endif
@@ -71,8 +75,10 @@ using namespace XFILE;
using namespace MUSICDATABASEDIRECTORY;
using namespace MUSIC_GRABBER;
using namespace MUSIC_INFO;
+using namespace KODI;
using namespace KODI::MESSAGING;
using KODI::MESSAGING::HELPERS::DialogResponse;
+using namespace KODI::VIDEO;
using namespace std::chrono_literals;
@@ -297,7 +303,7 @@ void CGUIWindowMusicBase::OnItemInfo(int iItem)
CFileItemPtr item = m_vecItems->Get(iItem);
// Match visibility test of CMusicInfo::IsVisible
- if (item->IsVideoDb() && item->HasVideoInfoTag() &&
+ if (IsVideoDb(*item) && item->HasVideoInfoTag() &&
(item->HasProperty("artist_musicid") || item->HasProperty("album_musicid")))
{
// Music video artist or album (navigation by music > music video > artist))
@@ -305,7 +311,7 @@ void CGUIWindowMusicBase::OnItemInfo(int iItem)
return;
}
- if (item->IsVideo() && item->HasVideoInfoTag() &&
+ if (IsVideo(*item) && item->HasVideoInfoTag() &&
item->GetVideoInfoTag()->m_type == MediaTypeMusicVideo)
{ // Music video on a mixed current playlist or navigation by music > music video > artist > video
CGUIDialogVideoInfo::ShowFor(*item);
@@ -348,7 +354,8 @@ void CGUIWindowMusicBase::RetrieveMusicInfo()
for (int i = 0; i < m_vecItems->Size(); ++i)
{
CFileItemPtr pItem = (*m_vecItems)[i];
- if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsPicture() || pItem->IsLyrics() || pItem->IsVideo())
+ if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsPicture() ||
+ MUSIC::IsLyrics(*pItem) || IsVideo(*pItem))
continue;
CMusicInfoTag& tag = *pItem->GetMusicInfoTag();
@@ -405,9 +412,8 @@ void CGUIWindowMusicBase::UpdateButtons()
{
CONTROL_ENABLE_ON_CONDITION(CONTROL_BTNRIP, CServiceBroker::GetMediaManager().IsAudio());
- CONTROL_ENABLE_ON_CONDITION(CONTROL_BTNSCAN,
- !(m_vecItems->IsVirtualDirectoryRoot() ||
- m_vecItems->IsMusicDb()));
+ CONTROL_ENABLE_ON_CONDITION(
+ CONTROL_BTNSCAN, !(m_vecItems->IsVirtualDirectoryRoot() || MUSIC::IsMusicDb(*m_vecItems)));
if (CMusicLibraryQueue::GetInstance().IsScanningLibrary())
SET_CONTROL_LABEL(CONTROL_BTNSCAN, 14056); // Stop Scan
@@ -452,7 +458,7 @@ void CGUIWindowMusicBase::GetContextButtons(int itemNumber, CContextButtons &but
}
#ifdef HAS_OPTICAL_DRIVE
// enable Rip CD Audio or Track button if we have an audio disc
- if (CServiceBroker::GetMediaManager().IsDiscInDrive() && m_vecItems->IsCDDA())
+ if (CServiceBroker::GetMediaManager().IsDiscInDrive() && MUSIC::IsCDDA(*m_vecItems))
{
// those cds can also include Audio Tracks: CDExtra and MixedMode!
MEDIA_DETECT::CCdInfo* pCdInfo = CServiceBroker::GetMediaManager().GetCdInfo();
@@ -463,7 +469,7 @@ void CGUIWindowMusicBase::GetContextButtons(int itemNumber, CContextButtons &but
}
// enable CDDB lookup if the current dir is CDDA
- if (CServiceBroker::GetMediaManager().IsDiscInDrive() && m_vecItems->IsCDDA() &&
+ if (CServiceBroker::GetMediaManager().IsDiscInDrive() && MUSIC::IsCDDA(*m_vecItems) &&
(profileManager->GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
{
buttons.Add(CONTEXT_BUTTON_CDDB, 16002);
@@ -561,7 +567,7 @@ void CGUIWindowMusicBase::OnRipCD()
{
if (CServiceBroker::GetMediaManager().IsAudio())
{
- if (!g_application.CurrentFileItem().IsCDDA())
+ if (!MUSIC::IsCDDA(g_application.CurrentFileItem()))
{
#ifdef HAS_CDDA_RIPPER
KODI::CDRIP::CCDDARipper::GetInstance().RipCD();
@@ -576,7 +582,7 @@ void CGUIWindowMusicBase::OnRipTrack(int iItem)
{
if (CServiceBroker::GetMediaManager().IsAudio())
{
- if (!g_application.CurrentFileItem().IsCDDA())
+ if (!MUSIC::IsCDDA(g_application.CurrentFileItem()))
{
#ifdef HAS_CDDA_RIPPER
CFileItemPtr item = m_vecItems->Get(iItem);
@@ -706,7 +712,7 @@ bool CGUIWindowMusicBase::OnPlayMedia(int iItem, const std::string &player)
g_partyModeManager.AddUserSongs(playlistTemp, !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MUSICPLAYER_QUEUEBYDEFAULT));
return true;
}
- else if (!pItem->IsPlayList() && !pItem->IsInternetStream())
+ else if (!pItem->IsPlayList() && !NETWORK::IsInternetStream(*pItem))
{ // single music file - if we get here then we have autoplaynextitem turned off or queuebydefault
// turned on, but we still want to use the playlist player in order to handle more queued items
// following etc.
@@ -728,10 +734,12 @@ bool CGUIWindowMusicBase::OnPlayMedia(int iItem, const std::string &player)
void CGUIWindowMusicBase::OnRetrieveMusicInfo(CFileItemList& items)
{
// No need to attempt to read music file tags for music videos
- if (items.IsVideoDb())
+ if (IsVideoDb(items))
return;
- if (items.GetFolderCount()==items.Size() || items.IsMusicDb() ||
- (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MUSICFILES_USETAGS) && !items.IsCDDA()))
+ if (items.GetFolderCount() == items.Size() || MUSIC::IsMusicDb(items) ||
+ (!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_MUSICFILES_USETAGS) &&
+ !MUSIC::IsCDDA(items)))
{
return;
}
@@ -874,10 +882,9 @@ bool CGUIWindowMusicBase::GetDirectory(const std::string &strDirectory, CFileIte
bool CGUIWindowMusicBase::CheckFilterAdvanced(CFileItemList &items) const
{
const std::string& content = items.GetContent();
- if ((items.IsMusicDb() || CanContainFilter(m_strFilterPath)) &&
+ if ((MUSIC::IsMusicDb(items) || CanContainFilter(m_strFilterPath)) &&
(StringUtils::EqualsNoCase(content, "artists") ||
- StringUtils::EqualsNoCase(content, "albums") ||
- StringUtils::EqualsNoCase(content, "songs")))
+ StringUtils::EqualsNoCase(content, "albums") || StringUtils::EqualsNoCase(content, "songs")))
return true;
return false;
@@ -891,7 +898,7 @@ bool CGUIWindowMusicBase::CanContainFilter(const std::string &strDirectory) cons
bool CGUIWindowMusicBase::OnSelect(int iItem)
{
auto item = m_vecItems->Get(iItem);
- if (item->IsAudioBook())
+ if (MUSIC::IsAudioBook(*item))
{
int bookmark;
if (m_musicdatabase.GetResumeBookmarkForAudioBook(*item, bookmark) && bookmark > 0)
@@ -1039,7 +1046,7 @@ void CGUIWindowMusicBase::OnPrepareFileItems(CFileItemList &items)
{
CGUIMediaWindow::OnPrepareFileItems(items);
- if (!items.IsMusicDb() && !items.IsSmartPlayList())
+ if (!MUSIC::IsMusicDb(items) && !items.IsSmartPlayList())
RetrieveMusicInfo();
}
diff --git a/xbmc/music/windows/GUIWindowMusicNav.cpp b/xbmc/music/windows/GUIWindowMusicNav.cpp
index a544090204..46e1fab725 100644
--- a/xbmc/music/windows/GUIWindowMusicNav.cpp
+++ b/xbmc/music/windows/GUIWindowMusicNav.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowMusicNav.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
@@ -28,9 +29,11 @@
#include "input/actions/ActionIDs.h"
#include "messaging/ApplicationMessenger.h"
#include "messaging/helpers/DialogOKHelper.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicLibraryQueue.h"
#include "music/dialogs/GUIDialogInfoProviderSettings.h"
#include "music/tags/MusicInfoTag.h"
+#include "network/NetworkFileItemClassify.h"
#include "playlists/PlayList.h"
#include "playlists/PlayListFactory.h"
#include "profiles/ProfileManager.h"
@@ -45,6 +48,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/dialogs/GUIDialogVideoInfo.h"
#include "video/windows/GUIWindowVideoNav.h"
#include "view/GUIViewState.h"
@@ -52,7 +56,9 @@
using namespace XFILE;
using namespace PLAYLIST;
using namespace MUSICDATABASEDIRECTORY;
+using namespace KODI;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
#define CONTROL_BTNVIEWASICONS 2
#define CONTROL_BTNSORTBY 3
@@ -347,7 +353,7 @@ bool CGUIWindowMusicNav::OnClick(int iItem, const std::string &player /* = "" */
}
return true;
}
- if (item->IsMusicDb() && !item->m_bIsFolder)
+ if (MUSIC::IsMusicDb(*item) && !item->m_bIsFolder)
m_musicdatabase.SetPropertiesForFileItem(*item);
if (item->IsPlayList() &&
@@ -386,7 +392,7 @@ bool CGUIWindowMusicNav::GetDirectory(const std::string &strDirectory, CFileItem
}
// update our content in the info manager
- if (StringUtils::StartsWithNoCase(strDirectory, "videodb://") || items.IsVideoDb())
+ if (StringUtils::StartsWithNoCase(strDirectory, "videodb://") || IsVideoDb(items))
{
CVideoDatabaseDirectory dir;
VIDEODATABASEDIRECTORY::NODE_TYPE node = dir.GetDirectoryChildType(items.GetPath());
@@ -425,7 +431,7 @@ bool CGUIWindowMusicNav::GetDirectory(const std::string &strDirectory, CFileItem
break;
}
}
- else if (StringUtils::StartsWithNoCase(strDirectory, "musicdb://") || items.IsMusicDb())
+ else if (StringUtils::StartsWithNoCase(strDirectory, "musicdb://") || MUSIC::IsMusicDb(items))
{
CMusicDatabaseDirectory dir;
NODE_TYPE node = dir.GetDirectoryChildType(items.GetPath());
@@ -579,7 +585,7 @@ void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &butt
CGUIDialogContextMenu::GetContextButtons("music", item, buttons);
#ifdef HAS_OPTICAL_DRIVE
// enable Rip CD an audio disc
- if (CServiceBroker::GetMediaManager().IsDiscInDrive() && item->IsCDDA())
+ if (CServiceBroker::GetMediaManager().IsDiscInDrive() && MUSIC::IsCDDA(*item))
{
// those cds can also include Audio Tracks: CDExtra and MixedMode!
MEDIA_DETECT::CCdInfo* pCdInfo = CServiceBroker::GetMediaManager().GetCdInfo();
@@ -607,7 +613,8 @@ void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &butt
// Scan button for real folders containing files when navigating within music sources.
// Blacklist the bespoke Kodi protocols as to many valid external protocols to whitelist
if (m_vecItems->GetContent() == "files" && // Other content not scanned to library
- !inPlaylists && !m_vecItems->IsInternetStream() && // Not playlists locations or streams
+ !inPlaylists &&
+ !NETWORK::IsInternetStream(*m_vecItems) && // Not playlists locations or streams
!item->IsPath("add") && !item->IsParentFolder() && // Not ".." and "Add items
item->m_bIsFolder && // Folders only, but playlists can be folders too
!URIUtils::IsLibraryContent(item->GetPath()) && // database folder or .xsp files
@@ -624,8 +631,8 @@ void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &butt
if (!item->IsParentFolder() && !dir.IsAllItem(item->GetPath()))
{
- if (item->m_bIsFolder && !item->IsVideoDb() &&
- !item->IsPlugin() && !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://"))
+ if (item->m_bIsFolder && !IsVideoDb(*item) && !item->IsPlugin() &&
+ !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://"))
{
if (item->IsAlbum())
// enable query all albums button only in album view
@@ -718,7 +725,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
{
case CONTEXT_BUTTON_INFO:
{
- if (!item->IsVideoDb())
+ if (!IsVideoDb(*item))
return CGUIWindowMusicBase::OnContextButton(itemNumber,button);
// music videos - artists
@@ -807,7 +814,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
}
case CONTEXT_BUTTON_RENAME:
- if (!item->IsVideoDb() && !item->IsReadOnly())
+ if (!IsVideoDb(*item) && !item->IsReadOnly())
OnRenameItem(itemNumber);
CGUIDialogVideoInfo::UpdateVideoItemTitle(item);
@@ -823,7 +830,7 @@ bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
if (gui && gui->ConfirmDelete(item->GetPath()))
CFileUtils::DeleteItem(item);
}
- else if (!item->IsVideoDb())
+ else if (!IsVideoDb(*item))
OnDeleteItem(itemNumber);
else
{
diff --git a/xbmc/music/windows/GUIWindowMusicPlaylist.cpp b/xbmc/music/windows/GUIWindowMusicPlaylist.cpp
index fe1d72a163..92578e88be 100644
--- a/xbmc/music/windows/GUIWindowMusicPlaylist.cpp
+++ b/xbmc/music/windows/GUIWindowMusicPlaylist.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowMusicPlaylist.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
@@ -24,6 +25,7 @@
#include "guilib/LocalizeStrings.h"
#include "input/actions/Action.h"
#include "input/actions/ActionIDs.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "playlists/PlayListM3U.h"
#include "profiles/ProfileManager.h"
@@ -37,6 +39,8 @@
#include "utils/log.h"
#include "view/GUIViewState.h"
+using namespace KODI;
+
#define CONTROL_BTNVIEWASICONS 2
#define CONTROL_BTNSORTBY 3
#define CONTROL_BTNSORTASC 4
@@ -335,7 +339,7 @@ void CGUIWindowMusicPlayList::SavePlayList()
// Musicdatabase items should contain the real path instead of a musicdb url
// otherwise the user can't save and reuse the playlist when the musicdb gets deleted
- if (pItem->IsMusicDb())
+ if (MUSIC::IsMusicDb(*pItem))
pItem->SetPath(pItem->GetMusicInfoTag()->GetURL());
playlist.Add(pItem);
diff --git a/xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp b/xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp
index cf9e73e817..16ecdd0c3c 100644
--- a/xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp
+++ b/xbmc/music/windows/GUIWindowMusicPlaylistEditor.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "Util.h"
diff --git a/xbmc/music/windows/MusicFileItemListModifier.cpp b/xbmc/music/windows/MusicFileItemListModifier.cpp
index fe04aed423..56a2dad2fe 100644
--- a/xbmc/music/windows/MusicFileItemListModifier.cpp
+++ b/xbmc/music/windows/MusicFileItemListModifier.cpp
@@ -9,21 +9,24 @@
#include "MusicFileItemListModifier.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/MusicDatabaseDirectory/DirectoryNode.h"
#include "guilib/LocalizeStrings.h"
#include "music/MusicDbUrl.h"
+#include "music/MusicFileItemClassify.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include <memory>
+using namespace KODI;
using namespace XFILE::MUSICDATABASEDIRECTORY;
bool CMusicFileItemListModifier::CanModify(const CFileItemList &items) const
{
- if (items.IsMusicDb())
+ if (MUSIC::IsMusicDb(items))
return true;
return false;
@@ -39,7 +42,7 @@ bool CMusicFileItemListModifier::Modify(CFileItemList &items) const
// depending on the child node
void CMusicFileItemListModifier::AddQueuingFolder(CFileItemList& items)
{
- if (!items.IsMusicDb())
+ if (!MUSIC::IsMusicDb(items))
return;
auto directoryNode = CDirectoryNode::ParseURL(items.GetPath());
diff --git a/xbmc/network/AirPlayServer.cpp b/xbmc/network/AirPlayServer.cpp
index eaa0aa58fd..6b30e11e06 100644
--- a/xbmc/network/AirPlayServer.cpp
+++ b/xbmc/network/AirPlayServer.cpp
@@ -12,6 +12,7 @@
#include "AirPlayServer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "application/ApplicationComponents.h"
diff --git a/xbmc/network/CMakeLists.txt b/xbmc/network/CMakeLists.txt
index 147af290b6..2060605761 100644
--- a/xbmc/network/CMakeLists.txt
+++ b/xbmc/network/CMakeLists.txt
@@ -4,6 +4,7 @@ set(SOURCES DNSNameCache.cpp
EventServer.cpp
GUIDialogNetworkSetup.cpp
Network.cpp
+ NetworkFileItemClassify.cpp
NetworkServices.cpp
Socket.cpp
TCPServer.cpp
@@ -18,6 +19,7 @@ set(HEADERS DNSNameCache.h
EventServer.h
GUIDialogNetworkSetup.h
Network.h
+ NetworkFileItemClassify.h
NetworkServices.h
Socket.h
TCPServer.h
diff --git a/xbmc/network/NetworkFileItemClassify.cpp b/xbmc/network/NetworkFileItemClassify.cpp
new file mode 100644
index 0000000000..ed4bd77be6
--- /dev/null
+++ b/xbmc/network/NetworkFileItemClassify.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2005-2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "network/NetworkFileItemClassify.h"
+
+#include "FileItem.h"
+#include "utils/URIUtils.h"
+
+namespace KODI::NETWORK
+{
+
+bool IsInternetStream(const CFileItem& item, const bool bStrictCheck /* = false */)
+{
+ if (item.HasProperty("IsHTTPDirectory"))
+ return bStrictCheck;
+
+ if (!item.GetDynPath().empty())
+ return URIUtils::IsInternetStream(item.GetDynPath(), bStrictCheck);
+
+ return URIUtils::IsInternetStream(item.GetPath(), bStrictCheck);
+}
+
+bool IsRemote(const CFileItem& item)
+{
+ return URIUtils::IsRemote(item.GetPath());
+}
+
+bool IsStreamedFilesystem(const CFileItem& item)
+{
+ if (!item.GetDynPath().empty())
+ return URIUtils::IsStreamedFilesystem(item.GetDynPath());
+
+ return URIUtils::IsStreamedFilesystem(item.GetPath());
+}
+
+} // namespace KODI::NETWORK
diff --git a/xbmc/network/NetworkFileItemClassify.h b/xbmc/network/NetworkFileItemClassify.h
new file mode 100644
index 0000000000..5a96a98253
--- /dev/null
+++ b/xbmc/network/NetworkFileItemClassify.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+class CFileItem;
+
+namespace KODI::NETWORK
+{
+
+//! \brief Check whether an item is a an internet stream.
+bool IsInternetStream(const CFileItem& item, const bool bStrictCheck = false);
+
+//! \brief Check whether an item is on a remote location.
+bool IsRemote(const CFileItem& item);
+
+//! \brief Check whether an item is on a streamed filesystem.
+bool IsStreamedFilesystem(const CFileItem& item);
+} // namespace KODI::NETWORK
diff --git a/xbmc/network/test/CMakeLists.txt b/xbmc/network/test/CMakeLists.txt
index 05eb260c0b..b075775736 100644
--- a/xbmc/network/test/CMakeLists.txt
+++ b/xbmc/network/test/CMakeLists.txt
@@ -1,4 +1,5 @@
-set(SOURCES TestNetwork.cpp)
+set(SOURCES TestNetwork.cpp
+ TestNetworkFileItemClassify.cpp)
if(MICROHTTPD_FOUND)
list(APPEND SOURCES TestWebServer.cpp)
diff --git a/xbmc/network/test/TestNetworkFileItemClassify.cpp b/xbmc/network/test/TestNetworkFileItemClassify.cpp
new file mode 100644
index 0000000000..13dbd44c72
--- /dev/null
+++ b/xbmc/network/test/TestNetworkFileItemClassify.cpp
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "FileItem.h"
+#include "URL.h"
+#include "filesystem/StackDirectory.h"
+#include "network/NetworkFileItemClassify.h"
+
+#include <array>
+#include <string>
+
+#include <gtest/gtest.h>
+
+using namespace KODI;
+
+namespace
+{
+
+struct SimpleDefinition
+{
+ SimpleDefinition(const std::string& path, bool folder, bool res) : item(path, folder), result(res)
+ {
+ }
+
+ CFileItem item;
+ bool result;
+};
+
+} // namespace
+
+struct InternetStreamDefinition
+{
+ InternetStreamDefinition(const std::string& path, bool folder, bool strict, bool res)
+ : item(path, folder), strictCheck(strict), result(res)
+ {
+ }
+
+ CFileItem item;
+ bool strictCheck;
+ bool result;
+};
+
+class InternetStreamTest : public testing::WithParamInterface<InternetStreamDefinition>,
+ public testing::Test
+{
+};
+
+TEST_P(InternetStreamTest, IsInternetStream)
+{
+ EXPECT_EQ(NETWORK::IsInternetStream(GetParam().item, GetParam().strictCheck), GetParam().result);
+}
+
+const auto inetstream_tests = std::array{
+ InternetStreamDefinition{"/home/user/test.disc", false, false, false},
+ InternetStreamDefinition{"/home/user/test.disc", true, true, false},
+ InternetStreamDefinition{"http://some.where/foo", false, false, true},
+ InternetStreamDefinition{"http://some.where/foo", false, true, true},
+ InternetStreamDefinition{"http://some.where/foo", true, false, true},
+ InternetStreamDefinition{"http://some.where/foo", true, true, true},
+ InternetStreamDefinition{"https://some.where/foo", false, false, true},
+ InternetStreamDefinition{"https://some.where/foo", false, true, true},
+ InternetStreamDefinition{"https://some.where/foo", true, false, true},
+ InternetStreamDefinition{"https://some.where/foo", true, true, true},
+ InternetStreamDefinition{"tcp://some.where/foo", false, false, true},
+ InternetStreamDefinition{"tcp://some.where/foo", false, true, true},
+ InternetStreamDefinition{"tcp://some.where/foo", true, false, true},
+ InternetStreamDefinition{"tcp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"udp://some.where/foo", false, false, true},
+ InternetStreamDefinition{"udp://some.where/foo", false, true, true},
+ InternetStreamDefinition{"udp://some.where/foo", true, false, true},
+ InternetStreamDefinition{"udp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rtp://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rtp://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rtp://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rtp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"sdp://some.where/foo", false, false, true},
+ InternetStreamDefinition{"sdp://some.where/foo", false, true, true},
+ InternetStreamDefinition{"sdp://some.where/foo", true, false, true},
+ InternetStreamDefinition{"sdp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"mms://some.where/foo", false, false, true},
+ InternetStreamDefinition{"mms://some.where/foo", false, true, true},
+ InternetStreamDefinition{"mms://some.where/foo", true, false, true},
+ InternetStreamDefinition{"mms://some.where/foo", true, true, true},
+ InternetStreamDefinition{"mmst://some.where/foo", false, false, true},
+ InternetStreamDefinition{"mmst://some.where/foo", false, true, true},
+ InternetStreamDefinition{"mmst://some.where/foo", true, false, true},
+ InternetStreamDefinition{"mmst://some.where/foo", true, true, true},
+ InternetStreamDefinition{"mmsh://some.where/foo", false, false, true},
+ InternetStreamDefinition{"mmsh://some.where/foo", false, true, true},
+ InternetStreamDefinition{"mmsh://some.where/foo", true, false, true},
+ InternetStreamDefinition{"mmsh://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rtsp://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rtsp://some.where/foo", false, true, true},
+ InternetStreamDefinition{"rtsp://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rtsp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rtmp://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rtmp://some.where/foo", false, true, true},
+ InternetStreamDefinition{"rtmp://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rtmp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rtmpt://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rtmpt://some.where/foo", false, true, true},
+ InternetStreamDefinition{"rtmpt://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rtmpt://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rtmpe://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rtmpe://some.where/foo", false, true, true},
+ InternetStreamDefinition{"rtmpe://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rtmpe://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rtmpte://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rtmpte://some.where/foo", false, true, true},
+ InternetStreamDefinition{"rtmpte://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rtmpte://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rtmps://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rtmps://some.where/foo", false, true, true},
+ InternetStreamDefinition{"rtmps://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rtmps://some.where/foo", true, true, true},
+ InternetStreamDefinition{"shout://some.where/foo", false, false, true},
+ InternetStreamDefinition{"shout://some.where/foo", false, true, true},
+ InternetStreamDefinition{"shout://some.where/foo", true, false, true},
+ InternetStreamDefinition{"shout://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rss://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rss://some.where/foo", false, true, true},
+ InternetStreamDefinition{"rss://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rss://some.where/foo", true, true, true},
+ InternetStreamDefinition{"rsss://some.where/foo", false, false, true},
+ InternetStreamDefinition{"rsss://some.where/foo", false, true, true},
+ InternetStreamDefinition{"rsss://some.where/foo", true, false, true},
+ InternetStreamDefinition{"rsss://some.where/foo", true, true, true},
+ InternetStreamDefinition{"upnp://some.where/foo", false, false, false},
+ InternetStreamDefinition{"upnp://some.where/foo", true, false, false},
+ InternetStreamDefinition{"upnp://some.where/foo", false, true, true},
+ InternetStreamDefinition{"upnp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"ftp://some.where/foo", false, false, false},
+ InternetStreamDefinition{"ftp://some.where/foo", true, false, false},
+ InternetStreamDefinition{"ftp://some.where/foo", false, true, true},
+ InternetStreamDefinition{"ftp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"sftp://some.where/foo", false, false, false},
+ InternetStreamDefinition{"sftp://some.where/foo", true, false, false},
+ InternetStreamDefinition{"sftp://some.where/foo", false, true, true},
+ InternetStreamDefinition{"sftp://some.where/foo", true, true, true},
+ InternetStreamDefinition{"ssh://some.where/foo", false, false, false},
+ InternetStreamDefinition{"ssh://some.where/foo", true, false, false},
+ InternetStreamDefinition{"ssh://some.where/foo", false, true, true},
+ InternetStreamDefinition{"ssh://some.where/foo", true, true, true},
+ InternetStreamDefinition{"ssh://some.where/foo", true, true, true},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestNetworkFileItemClassify,
+ InternetStreamTest,
+ testing::ValuesIn(inetstream_tests));
+
+TEST(TestNetworkWorkFileItemClassify, InternetStreamStacks)
+{
+ std::string stackPath;
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"/home/foo/somthing.avi", "/home/bar/else.mkv"}, stackPath));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, false), false));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, true), false));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, false), true));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, true), true));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"https://home/foo/somthing.avi", "https://home/bar/else.mkv"}, stackPath));
+ EXPECT_TRUE(NETWORK::IsInternetStream(CFileItem(stackPath, false), false));
+ EXPECT_TRUE(NETWORK::IsInternetStream(CFileItem(stackPath, true), false));
+ EXPECT_TRUE(NETWORK::IsInternetStream(CFileItem(stackPath, false), true));
+ EXPECT_TRUE(NETWORK::IsInternetStream(CFileItem(stackPath, true), true));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"ftp://home/foo/somthing.avi", "ftp://home/bar/else.mkv"}, stackPath));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, false), false));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, true), false));
+ EXPECT_TRUE(NETWORK::IsInternetStream(CFileItem(stackPath, false), true));
+ EXPECT_TRUE(NETWORK::IsInternetStream(CFileItem(stackPath, true), true));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"ftp://home/foo/somthing.avi", "/home/bar/else.mkv"}, stackPath));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, false), false));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, true), false));
+ EXPECT_TRUE(NETWORK::IsInternetStream(CFileItem(stackPath, false), true));
+ EXPECT_TRUE(NETWORK::IsInternetStream(CFileItem(stackPath, true), true));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"/home/foo/somthing.avi", "ftp://home/bar/else.mkv"}, stackPath));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, false), false));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, true), false));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, false), true));
+ EXPECT_FALSE(NETWORK::IsInternetStream(CFileItem(stackPath, true), true));
+}
+
+class RemoteTest : public testing::WithParamInterface<SimpleDefinition>, public testing::Test
+{
+};
+
+TEST_P(RemoteTest, IsRemote)
+{
+ EXPECT_EQ(NETWORK::IsRemote(GetParam().item), GetParam().result);
+}
+
+const auto remote_tests = std::array{
+ SimpleDefinition{"cdda://1", false, false},
+ SimpleDefinition{"cdda://1", true, false},
+ SimpleDefinition{"iso9660://some.file", false, false},
+ SimpleDefinition{"cdda://some.file", true, false},
+ SimpleDefinition{"special://home/foo.xml", false, false},
+ SimpleDefinition{"special://home", true, false},
+ SimpleDefinition{"zip://" + CURL::Encode("/home/foo/bar.zip"), true, false},
+ SimpleDefinition{"zip://" + CURL::Encode("https://some.where/yo.zip"), true, true},
+ SimpleDefinition{"addons://plugins", true, false},
+ SimpleDefinition{"sources://music", true, false},
+ SimpleDefinition{"videodb://1/2", true, false},
+ SimpleDefinition{"musicdb://1/2", true, false},
+ SimpleDefinition{"library://movies/titles", true, false},
+ SimpleDefinition{"plugin://plugin.video.yo", true, false},
+ SimpleDefinition{"androidapp://cool.app", true, false},
+ SimpleDefinition{"/home/foo/bar", true, false},
+ SimpleDefinition{"https://127.0.0.1/bar", true, false},
+ SimpleDefinition{"https://some.where/bar", true, true},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestNetworkFileItemClassify, RemoteTest, testing::ValuesIn(remote_tests));
+
+class StreamedFilesystemTest : public testing::WithParamInterface<SimpleDefinition>,
+ public testing::Test
+{
+};
+
+TEST_P(StreamedFilesystemTest, IsStreamedFilesystem)
+{
+ EXPECT_EQ(NETWORK::IsStreamedFilesystem(GetParam().item), GetParam().result);
+}
+
+const auto streamedfs_tests = std::array{
+ SimpleDefinition{"/home/user/test.disc", false, false},
+ SimpleDefinition{"/home/user/test.disc", true, false},
+ SimpleDefinition{"http://some.where/foo", false, true},
+ SimpleDefinition{"http://some.where/foo", true, true},
+ SimpleDefinition{"https://some.where/foo", false, true},
+ SimpleDefinition{"https://some.where/foo", true, true},
+ SimpleDefinition{"ftp://some.where/foo", false, true},
+ SimpleDefinition{"ftp://some.where/foo", true, true},
+ SimpleDefinition{"sftp://some.where/foo", false, true},
+ SimpleDefinition{"sftp://some.where/foo", true, true},
+ SimpleDefinition{"ssh://some.where/foo", false, true},
+ SimpleDefinition{"ssh://some.where/foo", true, true},
+ SimpleDefinition{"ssh://some.where/foo", true, true},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestNetworkFileItemClassify,
+ StreamedFilesystemTest,
+ testing::ValuesIn(streamedfs_tests));
+
+TEST(TestNetworkWorkFileItemClassify, StreamedFilesystemStacks)
+{
+ std::string stackPath;
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"/home/foo/somthing.avi", "/home/bar/else.mkv"}, stackPath));
+ EXPECT_FALSE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, false)));
+ EXPECT_FALSE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, true)));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"https://home/foo/somthing.avi", "https://home/bar/else.mkv"}, stackPath));
+ EXPECT_TRUE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, false)));
+ EXPECT_TRUE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, true)));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"shout://home/foo/somthing.avi", "shout://home/bar/else.mkv"}, stackPath));
+ EXPECT_TRUE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, false)));
+ EXPECT_TRUE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, true)));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"ftp://home/foo/somthing.avi", "ftp://home/bar/else.mkv"}, stackPath));
+ EXPECT_TRUE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, false)));
+ EXPECT_TRUE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, true)));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"ftp://home/foo/somthing.avi", "/home/bar/else.mkv"}, stackPath));
+ EXPECT_TRUE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, false)));
+ EXPECT_TRUE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, true)));
+
+ EXPECT_TRUE(XFILE::CStackDirectory::ConstructStackPath(
+ {"/home/foo/somthing.avi", "ftp://home/bar/else.mkv"}, stackPath));
+ EXPECT_FALSE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, false)));
+ EXPECT_FALSE(NETWORK::IsStreamedFilesystem(CFileItem(stackPath, true)));
+}
diff --git a/xbmc/network/upnp/UPnPInternal.cpp b/xbmc/network/upnp/UPnPInternal.cpp
index 734e7fd067..c70edf2b32 100644
--- a/xbmc/network/upnp/UPnPInternal.cpp
+++ b/xbmc/network/upnp/UPnPInternal.cpp
@@ -17,6 +17,7 @@
#include "filesystem/MusicDatabaseDirectory.h"
#include "filesystem/StackDirectory.h"
#include "filesystem/VideoDatabaseDirectory.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
@@ -28,6 +29,7 @@
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include <algorithm>
@@ -38,6 +40,7 @@
#include <Platinum/Source/Platinum/Platinum.h>
+using namespace KODI;
using namespace MUSIC_INFO;
using namespace XFILE;
@@ -203,13 +206,13 @@ NPT_String GetMimeType(const CFileItem& item, const PLT_HttpRequestContext* cont
/* fallback to generic mime type if not found */
if (mime.IsEmpty())
{
- if (item.IsVideo() || item.IsVideoDb())
+ if (VIDEO::IsVideo(item) || VIDEO::IsVideoDb(item))
mime = "video/" + ext;
- else if (item.IsAudio() || item.IsMusicDb())
+ else if (MUSIC::IsAudio(item) || MUSIC::IsMusicDb(item))
mime = "audio/" + ext;
else if (item.IsPicture())
mime = "image/" + ext;
- else if (item.IsSubtitle())
+ else if (VIDEO::IsSubtitle(item))
mime = "text/" + ext;
}
@@ -518,7 +521,7 @@ PLT_MediaObject* BuildObject(CFileItem& item,
object->m_ObjectID = EncodeObjectId(item.GetPath());
/* Setup object type */
- if (item.IsMusicDb() || item.IsAudio())
+ if (MUSIC::IsMusicDb(item) || MUSIC::IsAudio(item))
{
object->m_ObjectClass.type = "object.item.audioItem.musicTrack";
@@ -528,7 +531,7 @@ PLT_MediaObject* BuildObject(CFileItem& item,
PopulateObjectFromTag(*tag, *object, &file_path, &resource, quirks, upnp_service);
}
}
- else if (item.IsVideoDb() || item.IsVideo())
+ else if (VIDEO::IsVideoDb(item) || VIDEO::IsVideo(item))
{
object->m_ObjectClass.type = "object.item.videoItem";
@@ -614,7 +617,7 @@ PLT_MediaObject* BuildObject(CFileItem& item,
container->m_ChildrenCount = -1;
/* this might be overkill, but hey */
- if (item.IsMusicDb())
+ if (MUSIC::IsMusicDb(item))
{
MUSICDATABASEDIRECTORY::NODE_TYPE node =
CMusicDatabaseDirectory::GetDirectoryType(item.GetPath());
@@ -672,7 +675,7 @@ PLT_MediaObject* BuildObject(CFileItem& item,
break;
}
}
- else if (item.IsVideoDb())
+ else if (VIDEO::IsVideoDb(item))
{
VIDEODATABASEDIRECTORY::NODE_TYPE node =
CVideoDatabaseDirectory::GetDirectoryType(item.GetPath());
@@ -818,7 +821,7 @@ PLT_MediaObject* BuildObject(CFileItem& item,
// look for and add external subtitle if we are processing a video file and
// we are being called by a UPnP player or renderer or the user has chosen
// to look for external subtitles
- if (upnp_server != NULL && item.IsVideo() &&
+ if (upnp_server != nullptr && VIDEO::IsVideo(item) &&
(upnp_service == UPnPPlayer || upnp_service == UPnPRenderer ||
settings->GetBool(CSettings::SETTING_SERVICES_UPNPLOOKFOREXTERNALSUBTITLES)))
{
diff --git a/xbmc/network/upnp/UPnPPlayer.cpp b/xbmc/network/upnp/UPnPPlayer.cpp
index 0080141db6..143363836b 100644
--- a/xbmc/network/upnp/UPnPPlayer.cpp
+++ b/xbmc/network/upnp/UPnPPlayer.cpp
@@ -17,6 +17,7 @@
#include "input/actions/Action.h"
#include "input/actions/ActionIDs.h"
#include "messaging/helpers/DialogHelper.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicThumbLoader.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -24,6 +25,7 @@
#include "utils/StringUtils.h"
#include "utils/TimeUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoThumbLoader.h"
#include <mutex>
@@ -33,6 +35,7 @@
#include <Platinum/Source/Platinum/Platinum.h>
using namespace KODI::MESSAGING;
+using namespace KODI;
using KODI::MESSAGING::HELPERS::DialogResponse;
using namespace std::chrono_literals;
@@ -223,9 +226,9 @@ int CUPnPPlayer::PlayFile(const CFileItem& file,
NPT_CHECK_POINTER_LABEL_SEVERE(m_delegate, failed);
- if (file.IsVideoDb())
+ if (VIDEO::IsVideoDb(file))
thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
- else if (item.IsMusicDb())
+ else if (MUSIC::IsMusicDb(item))
thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());
obj = BuildObject(item, path, false, thumb_loader, NULL, CUPnP::GetServer(), UPnPPlayer);
@@ -383,11 +386,11 @@ bool CUPnPPlayer::OpenFile(const CFileItem& file, const CPlayerOptions& options)
m_stopremote = true;
m_started = true;
- if (file.IsVideo())
+ if (VIDEO::IsVideo(file))
{
m_hasVideo = true;
}
- else if (file.IsAudio())
+ else if (MUSIC::IsAudio(file))
{
m_hasAudio = true;
}
@@ -417,9 +420,9 @@ bool CUPnPPlayer::QueueNextFile(const CFileItem& file)
NPT_String path(file.GetPath().c_str());
NPT_String tmp;
- if (file.IsVideoDb())
+ if (VIDEO::IsVideoDb(file))
thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
- else if (item.IsMusicDb())
+ else if (MUSIC::IsMusicDb(item))
thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());
obj = BuildObject(item, path, false, thumb_loader, NULL, CUPnP::GetServer(), UPnPPlayer);
diff --git a/xbmc/network/upnp/UPnPRenderer.cpp b/xbmc/network/upnp/UPnPRenderer.cpp
index a2374458b5..acc25a81a9 100644
--- a/xbmc/network/upnp/UPnPRenderer.cpp
+++ b/xbmc/network/upnp/UPnPRenderer.cpp
@@ -8,6 +8,7 @@
#include "UPnPRenderer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
@@ -30,12 +31,15 @@
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "utils/Variant.h"
+#include "video/VideoFileItemClassify.h"
#include <inttypes.h>
#include <mutex>
#include <Platinum/Source/Platinum/Platinum.h>
+using namespace KODI::VIDEO;
+
NPT_SET_LOCAL_LOGGER("xbmc.upnp.renderer")
namespace UPNP
@@ -628,7 +632,7 @@ NPT_Result CUPnPRenderer::OnSetNextAVTransportURI(PLT_ActionReference& action)
{
PLAYLIST::Id playlistId = PLAYLIST::TYPE_MUSIC;
- if (item->IsVideo())
+ if (IsVideo(*item))
playlistId = PLAYLIST::TYPE_VIDEO;
// note: auto-deleted when the message is consumed
diff --git a/xbmc/network/upnp/UPnPServer.cpp b/xbmc/network/upnp/UPnPServer.cpp
index 3618708a5d..ca1db197cb 100644
--- a/xbmc/network/upnp/UPnPServer.cpp
+++ b/xbmc/network/upnp/UPnPServer.cpp
@@ -7,6 +7,7 @@
*/
#include "UPnPServer.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
@@ -24,6 +25,7 @@
#include "interfaces/AnnouncementManager.h"
#include "music/Artist.h"
#include "music/MusicDatabase.h"
+#include "music/MusicFileItemClassify.h"
#include "music/MusicLibraryQueue.h"
#include "music/MusicThumbLoader.h"
#include "music/tags/MusicInfoTag.h"
@@ -38,6 +40,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoLibraryQueue.h"
#include "video/VideoThumbLoader.h"
#include "view/GUIViewState.h"
@@ -49,6 +52,8 @@
NPT_SET_LOCAL_LOGGER("xbmc.upnp.server")
using namespace ANNOUNCEMENT;
+using namespace KODI;
+using namespace KODI::VIDEO;
using namespace XFILE;
using KODI::UTILITY::CDigest;
@@ -448,7 +453,7 @@ PLT_MediaObject* CUPnPServer::Build(const std::shared_ptr<CFileItem>& item,
item->m_bIsFolder = true;
}
// audio and not a playlist -> song, so it's not a folder
- else if (item->IsAudio())
+ else if (MUSIC::IsAudio(*item))
{
item->m_bIsFolder = false;
}
@@ -713,11 +718,11 @@ NPT_Result CUPnPServer::OnBrowseMetadata(PLT_ActionReference& action,
parent = "sources://video/"; // this can only match video sources
}
- if (item->IsVideoDb())
+ if (IsVideoDb(*item))
{
thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
}
- else if (item->IsMusicDb())
+ else if (MUSIC::IsMusicDb(*item))
{
thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());
}
@@ -1306,7 +1311,7 @@ NPT_Result CUPnPServer::OnUpdateObject(PLT_ActionReference& action,
NPT_CHECK_LABEL(FindServiceById("urn:upnp-org:serviceId:ContentDirectory", service), error);
NPT_CHECK_LABEL(service->PauseEventing(), error);
- if (updated.IsVideoDb())
+ if (IsVideoDb(updated))
{
CVideoDatabase db;
NPT_CHECK_LABEL(!db.Open(), error);
@@ -1394,7 +1399,7 @@ NPT_Result CUPnPServer::OnUpdateObject(PLT_ActionReference& action,
CVideoThumbLoader().FillLibraryArt(updated);
}
}
- else if (updated.IsMusicDb())
+ else if (MUSIC::IsMusicDb(updated))
{
//! @todo implement this
}
@@ -1408,9 +1413,9 @@ NPT_Result CUPnPServer::OnUpdateObject(PLT_ActionReference& action,
if (updatelisting)
{
updated.SetPath(path);
- if (updated.IsVideoDb())
+ if (IsVideoDb(updated))
CUtil::DeleteVideoDatabaseDirectoryCache();
- else if (updated.IsMusicDb())
+ else if (MUSIC::IsMusicDb(updated))
CUtil::DeleteMusicDatabaseDirectoryCache();
CFileItemPtr msgItem(new CFileItem(updated));
@@ -1525,7 +1530,7 @@ NPT_Result CUPnPServer::ServeFile(const NPT_HttpRequest& request,
void CUPnPServer::DefaultSortItems(CFileItemList& items)
{
CGUIViewState* viewState =
- CGUIViewState::GetViewState(items.IsVideoDb() ? WINDOW_VIDEO_NAV : -1, items);
+ CGUIViewState::GetViewState(IsVideoDb(items) ? WINDOW_VIDEO_NAV : -1, items);
if (viewState)
{
SortDescription sorting = viewState->GetSortMethod();
diff --git a/xbmc/peripherals/addons/PeripheralAddon.cpp b/xbmc/peripherals/addons/PeripheralAddon.cpp
index d55dfb55ce..2b7aca7584 100644
--- a/xbmc/peripherals/addons/PeripheralAddon.cpp
+++ b/xbmc/peripherals/addons/PeripheralAddon.cpp
@@ -9,6 +9,7 @@
#include "PeripheralAddon.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PeripheralAddonTranslator.h"
#include "addons/addoninfo/AddonInfo.h"
#include "addons/addoninfo/AddonType.h"
diff --git a/xbmc/peripherals/bus/PeripheralBus.cpp b/xbmc/peripherals/bus/PeripheralBus.cpp
index b59ba1dca3..f33b80181b 100644
--- a/xbmc/peripherals/bus/PeripheralBus.cpp
+++ b/xbmc/peripherals/bus/PeripheralBus.cpp
@@ -9,6 +9,7 @@
#include "PeripheralBus.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "guilib/LocalizeStrings.h"
#include "peripherals/Peripherals.h"
#include "peripherals/devices/Peripheral.h"
diff --git a/xbmc/peripherals/dialogs/GUIDialogPeripherals.h b/xbmc/peripherals/dialogs/GUIDialogPeripherals.h
index 8a54e01aca..4eedb2e390 100644
--- a/xbmc/peripherals/dialogs/GUIDialogPeripherals.h
+++ b/xbmc/peripherals/dialogs/GUIDialogPeripherals.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "dialogs/GUIDialogSelect.h"
#include "threads/CriticalSection.h"
#include "utils/Observer.h"
diff --git a/xbmc/pictures/GUIDialogPictureInfo.cpp b/xbmc/pictures/GUIDialogPictureInfo.cpp
index 263b48238f..2a4b8cc665 100644
--- a/xbmc/pictures/GUIDialogPictureInfo.cpp
+++ b/xbmc/pictures/GUIDialogPictureInfo.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPictureInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/pictures/GUIViewStatePictures.cpp b/xbmc/pictures/GUIViewStatePictures.cpp
index 47d0cdff7a..5b9ebfd208 100644
--- a/xbmc/pictures/GUIViewStatePictures.cpp
+++ b/xbmc/pictures/GUIViewStatePictures.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStatePictures.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/pictures/GUIWindowPictures.cpp b/xbmc/pictures/GUIWindowPictures.cpp
index fa7ec34ade..b7345526fd 100644
--- a/xbmc/pictures/GUIWindowPictures.cpp
+++ b/xbmc/pictures/GUIWindowPictures.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogPictureInfo.h"
#include "GUIPassword.h"
#include "GUIWindowSlideShow.h"
@@ -40,6 +41,7 @@
#include "utils/Variant.h"
#include "utils/XTimeUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "view/GUIViewState.h"
#define CONTROL_BTNSORTASC 4
@@ -47,6 +49,7 @@
using namespace XFILE;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
using namespace std::chrono_literals;
@@ -294,7 +297,7 @@ bool CGUIWindowPictures::GetDirectory(const std::string &strDirectory, CFileItem
bool CGUIWindowPictures::OnPlayMedia(int iItem, const std::string &player)
{
- if (m_vecItems->Get(iItem)->IsVideo())
+ if (IsVideo(*m_vecItems->Get(iItem)))
return CGUIMediaWindow::OnPlayMedia(iItem);
return ShowPicture(iItem, false);
@@ -327,7 +330,7 @@ bool CGUIWindowPictures::ShowPicture(int iItem, bool startSlideShow)
{
if (!pItem->m_bIsFolder &&
!(URIUtils::IsRAR(pItem->GetPath()) || URIUtils::IsZIP(pItem->GetPath())) &&
- (pItem->IsPicture() || (bShowVideos && pItem->IsVideo())))
+ (pItem->IsPicture() || (bShowVideos && IsVideo(*pItem))))
{
slideShow.Add(pItem.get());
}
diff --git a/xbmc/pictures/GUIWindowSlideShow.cpp b/xbmc/pictures/GUIWindowSlideShow.cpp
index b70745342e..4a47726dc8 100644
--- a/xbmc/pictures/GUIWindowSlideShow.cpp
+++ b/xbmc/pictures/GUIWindowSlideShow.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowSlideShow.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIDialogPictureInfo.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
@@ -42,11 +43,13 @@
#include "utils/Variant.h"
#include "utils/XTimeUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include <memory>
#include <random>
using namespace KODI;
+using namespace KODI::VIDEO;
using namespace MESSAGING;
using namespace XFILE;
using namespace std::chrono_literals;
@@ -293,7 +296,7 @@ void CGUIWindowSlideShow::Add(const CFileItem *picture)
// item without tag; get mimetype then we can tell whether it's video item
item->FillInMimeType();
- if (!item->IsVideo())
+ if (!IsVideo(*item))
// then it is a picture and force tag generation
item->GetPictureInfoTag();
}
@@ -446,13 +449,13 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
{
CLog::Log(LOGERROR, "Error loading the current image {}: {}", m_iCurrentSlide,
m_slides.at(m_iCurrentSlide)->GetPath());
- if (!m_slides.at(m_iCurrentPic)->IsVideo())
+ if (!IsVideo(*m_slides.at(m_iCurrentPic)))
{
// try next if we are in slideshow
CLog::Log(LOGINFO, "set image {} unplayable", m_slides.at(m_iCurrentSlide)->GetPath());
m_slides.at(m_iCurrentSlide)->SetProperty("unplayable", true);
}
- if (m_bLoadNextPic || (bSlideShow && !m_bPause && !m_slides.at(m_iCurrentPic)->IsVideo()))
+ if (m_bLoadNextPic || (bSlideShow && !m_bPause && !IsVideo(*m_slides.at(m_iCurrentPic))))
{
// change to next item, wait loading.
m_iCurrentSlide = m_iNextSlide;
@@ -467,7 +470,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
CLog::Log(LOGERROR, "Error loading the next image {}: {}", m_iNextSlide,
m_slides.at(m_iNextSlide)->GetPath());
// load next image failed, then skip to load next of next if next is not video.
- if (!m_slides.at(m_iNextSlide)->IsVideo())
+ if (!IsVideo(*m_slides.at(m_iNextSlide)))
{
CLog::Log(LOGINFO, "set image {} unplayable", m_slides.at(m_iNextSlide)->GetPath());
m_slides.at(m_iNextSlide)->SetProperty("unplayable", true);
@@ -502,7 +505,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
std::string picturePath = GetPicturePath(item.get());
if (!picturePath.empty())
{
- if (item->IsVideo())
+ if (IsVideo(*item))
CLog::Log(LOGDEBUG, "Loading the thumb {} for current video {}: {}", picturePath,
m_iCurrentSlide, item->GetPath());
else
@@ -532,9 +535,9 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
m_iLastFailedNextSlide = -1;
CFileItemPtr item = m_slides.at(m_iNextSlide);
std::string picturePath = GetPicturePath(item.get());
- if (!picturePath.empty() && (!item->IsVideo() || !m_bSlideShow || m_bPause))
+ if (!picturePath.empty() && (!IsVideo(*item) || !m_bSlideShow || m_bPause))
{
- if (item->IsVideo())
+ if (IsVideo(*item))
CLog::Log(LOGDEBUG, "Loading the thumb {} for next video {}: {}", picturePath, m_iNextSlide,
item->GetPath());
else
@@ -548,7 +551,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
}
}
- bool bPlayVideo = m_slides.at(m_iCurrentSlide)->IsVideo() && m_iVideoSlide != m_iCurrentSlide;
+ bool bPlayVideo = IsVideo(*m_slides.at(m_iCurrentSlide)) && m_iVideoSlide != m_iCurrentSlide;
if (bPlayVideo)
bSlideShow = false;
@@ -577,7 +580,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
// render the next image
if (m_Image[m_iCurrentPic]->DrawNextImage())
{
- if (m_bSlideShow && !m_bPause && m_slides.at(m_iNextSlide)->IsVideo())
+ if (m_bSlideShow && !m_bPause && IsVideo(*m_slides.at(m_iNextSlide)))
{
// do not show thumb of video when playing slideshow
}
@@ -599,7 +602,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
m_Image[1 - m_iCurrentPic]->SetTransitionTime(0,
m_Image[m_iCurrentPic]->GetTransitionTime(1));
m_Image[1 - m_iCurrentPic]->Pause(!m_bSlideShow || m_bPause ||
- m_slides.at(m_iNextSlide)->IsVideo());
+ IsVideo(*m_slides.at(m_iNextSlide)));
m_Image[1 - m_iCurrentPic]->Process(currentTime, regions);
}
else // next pic isn't loaded. We should hang around if it is in progress
@@ -650,7 +653,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
m_iCurrentSlide = m_iNextSlide;
m_iNextSlide = GetNextSlide();
- bPlayVideo = m_slides.at(m_iCurrentSlide)->IsVideo() && m_iVideoSlide != m_iCurrentSlide;
+ bPlayVideo = IsVideo(*m_slides.at(m_iCurrentSlide)) && m_iVideoSlide != m_iCurrentSlide;
}
AnnouncePlayerPlay(m_slides.at(m_iCurrentSlide));
@@ -666,7 +669,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re
CServiceBroker::GetGUI()->GetInfoManager().GetInfoProviders().GetPicturesInfoProvider().SetCurrentSlide(m_slides.at(m_iCurrentSlide).get());
RenderPause();
- if (m_slides.at(m_iCurrentSlide)->IsVideo() && appPlayer && appPlayer->IsRenderingGuiLayer())
+ if (IsVideo(*m_slides.at(m_iCurrentSlide)) && appPlayer && appPlayer->IsRenderingGuiLayer())
{
MarkDirtyRegion();
}
@@ -682,7 +685,7 @@ void CGUIWindowSlideShow::Render()
CGraphicContext& gfxCtx = CServiceBroker::GetWinSystem()->GetGfxContext();
gfxCtx.Clear(0xff000000);
- if (m_slides.at(m_iCurrentSlide)->IsVideo())
+ if (IsVideo(*m_slides.at(m_iCurrentSlide)))
{
gfxCtx.SetViewWindow(0, 0, m_coordsRes.iWidth, m_coordsRes.iHeight);
gfxCtx.SetRenderingResolution(gfxCtx.GetVideoResolution(), false);
@@ -722,7 +725,7 @@ void CGUIWindowSlideShow::Render()
void CGUIWindowSlideShow::RenderEx()
{
- if (m_slides.at(m_iCurrentSlide)->IsVideo())
+ if (IsVideo(*m_slides.at(m_iCurrentSlide)))
{
auto& components = CServiceBroker::GetAppComponents();
const auto appPlayer = components.GetComponent<CApplicationPlayer>();
@@ -883,7 +886,7 @@ bool CGUIWindowSlideShow::OnAction(const CAction &action)
case ACTION_PLAYER_PLAY:
if (m_slides.size() == 0)
break;
- if (m_slides.at(m_iCurrentSlide)->IsVideo())
+ if (IsVideo(*m_slides.at(m_iCurrentSlide)))
{
if (!m_bPlayingVideo)
{
@@ -1169,7 +1172,7 @@ void CGUIWindowSlideShow::Move(float fX, float fY)
bool CGUIWindowSlideShow::PlayVideo()
{
CFileItemPtr item = m_slides.at(m_iCurrentSlide);
- if (!item || !item->IsVideo())
+ if (!item || !IsVideo(*item))
return false;
CLog::Log(LOGDEBUG, "Playing current video slide {}", item->GetPath());
m_bPlayingVideo = true;
@@ -1189,7 +1192,7 @@ bool CGUIWindowSlideShow::PlayVideo()
CSlideShowPic::DISPLAY_EFFECT CGUIWindowSlideShow::GetDisplayEffect(int iSlideNumber) const
{
- if (m_bSlideShow && !m_bPause && !m_slides.at(iSlideNumber)->IsVideo())
+ if (m_bSlideShow && !m_bPause && !IsVideo(*m_slides.at(iSlideNumber)))
return CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_SLIDESHOW_DISPLAYEFFECTS) ? CSlideShowPic::EFFECT_RANDOM : CSlideShowPic::EFFECT_NONE;
else
return CSlideShowPic::EFFECT_NO_TIMEOUT;
@@ -1376,7 +1379,7 @@ void CGUIWindowSlideShow::GetCheckedSize(float width, float height, int &maxWidt
std::string CGUIWindowSlideShow::GetPicturePath(CFileItem *item)
{
- bool isVideo = item->IsVideo();
+ bool isVideo = IsVideo(*item);
std::string picturePath = item->GetDynPath();
if (isVideo)
{
diff --git a/xbmc/pictures/PictureFolderImageFileLoader.cpp b/xbmc/pictures/PictureFolderImageFileLoader.cpp
index 1eb58f21b0..b80749b086 100644
--- a/xbmc/pictures/PictureFolderImageFileLoader.cpp
+++ b/xbmc/pictures/PictureFolderImageFileLoader.cpp
@@ -9,6 +9,7 @@
#include "PictureFolderImageFileLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "Picture.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
diff --git a/xbmc/pictures/PictureInfoLoader.cpp b/xbmc/pictures/PictureInfoLoader.cpp
index 81b8cfac92..507834e5bd 100644
--- a/xbmc/pictures/PictureInfoLoader.cpp
+++ b/xbmc/pictures/PictureInfoLoader.cpp
@@ -9,10 +9,15 @@
#include "PictureInfoLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PictureInfoTag.h"
#include "ServiceBroker.h"
+#include "network/NetworkFileItemClassify.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
+#include "video/VideoFileItemClassify.h"
+
+using namespace KODI;
CPictureInfoLoader::CPictureInfoLoader()
{
@@ -50,7 +55,8 @@ bool CPictureInfoLoader::LoadItem(CFileItem* pItem)
bool CPictureInfoLoader::LoadItemCached(CFileItem* pItem)
{
- if (!pItem->IsPicture() || pItem->IsZIP() || pItem->IsRAR() || pItem->IsCBR() || pItem->IsCBZ() || pItem->IsInternetStream() || pItem->IsVideo())
+ if (!pItem->IsPicture() || pItem->IsZIP() || pItem->IsRAR() || pItem->IsCBR() || pItem->IsCBZ() ||
+ NETWORK::IsInternetStream(*pItem) || VIDEO::IsVideo(*pItem))
return false;
if (pItem->HasPictureInfoTag())
@@ -73,7 +79,8 @@ bool CPictureInfoLoader::LoadItemLookup(CFileItem* pItem)
if (m_pProgressCallback && !pItem->m_bIsFolder)
m_pProgressCallback->SetProgressAdvance();
- if (!pItem->IsPicture() || pItem->IsZIP() || pItem->IsRAR() || pItem->IsCBR() || pItem->IsCBZ() || pItem->IsInternetStream() || pItem->IsVideo())
+ if (!pItem->IsPicture() || pItem->IsZIP() || pItem->IsRAR() || pItem->IsCBR() || pItem->IsCBZ() ||
+ NETWORK::IsInternetStream(*pItem) || VIDEO::IsVideo(*pItem))
return false;
if (pItem->HasPictureInfoTag())
diff --git a/xbmc/pictures/PictureThumbLoader.cpp b/xbmc/pictures/PictureThumbLoader.cpp
index 97114e304e..f223a3ba60 100644
--- a/xbmc/pictures/PictureThumbLoader.cpp
+++ b/xbmc/pictures/PictureThumbLoader.cpp
@@ -9,6 +9,7 @@
#include "PictureThumbLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "Picture.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
@@ -23,8 +24,10 @@
#include "utils/FileExtensionProvider.h"
#include "utils/FileUtils.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoThumbLoader.h"
+using namespace KODI::VIDEO;
using namespace XFILE;
CPictureThumbLoader::CPictureThumbLoader() : CThumbLoader()
@@ -78,10 +81,11 @@ bool CPictureThumbLoader::LoadItemCached(CFileItem* pItem)
{ // load the thumb from the image file
thumb = pItem->HasArt("thumb") ? pItem->GetArt("thumb") : CTextureUtils::GetWrappedThumbURL(pItem->GetPath());
}
- else if (pItem->IsVideo() && !pItem->IsZIP() && !pItem->IsRAR() && !pItem->IsCBZ() && !pItem->IsCBR() && !pItem->IsPlayList())
+ else if (IsVideo(*pItem) && !pItem->IsZIP() && !pItem->IsRAR() && !pItem->IsCBZ() &&
+ !pItem->IsCBR() && !pItem->IsPlayList())
{ // video
CVideoThumbLoader loader;
- loader.LoadItemCached(pItem);
+ loader.LoadItem(pItem);
}
else if (!pItem->HasArt("thumb"))
{ // folder, zip, cbz, rar, cbr, playlist may have a previously cached image
diff --git a/xbmc/pictures/SlideShowPicture.cpp b/xbmc/pictures/SlideShowPicture.cpp
index 005d740654..fd0fd2cdd6 100644
--- a/xbmc/pictures/SlideShowPicture.cpp
+++ b/xbmc/pictures/SlideShowPicture.cpp
@@ -727,6 +727,9 @@ void CSlideShowPic::Move(float fDeltaX, float fDeltaY)
void CSlideShowPic::Render()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
std::unique_lock<CCriticalSection> lock(m_textureAccess);
Render(m_ax, m_ay, m_pImage.get(), (m_alpha << 24) | 0xFFFFFF);
diff --git a/xbmc/pictures/SlideShowPictureGL.cpp b/xbmc/pictures/SlideShowPictureGL.cpp
index 5749bff2c1..ee7ddb2a9f 100644
--- a/xbmc/pictures/SlideShowPictureGL.cpp
+++ b/xbmc/pictures/SlideShowPictureGL.cpp
@@ -81,6 +81,7 @@ void CSlideShowPicGL::Render(float* x, float* y, CTexture* pTexture, UTILS::COLO
GLint posLoc = renderSystem->ShaderGetPos();
GLint tex0Loc = renderSystem->ShaderGetCoord0();
GLint uniColLoc = renderSystem->ShaderGetUniCol();
+ GLint depthLoc = renderSystem->ShaderGetDepth();
glGenBuffers(1, &vertexVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
@@ -102,6 +103,7 @@ void CSlideShowPicGL::Render(float* x, float* y, CTexture* pTexture, UTILS::COLO
glUniform4f(uniColLoc, (colour[0] / 255.0f), (colour[1] / 255.0f), (colour[2] / 255.0f),
(colour[3] / 255.0f));
+ glUniform1f(depthLoc, -1.0f);
glGenBuffers(1, &indexVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
diff --git a/xbmc/pictures/SlideShowPictureGLES.cpp b/xbmc/pictures/SlideShowPictureGLES.cpp
index ce0200616d..de41bbe77f 100644
--- a/xbmc/pictures/SlideShowPictureGLES.cpp
+++ b/xbmc/pictures/SlideShowPictureGLES.cpp
@@ -53,6 +53,7 @@ void CSlideShowPicGLES::Render(float* x, float* y, CTexture* pTexture, UTILS::CO
GLint posLoc = renderSystem->GUIShaderGetPos();
GLint tex0Loc = renderSystem->GUIShaderGetCoord0();
GLint uniColLoc = renderSystem->GUIShaderGetUniCol();
+ GLint depthLoc = renderSystem->GUIShaderGetDepth();
glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, 0, ver);
glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, 0, tex);
@@ -88,6 +89,7 @@ void CSlideShowPicGLES::Render(float* x, float* y, CTexture* pTexture, UTILS::CO
glUniform4f(uniColLoc, (col[0] / 255.0f), (col[1] / 255.0f), (col[2] / 255.0f),
(col[3] / 255.0f));
+ glUniform1f(depthLoc, -1.0f);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
glDisableVertexAttribArray(posLoc);
diff --git a/xbmc/platform/android/activity/CMakeLists.txt b/xbmc/platform/android/activity/CMakeLists.txt
index fddcec8525..55714df929 100644
--- a/xbmc/platform/android/activity/CMakeLists.txt
+++ b/xbmc/platform/android/activity/CMakeLists.txt
@@ -16,6 +16,7 @@ set(SOURCES android_main.cpp
JNIXBMCNsdManagerResolveListener.cpp
JNIXBMCJsonHandler.cpp
JNIXBMCFile.cpp
+ JNIXBMCTextureCache.cpp
JNIXBMCURIUtils.cpp
JNIXBMCDisplayManagerDisplayListener.cpp
JNIXBMCSpeechRecognitionListener.cpp
@@ -42,6 +43,7 @@ set(HEADERS AndroidFeatures.h
JNIXBMCNsdManagerResolveListener.h
JNIXBMCJsonHandler.h
JNIXBMCFile.h
+ JNIXBMCTextureCache.h
JNIXBMCURIUtils.h
JNIXBMCDisplayManagerDisplayListener.h
JNIXBMCSpeechRecognitionListener.h
diff --git a/xbmc/platform/android/activity/JNIXBMCTextureCache.cpp b/xbmc/platform/android/activity/JNIXBMCTextureCache.cpp
new file mode 100644
index 0000000000..bacb4a826d
--- /dev/null
+++ b/xbmc/platform/android/activity/JNIXBMCTextureCache.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "JNIXBMCTextureCache.h"
+
+#include "CompileInfo.h"
+#include "TextureCache.h"
+
+#include <androidjni/Context.h>
+#include <androidjni/jutils-details.hpp>
+
+using namespace jni;
+
+static std::string s_className = std::string(CCompileInfo::GetClass()) + "/XBMCTextureCache";
+
+void CJNIXBMCTextureCache::RegisterNatives(JNIEnv* env)
+{
+ jclass cClass = env->FindClass(s_className.c_str());
+ if (cClass)
+ {
+ JNINativeMethod methods[] = {
+ {"_unwrapImageURL", "(Ljava/lang/String;)Ljava/lang/String;",
+ (void*)&CJNIXBMCTextureCache::_unwrapImageURL},
+ };
+
+ env->RegisterNatives(cClass, methods, sizeof(methods) / sizeof(methods[0]));
+ }
+}
+
+jstring CJNIXBMCTextureCache::_unwrapImageURL(JNIEnv* env, jobject thiz, jstring image)
+{
+ std::string strImage = jcast<std::string>(jhstring::fromJNI(image));
+ std::string responseData = CTextureUtils::UnwrapImageURL(strImage);
+
+ jstring jres = env->NewStringUTF(responseData.c_str());
+ return jres;
+}
diff --git a/xbmc/platform/android/activity/JNIXBMCTextureCache.h b/xbmc/platform/android/activity/JNIXBMCTextureCache.h
new file mode 100644
index 0000000000..92da6e91d5
--- /dev/null
+++ b/xbmc/platform/android/activity/JNIXBMCTextureCache.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include <androidjni/JNIBase.h>
+
+namespace jni
+{
+
+class CJNIXBMCTextureCache : public CJNIBase
+{
+public:
+ CJNIXBMCTextureCache(const jni::jhobject& object) : CJNIBase(object) {}
+
+ static void RegisterNatives(JNIEnv* env);
+
+protected:
+ ~CJNIXBMCTextureCache() override = default;
+
+ static jstring _unwrapImageURL(JNIEnv* env, jobject thiz, jstring image);
+};
+
+} // namespace jni
diff --git a/xbmc/platform/android/activity/XBMCApp.cpp b/xbmc/platform/android/activity/XBMCApp.cpp
index a912c1da0e..437c7371d9 100644
--- a/xbmc/platform/android/activity/XBMCApp.cpp
+++ b/xbmc/platform/android/activity/XBMCApp.cpp
@@ -47,6 +47,7 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "windowing/GraphicContext.h"
#include "windowing/WinEvents.h"
@@ -117,6 +118,7 @@
using namespace ANNOUNCEMENT;
using namespace jni;
using namespace KODI::GUILIB;
+using namespace KODI::VIDEO;
using namespace std::chrono_literals;
std::shared_ptr<CNativeWindow> CNativeWindow::CreateFromSurface(CJNISurfaceHolder holder)
@@ -213,14 +215,23 @@ void CXBMCApp::Announce(ANNOUNCEMENT::AnnouncementFlag flag,
else if (message == "OnStop")
OnPlayBackStopped();
else if (message == "OnSeek")
+ {
+ m_mediaSessionUpdated = false;
UpdateSessionState();
+ }
else if (message == "OnSpeedChanged")
+ {
+ m_mediaSessionUpdated = false;
UpdateSessionState();
+ }
}
else if (flag & Info)
{
if (message == "OnChanged")
+ {
+ m_mediaSessionUpdated = false;
UpdateSessionMetadata();
+ }
}
}
@@ -676,29 +687,6 @@ bool CXBMCApp::SetBuffersGeometry(int width, int height, int format)
return false;
}
-void CXBMCApp::SetRefreshRateCallback(void* rateVariant)
-{
- CVariant* rateV = static_cast<CVariant*>(rateVariant);
- float rate = rateV->asFloat();
- delete rateV;
-
- CJNIWindow window = getWindow();
- if (window)
- {
- CJNIWindowManagerLayoutParams params = window.getAttributes();
- if (fabs(params.getpreferredRefreshRate() - rate) > 0.001f)
- {
- params.setpreferredRefreshRate(rate);
- if (params.getpreferredRefreshRate() > 0.0f)
- {
- window.setAttributes(params);
- return;
- }
- }
- }
- CXBMCApp::Get().m_displayChangeEvent.Set();
-}
-
void CXBMCApp::SetDisplayModeCallback(void* modeVariant)
{
CVariant* modeV = static_cast<CVariant*>(modeVariant);
@@ -719,30 +707,6 @@ void CXBMCApp::SetDisplayModeCallback(void* modeVariant)
CXBMCApp::Get().m_displayChangeEvent.Set();
}
-void CXBMCApp::SetRefreshRate(float rate)
-{
- if (rate < 1.0f)
- return;
-
- CJNIWindow window = getWindow();
- if (window)
- {
- CJNIWindowManagerLayoutParams params = window.getAttributes();
- if (fabs(params.getpreferredRefreshRate() - rate) <= 0.001f)
- return;
- }
-
- m_refreshRate = rate;
- m_displayChangeEvent.Reset();
-
- if (m_hdmiSource)
- dynamic_cast<CWinSystemAndroid*>(CServiceBroker::GetWinSystem())->InitiateModeChange();
-
- CVariant *variant = new CVariant(rate);
- runNativeOnUiThread(SetRefreshRateCallback, variant);
- m_displayChangeEvent.Wait(5000ms);
-}
-
void CXBMCApp::SetDisplayMode(int mode, float rate)
{
if (mode < 1.0)
@@ -884,6 +848,7 @@ void CXBMCApp::UpdateSessionState()
float speed = 0.0;
const auto& components = CServiceBroker::GetAppComponents();
const auto appPlayer = components.GetComponent<CApplicationPlayer>();
+ uint32_t oldPlayState = m_playback_state;
if (m_playback_state != PLAYBACK_STATE_STOPPED)
{
if (appPlayer->HasVideo())
@@ -907,9 +872,13 @@ void CXBMCApp::UpdateSessionState()
else
state = CJNIPlaybackState::STATE_STOPPED;
- builder.setState(state, pos, speed, CJNISystemClock::elapsedRealtime())
- .setActions(CJNIPlaybackState::PLAYBACK_POSITION_UNKNOWN);
- m_mediaSession->updatePlaybackState(builder.build());
+ if ((oldPlayState != m_playback_state) || !m_mediaSessionUpdated)
+ {
+ builder.setState(state, pos, speed, CJNISystemClock::elapsedRealtime())
+ .setActions(CJNIPlaybackState::PLAYBACK_POSITION_UNKNOWN);
+ m_mediaSession->updatePlaybackState(builder.build());
+ m_mediaSessionUpdated = true;
+ }
}
void CXBMCApp::OnPlayBackStarted()
@@ -927,6 +896,7 @@ void CXBMCApp::OnPlayBackStarted()
m_playback_state |= PLAYBACK_STATE_CANNOT_PAUSE;
m_mediaSession->activate(true);
+ m_mediaSessionUpdated = false;
UpdateSessionState();
CJNIIntent intent(ACTION_XBMC_RESUME, CJNIURI::EMPTY, *this, get_class(CJNIContext::get_raw()));
@@ -943,6 +913,7 @@ void CXBMCApp::OnPlayBackPaused()
CLog::Log(LOGDEBUG, "{}", __PRETTY_FUNCTION__);
m_playback_state &= ~PLAYBACK_STATE_PLAYING;
+ m_mediaSessionUpdated = false;
UpdateSessionState();
RequestVisibleBehind(false);
@@ -956,6 +927,7 @@ void CXBMCApp::OnPlayBackStopped()
m_playback_state = PLAYBACK_STATE_STOPPED;
UpdateSessionState();
m_mediaSession->activate(false);
+ m_mediaSessionUpdated = false;
RequestVisibleBehind(false);
CAndroidKey::SetHandleMediaKeys(true);
@@ -976,7 +948,8 @@ std::vector<int> CXBMCApp::GetInputDeviceIds()
void CXBMCApp::ProcessSlow()
{
- if ((m_playback_state & PLAYBACK_STATE_PLAYING) && m_mediaSession->isActive())
+ if ((m_playback_state & PLAYBACK_STATE_PLAYING) && !m_mediaSessionUpdated &&
+ m_mediaSession->isActive())
UpdateSessionState();
}
@@ -1480,7 +1453,7 @@ void CXBMCApp::onNewIntent(CJNIIntent intent)
else
{
CFileItem* item = new CFileItem(targetFile, false);
- if (item->IsVideoDb())
+ if (IsVideoDb(*item))
{
*(item->GetVideoInfoTag()) = XFILE::CVideoDatabaseFile::GetVideoTag(CURL(item->GetPath()));
item->SetPath(item->GetVideoInfoTag()->m_strFileNameAndPath);
diff --git a/xbmc/platform/android/activity/XBMCApp.h b/xbmc/platform/android/activity/XBMCApp.h
index 305c8513c0..2e2d8670a0 100644
--- a/xbmc/platform/android/activity/XBMCApp.h
+++ b/xbmc/platform/android/activity/XBMCApp.h
@@ -179,7 +179,6 @@ public:
static float GetSystemVolume();
static void SetSystemVolume(float percent);
- void SetRefreshRate(float rate);
void SetDisplayMode(int mode, float rate);
int GetDPI() const;
@@ -242,7 +241,6 @@ private:
void run();
void stop();
void SetupEnv();
- static void SetRefreshRateCallback(void* rateVariant);
static void SetDisplayModeCallback(void* modeVariant);
static void KeepScreenOnCallback(void* onVariant);
@@ -258,6 +256,7 @@ private:
bool m_wakeUp{false};
bool m_aeReset{false};
bool m_hdmiPlugged{true};
+ bool m_mediaSessionUpdated{false};
IInputDeviceCallbacks* m_inputDeviceCallbacks{nullptr};
IInputDeviceEventHandler* m_inputDeviceEventHandler{nullptr};
bool m_hasReqVisible{false};
diff --git a/xbmc/platform/android/activity/android_main.cpp b/xbmc/platform/android/activity/android_main.cpp
index 3970e78f49..a934b6ee1c 100644
--- a/xbmc/platform/android/activity/android_main.cpp
+++ b/xbmc/platform/android/activity/android_main.cpp
@@ -23,6 +23,7 @@
#include "platform/android/activity/JNIXBMCNsdManagerResolveListener.h"
#include "platform/android/activity/JNIXBMCSpeechRecognitionListener.h"
#include "platform/android/activity/JNIXBMCSurfaceTextureOnFrameAvailableListener.h"
+#include "platform/android/activity/JNIXBMCTextureCache.h"
#include "platform/android/activity/JNIXBMCURIUtils.h"
#include "platform/android/activity/JNIXBMCVideoView.h"
@@ -127,6 +128,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
CJNIXBMCNsdManagerResolveListener::RegisterNatives(env);
CJNIXBMCSpeechRecognitionListener::RegisterNatives(env);
CJNIXBMCSurfaceTextureOnFrameAvailableListener::RegisterNatives(env);
+ CJNIXBMCTextureCache::RegisterNatives(env);
CJNIXBMCURIUtils::RegisterNatives(env);
CJNIXBMCVideoView::RegisterNatives(env);
diff --git a/xbmc/platform/android/filesystem/APKDirectory.cpp b/xbmc/platform/android/filesystem/APKDirectory.cpp
index df890bfed6..4cdcf5c529 100644
--- a/xbmc/platform/android/filesystem/APKDirectory.cpp
+++ b/xbmc/platform/android/filesystem/APKDirectory.cpp
@@ -10,6 +10,7 @@
#include "APKFile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "utils/CharsetConverter.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/platform/android/filesystem/AndroidAppDirectory.cpp b/xbmc/platform/android/filesystem/AndroidAppDirectory.cpp
index c2af2aae47..132f666618 100644
--- a/xbmc/platform/android/filesystem/AndroidAppDirectory.cpp
+++ b/xbmc/platform/android/filesystem/AndroidAppDirectory.cpp
@@ -10,6 +10,7 @@
#include "CompileInfo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/File.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/platform/darwin/tvos/TVOSTopShelf.mm b/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
index 94690fea00..fb4770f5cd 100644
--- a/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
+++ b/xbmc/platform/darwin/tvos/TVOSTopShelf.mm
@@ -10,6 +10,7 @@
#include "DatabaseManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "application/Application.h"
#include "filesystem/File.h"
diff --git a/xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp b/xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp
index 0463943505..d0d25df5d6 100644
--- a/xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp
+++ b/xbmc/platform/darwin/tvos/filesystem/TVOSDirectory.cpp
@@ -21,6 +21,7 @@
#include "TVOSDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/SpecialProtocol.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/platform/freebsd/PlatformFreebsd.cpp b/xbmc/platform/freebsd/PlatformFreebsd.cpp
index c949a339cb..6ab3f46ed2 100644
--- a/xbmc/platform/freebsd/PlatformFreebsd.cpp
+++ b/xbmc/platform/freebsd/PlatformFreebsd.cpp
@@ -89,7 +89,7 @@ bool CPlatformFreebsd::InitStageOne()
}
else if (sink == "pulseaudio")
{
- OPTIONALS::PulseAudioRegister();
+ OPTIONALS::PulseAudioRegister(true);
}
else if (sink == "oss")
{
@@ -102,11 +102,11 @@ bool CPlatformFreebsd::InitStageOne()
else if (sink == "alsa+pulseaudio")
{
OPTIONALS::ALSARegister();
- OPTIONALS::PulseAudioRegister();
+ OPTIONALS::PulseAudioRegister(true);
}
else
{
- if (!OPTIONALS::PulseAudioRegister())
+ if (!OPTIONALS::PulseAudioRegister(false))
{
if (!OPTIONALS::ALSARegister())
{
diff --git a/xbmc/platform/linux/OptionalsReg.cpp b/xbmc/platform/linux/OptionalsReg.cpp
index 82fb176d1d..3992f2a0d0 100644
--- a/xbmc/platform/linux/OptionalsReg.cpp
+++ b/xbmc/platform/linux/OptionalsReg.cpp
@@ -33,13 +33,13 @@ bool OPTIONALS::ALSARegister()
#ifdef HAS_PULSEAUDIO
#include "cores/AudioEngine/Sinks/AESinkPULSE.h"
-bool OPTIONALS::PulseAudioRegister()
+bool OPTIONALS::PulseAudioRegister(bool allowPipeWireCompatServer)
{
- bool ret = CAESinkPULSE::Register();
+ bool ret = CAESinkPULSE::Register(allowPipeWireCompatServer);
return ret;
}
#else
-bool OPTIONALS::PulseAudioRegister()
+bool OPTIONALS::PulseAudioRegister(bool)
{
return false;
}
diff --git a/xbmc/platform/linux/OptionalsReg.h b/xbmc/platform/linux/OptionalsReg.h
index 75fdb6ae62..3a777b7003 100644
--- a/xbmc/platform/linux/OptionalsReg.h
+++ b/xbmc/platform/linux/OptionalsReg.h
@@ -23,7 +23,7 @@ bool ALSARegister();
namespace OPTIONALS
{
-bool PulseAudioRegister();
+bool PulseAudioRegister(bool allowPipeWireCompatServer);
}
//-----------------------------------------------------------------------------
diff --git a/xbmc/platform/linux/PlatformLinux.cpp b/xbmc/platform/linux/PlatformLinux.cpp
index 6be5163883..e01f8216bf 100644
--- a/xbmc/platform/linux/PlatformLinux.cpp
+++ b/xbmc/platform/linux/PlatformLinux.cpp
@@ -101,7 +101,7 @@ bool CPlatformLinux::InitStageOne()
}
else if (sink == "pulseaudio")
{
- OPTIONALS::PulseAudioRegister();
+ OPTIONALS::PulseAudioRegister(true);
}
else if (sink == "pipewire")
{
@@ -114,13 +114,13 @@ bool CPlatformLinux::InitStageOne()
else if (sink == "alsa+pulseaudio")
{
OPTIONALS::ALSARegister();
- OPTIONALS::PulseAudioRegister();
+ OPTIONALS::PulseAudioRegister(true);
}
else
{
- if (!OPTIONALS::PipewireRegister())
+ if (!OPTIONALS::PulseAudioRegister(false))
{
- if (!OPTIONALS::PulseAudioRegister())
+ if (!OPTIONALS::PipewireRegister())
{
if (!OPTIONALS::ALSARegister())
{
diff --git a/xbmc/platform/posix/filesystem/PosixDirectory.cpp b/xbmc/platform/posix/filesystem/PosixDirectory.cpp
index 6685c0e1db..761b8d53b4 100644
--- a/xbmc/platform/posix/filesystem/PosixDirectory.cpp
+++ b/xbmc/platform/posix/filesystem/PosixDirectory.cpp
@@ -9,6 +9,7 @@
#include "PosixDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/AliasShortcutUtils.h"
#include "utils/CharsetConverter.h"
diff --git a/xbmc/platform/posix/filesystem/SMBDirectory.cpp b/xbmc/platform/posix/filesystem/SMBDirectory.cpp
index e2305afb4a..12fe62683e 100644
--- a/xbmc/platform/posix/filesystem/SMBDirectory.cpp
+++ b/xbmc/platform/posix/filesystem/SMBDirectory.cpp
@@ -20,6 +20,7 @@
#include "SMBDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PasswordManager.h"
#include "ServiceBroker.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp b/xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp
index 8bab0aa9e9..c2f247da10 100644
--- a/xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp
+++ b/xbmc/platform/posix/filesystem/SMBWSDiscovery.cpp
@@ -9,6 +9,7 @@
#include "SMBWSDiscovery.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "network/IWSDiscovery.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/platform/posix/filesystem/SMBWSDiscoveryListener.cpp b/xbmc/platform/posix/filesystem/SMBWSDiscoveryListener.cpp
index d42c19bb2c..142974591b 100644
--- a/xbmc/platform/posix/filesystem/SMBWSDiscoveryListener.cpp
+++ b/xbmc/platform/posix/filesystem/SMBWSDiscoveryListener.cpp
@@ -17,6 +17,7 @@
#include "platform/posix/filesystem/SMBWSDiscovery.h"
+#include <algorithm>
#include <array>
#include <chrono>
#include <mutex>
diff --git a/xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp b/xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp
index bba7074400..4bd0a0db4c 100644
--- a/xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp
+++ b/xbmc/platform/win10/filesystem/WinLibraryDirectory.cpp
@@ -9,6 +9,7 @@
#include "WinLibraryDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/platform/win32/filesystem/Win32Directory.cpp b/xbmc/platform/win32/filesystem/Win32Directory.cpp
index 5e4050fdd4..3d06e8dfbc 100644
--- a/xbmc/platform/win32/filesystem/Win32Directory.cpp
+++ b/xbmc/platform/win32/filesystem/Win32Directory.cpp
@@ -9,6 +9,7 @@
#include "Win32Directory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "utils/CharsetConverter.h"
#include "utils/SystemInfo.h"
diff --git a/xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp b/xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp
index 2075f957c8..c227351ad4 100644
--- a/xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp
+++ b/xbmc/platform/win32/filesystem/Win32SMBDirectory.cpp
@@ -9,6 +9,7 @@
#include "Win32SMBDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PasswordManager.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/platform/win32/network/NetworkWin32.cpp b/xbmc/platform/win32/network/NetworkWin32.cpp
index f87056134b..2dee878a9d 100644
--- a/xbmc/platform/win32/network/NetworkWin32.cpp
+++ b/xbmc/platform/win32/network/NetworkWin32.cpp
@@ -248,7 +248,7 @@ bool CNetworkWin32::PingHost(const struct sockaddr& host, unsigned int timeout_m
bool CNetworkInterfaceWin32::GetHostMacAddress(unsigned long host, std::string& mac) const
{
- struct sockaddr sockHost;
+ sockaddr sockHost{};
sockHost.sa_family = AF_INET;
reinterpret_cast<struct sockaddr_in&>(sockHost).sin_addr.S_un.S_addr = host;
return GetHostMacAddress(&sockHost, mac);
@@ -260,33 +260,38 @@ bool CNetworkInterfaceWin32::GetHostMacAddress(struct sockaddr* host, std::strin
if (GetBestInterfaceEx(host, &InterfaceIndex) != NO_ERROR)
return false;
- NET_LUID luid = {};
+ NET_LUID luid{};
if (ConvertInterfaceIndexToLuid(InterfaceIndex, &luid) != NO_ERROR)
return false;
- MIB_IPNET_ROW2 neighborIp = {};
+ MIB_IPNET_ROW2 neighborIp{};
neighborIp.InterfaceLuid = luid;
- neighborIp.InterfaceIndex;
- neighborIp.Address.si_family = host->sa_family;
switch (host->sa_family)
{
case AF_INET:
- neighborIp.Address.Ipv4 = reinterpret_cast<const struct sockaddr_in&>(host);
+ memcpy(&neighborIp.Address.Ipv4, host, sizeof(sockaddr_in));
break;
case AF_INET6:
- neighborIp.Address.Ipv6 = reinterpret_cast<const struct sockaddr_in6&>(host);
+ memcpy(&neighborIp.Address.Ipv6, host, sizeof(sockaddr_in6));
break;
default:
return false;
}
- DWORD dwRetVal = ResolveIpNetEntry2(&neighborIp, nullptr);
+ DWORD dwRetVal = GetIpNetEntry2(&neighborIp);
+
+ if (dwRetVal != NO_ERROR)
+ {
+ CLog::LogF(LOGDEBUG, "Host not found in the cache (error {}), resolve the address.", dwRetVal);
+ dwRetVal = ResolveIpNetEntry2(&neighborIp, nullptr);
+ }
if (dwRetVal != NO_ERROR)
{
CLog::LogF(LOGERROR, "ResolveIpNetEntry2 failed with error ({})", dwRetVal);
return false;
}
+
if (neighborIp.PhysicalAddressLength < MAC_LENGTH)
{
CLog::LogF(LOGERROR,
diff --git a/xbmc/playlists/PlayList.cpp b/xbmc/playlists/PlayList.cpp
index 82031bad2e..8857b818ac 100644
--- a/xbmc/playlists/PlayList.cpp
+++ b/xbmc/playlists/PlayList.cpp
@@ -9,10 +9,12 @@
#include "PlayList.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "PlayListFactory.h"
#include "ServiceBroker.h"
#include "filesystem/File.h"
#include "interfaces/AnnouncementManager.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "utils/Random.h"
#include "utils/StringUtils.h"
@@ -28,7 +30,7 @@
#include <utility>
#include <vector>
-
+using namespace KODI;
using namespace MUSIC_INFO;
using namespace XFILE;
using namespace PLAYLIST;
@@ -350,7 +352,7 @@ int CPlayList::RemoveDVDItems()
while (it != m_vecItems.end() )
{
CFileItemPtr item = *it;
- if ( item->IsCDDA() || item->IsOnDVD() )
+ if (MUSIC::IsCDDA(*item) || item->IsOnDVD())
{
vecFilenames.push_back( item->GetPath() );
}
@@ -506,7 +508,7 @@ void CPlayList::UpdateItem(const CFileItem *item)
const std::string& CPlayList::ResolveURL(const std::shared_ptr<CFileItem>& item) const
{
- if (item->IsMusicDb() && item->HasMusicInfoTag())
+ if (MUSIC::IsMusicDb(*item) && item->HasMusicInfoTag())
return item->GetMusicInfoTag()->GetURL();
else
return item->GetDynPath();
diff --git a/xbmc/playlists/PlayListFactory.cpp b/xbmc/playlists/PlayListFactory.cpp
index dc45bcce2d..4bae13dd27 100644
--- a/xbmc/playlists/PlayListFactory.cpp
+++ b/xbmc/playlists/PlayListFactory.cpp
@@ -9,6 +9,7 @@
#include "PlayListFactory.h"
#include "FileItem.h"
+#include "network/NetworkFileItemClassify.h"
#include "playlists/PlayListB4S.h"
#include "playlists/PlayListM3U.h"
#include "playlists/PlayListPLS.h"
@@ -19,6 +20,7 @@
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
+using namespace KODI;
using namespace PLAYLIST;
CPlayList* CPlayListFactory::Create(const std::string& filename)
@@ -29,7 +31,7 @@ CPlayList* CPlayListFactory::Create(const std::string& filename)
CPlayList* CPlayListFactory::Create(const CFileItem& item)
{
- if (item.IsInternetStream())
+ if (NETWORK::IsInternetStream(item))
{
// Ensure the MIME type has been retrieved for http:// and shout:// streams
if (item.GetMimeType().empty())
@@ -71,7 +73,8 @@ CPlayList* CPlayListFactory::Create(const CFileItem& item)
std::string extension = URIUtils::GetExtension(path);
StringUtils::ToLower(extension);
- if (extension == ".m3u" || (extension == ".m3u8" && !item.IsInternetStream()) || extension == ".strm")
+ if (extension == ".m3u" || (extension == ".m3u8" && !NETWORK::IsInternetStream(item)) ||
+ extension == ".strm")
return new CPlayListM3U();
if (extension == ".pls")
@@ -120,7 +123,7 @@ bool CPlayListFactory::IsPlaylist(const CFileItem& item)
*/
// online m3u8 files are hls:// -- do not treat as playlist
- if (item.IsInternetStream() && item.IsType(".m3u8"))
+ if (NETWORK::IsInternetStream(item) && item.IsType(".m3u8"))
return false;
if(strMimeType == "audio/x-pn-realaudio"
diff --git a/xbmc/playlists/PlayListM3U.cpp b/xbmc/playlists/PlayListM3U.cpp
index 8853a31275..e403c56117 100644
--- a/xbmc/playlists/PlayListM3U.cpp
+++ b/xbmc/playlists/PlayListM3U.cpp
@@ -12,14 +12,17 @@
#include "URL.h"
#include "Util.h"
#include "filesystem/File.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "utils/CharsetConverter.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include <inttypes.h>
+using namespace KODI;
using namespace PLAYLIST;
using namespace XFILE;
@@ -183,9 +186,10 @@ bool CPlayListM3U::Load(const std::string& strFileName)
if (iEndOffset)
lDuration = static_cast<int>(CUtil::ConvertMilliSecsToSecsIntRounded(iEndOffset - iStartOffset));
}
- if (newItem->IsVideo() && !newItem->HasVideoInfoTag()) // File is a video and needs a VideoInfoTag
+ if (VIDEO::IsVideo(*newItem) &&
+ !newItem->HasVideoInfoTag()) // File is a video and needs a VideoInfoTag
newItem->GetVideoInfoTag()->Reset(); // Force VideoInfoTag creation
- if (lDuration && newItem->IsAudio())
+ if (lDuration && MUSIC::IsAudio(*newItem))
newItem->GetMusicInfoTag()->SetDuration(lDuration);
for (auto &prop : properties)
{
diff --git a/xbmc/playlists/PlayListPLS.cpp b/xbmc/playlists/PlayListPLS.cpp
index 369804dba2..29cd4eb1b7 100644
--- a/xbmc/playlists/PlayListPLS.cpp
+++ b/xbmc/playlists/PlayListPLS.cpp
@@ -12,6 +12,7 @@
#include "PlayListFactory.h"
#include "Util.h"
#include "filesystem/File.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "utils/CharsetConverter.h"
#include "utils/StringUtils.h"
@@ -19,6 +20,7 @@
#include "utils/XBMCTinyXML.h"
#include "utils/XMLUtils.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include <iostream>
@@ -26,6 +28,7 @@
#include <string>
#include <vector>
+using namespace KODI;
using namespace XFILE;
using namespace PLAYLIST;
@@ -137,7 +140,7 @@ bool CPlayListPLS::Load(const std::string &strFile)
if (m_vecItems[idx - 1]->GetLabel().empty())
m_vecItems[idx - 1]->SetLabel(URIUtils::GetFileName(strValue));
CFileItem item(strValue, false);
- if (bShoutCast && !item.IsAudio())
+ if (bShoutCast && !MUSIC::IsAudio(item))
strValue.replace(0, 7, "shout://");
strValue = URIUtils::SubstitutePath(strValue);
@@ -272,7 +275,8 @@ bool CPlayListASX::LoadAsxIniInfo(std::istream &stream)
CLog::Log(LOGINFO, "Adding element {}={}", name, value);
CFileItemPtr newItem(new CFileItem(value));
newItem->SetPath(value);
- if (newItem->IsVideo() && !newItem->HasVideoInfoTag()) // File is a video and needs a VideoInfoTag
+ if (VIDEO::IsVideo(*newItem) &&
+ !newItem->HasVideoInfoTag()) // File is a video and needs a VideoInfoTag
newItem->GetVideoInfoTag()->Reset(); // Force VideoInfoTag creation
Add(newItem);
}
diff --git a/xbmc/playlists/SmartPlaylistFileItemListModifier.cpp b/xbmc/playlists/SmartPlaylistFileItemListModifier.cpp
index 7249bb5c0d..443dabcd4e 100644
--- a/xbmc/playlists/SmartPlaylistFileItemListModifier.cpp
+++ b/xbmc/playlists/SmartPlaylistFileItemListModifier.cpp
@@ -9,6 +9,7 @@
#include "SmartPlaylistFileItemListModifier.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "playlists/SmartPlayList.h"
#include "utils/StringUtils.h"
diff --git a/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp b/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp
index dcdf8c47a4..9f455c4a6b 100644
--- a/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp
+++ b/xbmc/profiles/dialogs/GUIDialogProfileSettings.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogProfileSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "Util.h"
diff --git a/xbmc/profiles/windows/GUIWindowSettingsProfile.cpp b/xbmc/profiles/windows/GUIWindowSettingsProfile.cpp
index d3690adb63..503516c0f6 100644
--- a/xbmc/profiles/windows/GUIWindowSettingsProfile.cpp
+++ b/xbmc/profiles/windows/GUIWindowSettingsProfile.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowSettingsProfile.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "dialogs/GUIDialogSelect.h"
diff --git a/xbmc/programs/GUIViewStatePrograms.cpp b/xbmc/programs/GUIViewStatePrograms.cpp
index 05e4cfd978..0b08a42864 100644
--- a/xbmc/programs/GUIViewStatePrograms.cpp
+++ b/xbmc/programs/GUIViewStatePrograms.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStatePrograms.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "guilib/LocalizeStrings.h"
diff --git a/xbmc/programs/GUIWindowPrograms.cpp b/xbmc/programs/GUIWindowPrograms.cpp
index 862bdb2249..7a57f1cc0b 100644
--- a/xbmc/programs/GUIWindowPrograms.cpp
+++ b/xbmc/programs/GUIWindowPrograms.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "Util.h"
diff --git a/xbmc/pvr/PVRChannelGroupImageFileLoader.cpp b/xbmc/pvr/PVRChannelGroupImageFileLoader.cpp
index e539ca55bd..b66ef00902 100644
--- a/xbmc/pvr/PVRChannelGroupImageFileLoader.cpp
+++ b/xbmc/pvr/PVRChannelGroupImageFileLoader.cpp
@@ -9,6 +9,7 @@
#include "PVRChannelGroupImageFileLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/PVRGUIDirectory.h"
#include "guilib/Texture.h"
#include "pictures/Picture.h"
diff --git a/xbmc/pvr/PVRThumbLoader.cpp b/xbmc/pvr/PVRThumbLoader.cpp
index 3f5fa63822..8f41a80b0c 100644
--- a/xbmc/pvr/PVRThumbLoader.cpp
+++ b/xbmc/pvr/PVRThumbLoader.cpp
@@ -9,6 +9,7 @@
#include "PVRThumbLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "pvr/PVRManager.h"
diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp
index d3a8408dc0..98cfe8db2a 100644
--- a/xbmc/pvr/addons/PVRClient.cpp
+++ b/xbmc/pvr/addons/PVRClient.cpp
@@ -421,6 +421,17 @@ const std::string CPVRClient::GetFriendlyName() const
return Name();
}
+std::string CPVRClient::GetInstanceName() const
+{
+ if (Addon()->SupportsInstanceSettings())
+ {
+ std::string instanceName;
+ Addon()->GetSettingString(ADDON_SETTING_INSTANCE_NAME_VALUE, instanceName, InstanceId());
+ return instanceName;
+ }
+ return "";
+}
+
PVR_ERROR CPVRClient::GetDriveSpace(uint64_t& iTotal, uint64_t& iUsed) const
{
/* default to 0 in case of error */
diff --git a/xbmc/pvr/addons/PVRClient.h b/xbmc/pvr/addons/PVRClient.h
index 12bcc4e57d..42f634a775 100644
--- a/xbmc/pvr/addons/PVRClient.h
+++ b/xbmc/pvr/addons/PVRClient.h
@@ -170,6 +170,12 @@ public:
const std::string GetFriendlyName() const;
/*!
+ * @brief The name used by the PVR client addon instance
+ * @return string that can be used in log messages and the GUI.
+ */
+ std::string GetInstanceName() const;
+
+ /*!
* @brief Get the disk space reported by the server.
* @param iTotal The total disk space.
* @param iUsed The used disk space.
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
index b057b338bc..563aa126cd 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelGuide.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPVRChannelGuide.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
#include "pvr/PVRPlaybackState.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
index d6665fcf4b..efae8e7279 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPVRChannelManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
index 9c079c8e7e..c349bd0623 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPVRChannelsOSD.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
index c0d6d801d7..1fa8cd5175 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogPVRGroupManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "dialogs/GUIDialogYesNo.h"
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp b/xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp
index 2add783cf2..72b4694528 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRItemsViewBase.cpp
@@ -10,6 +10,7 @@
#include "ContextMenuManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "input/actions/Action.h"
diff --git a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
index 8def92d871..2b15428347 100644
--- a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
+++ b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIDirectory.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/LocalizeStrings.h"
#include "guilib/WindowIDs.h"
diff --git a/xbmc/pvr/guilib/GUIEPGGridContainer.cpp b/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
index de3ef1059e..ffb9e4aa8b 100644
--- a/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
+++ b/xbmc/pvr/guilib/GUIEPGGridContainer.cpp
@@ -9,6 +9,7 @@
#include "GUIEPGGridContainer.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/DirtyRegion.h"
#include "guilib/GUIAction.h"
@@ -206,11 +207,23 @@ void CGUIEPGGridContainer::Process(unsigned int currentTime, CDirtyRegionList& d
void CGUIEPGGridContainer::Render()
{
- RenderChannels();
- RenderRulerDate();
- RenderRuler();
- RenderProgrammeGrid();
- RenderProgressIndicator();
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ {
+ RenderProgressIndicator();
+ RenderProgrammeGrid();
+ RenderRuler();
+ RenderRulerDate();
+ RenderChannels();
+ }
+ else
+ {
+ RenderChannels();
+ RenderRulerDate();
+ RenderRuler();
+ RenderProgrammeGrid();
+ RenderProgressIndicator();
+ }
CGUIControl::Render();
}
@@ -315,7 +328,7 @@ void CGUIEPGGridContainer::RenderProgressIndicator()
if (CServiceBroker::GetWinSystem()->GetGfxContext().SetClipRegion(m_rulerPosX, m_rulerPosY, GetProgressIndicatorWidth(), GetProgressIndicatorHeight()))
{
m_guiProgressIndicatorTexture->SetDiffuseColor(m_diffuseColor);
- m_guiProgressIndicatorTexture->Render();
+ m_guiProgressIndicatorTexture->Render(0, m_guiProgressIndicatorTextureDepth);
CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion();
}
}
@@ -2089,7 +2102,10 @@ void CGUIEPGGridContainer::GetProgrammeCacheOffsets(int& cacheBefore, int& cache
}
}
-void CGUIEPGGridContainer::HandleChannels(bool bRender, unsigned int currentTime, CDirtyRegionList& dirtyregions)
+void CGUIEPGGridContainer::HandleChannels(bool bRender,
+ unsigned int currentTime,
+ CDirtyRegionList& dirtyregions,
+ bool bAssignDepth)
{
if (!m_focusedChannelLayout || !m_channelLayout)
return;
@@ -2170,6 +2186,13 @@ void CGUIEPGGridContainer::HandleChannels(bool bRender, unsigned int currentTime
RenderItem(pos, originChannel.y, item.get(), false);
}
}
+ else if (bAssignDepth)
+ {
+ if (focused)
+ focusedItem = item;
+ else
+ AssignItemDepth(item.get(), false);
+ }
else
{
// process our item
@@ -2197,9 +2220,16 @@ void CGUIEPGGridContainer::HandleChannels(bool bRender, unsigned int currentTime
CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion();
}
+ else if (bAssignDepth && focusedItem)
+ {
+ AssignItemDepth(focusedItem.get(), true);
+ }
}
-void CGUIEPGGridContainer::HandleRulerDate(bool bRender, unsigned int currentTime, CDirtyRegionList& dirtyregions)
+void CGUIEPGGridContainer::HandleRulerDate(bool bRender,
+ unsigned int currentTime,
+ CDirtyRegionList& dirtyregions,
+ bool bAssignDepth)
{
if (!m_rulerDateLayout || m_gridModel->RulerItemsSize() <= 1 || m_gridModel->IsZeroGridDuration())
return;
@@ -2213,6 +2243,10 @@ void CGUIEPGGridContainer::HandleRulerDate(bool bRender, unsigned int currentTim
RenderItem(m_posX, m_posY, item.get(), false);
CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion();
}
+ else if (bAssignDepth)
+ {
+ AssignItemDepth(item.get(), false);
+ }
else
{
const int rulerOffset = GetProgrammeScrollOffset();
@@ -2223,7 +2257,10 @@ void CGUIEPGGridContainer::HandleRulerDate(bool bRender, unsigned int currentTim
}
}
-void CGUIEPGGridContainer::HandleRuler(bool bRender, unsigned int currentTime, CDirtyRegionList& dirtyregions)
+void CGUIEPGGridContainer::HandleRuler(bool bRender,
+ unsigned int currentTime,
+ CDirtyRegionList& dirtyregions,
+ bool bAssignDepth)
{
if (!m_rulerLayout || m_gridModel->RulerItemsSize() <= 1 || m_gridModel->IsZeroGridDuration())
return;
@@ -2252,6 +2289,12 @@ void CGUIEPGGridContainer::HandleRuler(bool bRender, unsigned int currentTime, C
else
CServiceBroker::GetWinSystem()->GetGfxContext().SetClipRegion(m_rulerPosX, m_rulerPosY, m_rulerWidth, m_gridHeight);
}
+ else if (bAssignDepth)
+ {
+ if (!m_rulerDateLayout)
+ AssignItemDepth(item.get(), false);
+ GetProgrammeCacheOffsets(cacheBeforeRuler, cacheAfterRuler);
+ }
else
{
if (!m_rulerDateLayout)
@@ -2310,6 +2353,8 @@ void CGUIEPGGridContainer::HandleRuler(bool bRender, unsigned int currentTime, C
{
if (bRender)
RenderItem(pos, originRuler.y, item.get(), false);
+ else if (bAssignDepth)
+ AssignItemDepth(item.get(), false);
else
ProcessItem(pos, originRuler.y, item, lastitem, false, m_rulerLayout, m_rulerLayout, currentTime, dirtyregions, m_rulerWidth);
@@ -2319,6 +2364,8 @@ void CGUIEPGGridContainer::HandleRuler(bool bRender, unsigned int currentTime, C
{
if (bRender)
RenderItem(originRuler.x, pos, item.get(), false);
+ else if (bAssignDepth)
+ AssignItemDepth(item.get(), false);
else
ProcessItem(originRuler.x, pos, item, lastitem, false, m_rulerLayout, m_rulerLayout, currentTime, dirtyregions, m_rulerHeight);
@@ -2332,7 +2379,10 @@ void CGUIEPGGridContainer::HandleRuler(bool bRender, unsigned int currentTime, C
CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion();
}
-void CGUIEPGGridContainer::HandleProgrammeGrid(bool bRender, unsigned int currentTime, CDirtyRegionList& dirtyregions)
+void CGUIEPGGridContainer::HandleProgrammeGrid(bool bRender,
+ unsigned int currentTime,
+ CDirtyRegionList& dirtyregions,
+ bool bAssignDepth)
{
if (!m_focusedProgrammeLayout || !m_programmeLayout || m_gridModel->RulerItemsSize() <= 1 || m_gridModel->IsZeroGridDuration())
return;
@@ -2347,7 +2397,7 @@ void CGUIEPGGridContainer::HandleProgrammeGrid(bool bRender, unsigned int curren
{
CServiceBroker::GetWinSystem()->GetGfxContext().SetClipRegion(m_gridPosX, m_gridPosY, m_gridWidth, m_gridHeight);
}
- else
+ else if (!bAssignDepth)
{
int cacheBeforeChannel, cacheAfterChannel;
GetChannelCacheOffsets(cacheBeforeChannel, cacheAfterChannel);
@@ -2459,6 +2509,24 @@ void CGUIEPGGridContainer::HandleProgrammeGrid(bool bRender, unsigned int curren
RenderItem(posB, posA2, item.get(), focused);
}
}
+ else if (bAssignDepth)
+ {
+ // reset to grid start position if first item is out of grid view
+ if (posA2 < posA)
+ posA2 = posA;
+
+ // render our item
+ if (focused)
+ {
+ focusedPosX = posA2;
+ focusedPosY = posB;
+ focusedItem = item;
+ }
+ else
+ {
+ AssignItemDepth(item.get(), focused);
+ }
+ }
else
{
// calculate the size to truncate if item is out of grid view
@@ -2511,4 +2579,35 @@ void CGUIEPGGridContainer::HandleProgrammeGrid(bool bRender, unsigned int curren
CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion();
}
+ else if (bAssignDepth && focusedItem)
+ {
+ AssignItemDepth(focusedItem.get(), true);
+ }
+}
+
+void CGUIEPGGridContainer::AssignDepth()
+{
+ unsigned int dummyTime = 0;
+ CDirtyRegionList dummyRegions;
+ HandleChannels(false, dummyTime, dummyRegions, true);
+ HandleRuler(false, dummyTime, dummyRegions, true);
+ HandleRulerDate(false, dummyTime, dummyRegions, true);
+ HandleProgrammeGrid(false, dummyTime, dummyRegions, true);
+ m_guiProgressIndicatorTextureDepth = CServiceBroker::GetWinSystem()->GetGfxContext().GetDepth();
}
+
+void CGUIEPGGridContainer::AssignItemDepth(CGUIListItem* item, bool focused)
+{
+ if (focused)
+ {
+ if (item->GetFocusedLayout())
+ item->GetFocusedLayout()->AssignDepth();
+ }
+ else
+ {
+ if (item->GetFocusedLayout() && item->GetFocusedLayout()->IsAnimating(ANIM_TYPE_UNFOCUS))
+ item->GetFocusedLayout()->AssignDepth();
+ else if (item->GetLayout())
+ item->GetLayout()->AssignDepth();
+ }
+} \ No newline at end of file
diff --git a/xbmc/pvr/guilib/GUIEPGGridContainer.h b/xbmc/pvr/guilib/GUIEPGGridContainer.h
index 09acfc7426..94b6043163 100644
--- a/xbmc/pvr/guilib/GUIEPGGridContainer.h
+++ b/xbmc/pvr/guilib/GUIEPGGridContainer.h
@@ -128,6 +128,10 @@ namespace PVR
*/
bool SetChannel(const CPVRChannelNumber& channelNumber);
+ virtual void AssignDepth() override;
+
+ void AssignItemDepth(CGUIListItem* item, bool focused);
+
private:
bool OnClick(int actionID);
bool SelectItemFromPoint(const CPoint& point, bool justGrid = true);
@@ -201,10 +205,22 @@ namespace PVR
bool OnMouseDoubleClick(int dwButton, const CPoint& point);
bool OnMouseWheel(char wheel, const CPoint& point);
- void HandleChannels(bool bRender, unsigned int currentTime, CDirtyRegionList& dirtyregions);
- void HandleRuler(bool bRender, unsigned int currentTime, CDirtyRegionList& dirtyregions);
- void HandleRulerDate(bool bRender, unsigned int currentTime, CDirtyRegionList& dirtyregions);
- void HandleProgrammeGrid(bool bRender, unsigned int currentTime, CDirtyRegionList& dirtyregions);
+ void HandleChannels(bool bRender,
+ unsigned int currentTime,
+ CDirtyRegionList& dirtyregions,
+ bool bAssignDepth = false);
+ void HandleRuler(bool bRender,
+ unsigned int currentTime,
+ CDirtyRegionList& dirtyregions,
+ bool bAssignDepth = false);
+ void HandleRulerDate(bool bRender,
+ unsigned int currentTime,
+ CDirtyRegionList& dirtyregions,
+ bool bAssignDepth = false);
+ void HandleProgrammeGrid(bool bRender,
+ unsigned int currentTime,
+ CDirtyRegionList& dirtyregions,
+ bool bAssignDepth = false);
float GetCurrentTimePositionOnPage() const;
float GetProgressIndicatorWidth() const;
@@ -248,6 +264,7 @@ namespace PVR
float m_analogScrollCount = 0;
std::unique_ptr<CGUITexture> m_guiProgressIndicatorTexture;
+ uint32_t m_guiProgressIndicatorTextureDepth{0};
std::shared_ptr<CFileItem> m_lastItem;
std::shared_ptr<CFileItem> m_lastChannel;
diff --git a/xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp b/xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp
index f99515160c..df6f7e41cd 100644
--- a/xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp
+++ b/xbmc/pvr/guilib/GUIEPGGridContainerModel.cpp
@@ -9,6 +9,7 @@
#include "GUIEPGGridContainerModel.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
#include "pvr/channels/PVRChannel.h"
diff --git a/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp b/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
index 53bbf815f6..1bf613dc4e 100644
--- a/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionsDatabase.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIActionsDatabase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogProgress.h"
#include "dialogs/GUIDialogSelect.h"
diff --git a/xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp b/xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp
index 15c8af4208..a0bc877a60 100644
--- a/xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionsPlayback.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIActionsPlayback.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "application/ApplicationEnums.h"
#include "cores/DataCacheCore.h"
@@ -48,6 +49,7 @@
#include <string>
#include <vector>
+using namespace KODI;
using namespace PVR;
using namespace KODI::MESSAGING;
@@ -82,7 +84,7 @@ bool CPVRGUIActionsPlayback::CheckResumeRecording(const CFileItem& item) const
bool CPVRGUIActionsPlayback::ResumePlayRecording(const CFileItem& item, bool bFallbackToPlay) const
{
- if (VIDEO_UTILS::GetItemResumeInformation(item).isResumable)
+ if (VIDEO::UTILS::GetItemResumeInformation(item).isResumable)
{
const_cast<CFileItem*>(&item)->SetStartOffset(STARTOFFSET_RESUME);
}
@@ -125,7 +127,7 @@ bool CPVRGUIActionsPlayback::PlayRecording(const CFileItem& item, bool bCheckRes
if (!bCheckResume || CheckResumeRecording(item))
{
- if (!item.m_bIsFolder && VIDEO_UTILS::IsAutoPlayNextItem(item))
+ if (!item.m_bIsFolder && VIDEO::UTILS::IsAutoPlayNextItem(item))
{
// recursively add items located in the same folder as item to play list, starting with item
std::string parentPath = item.GetProperty("ParentPath").asString();
@@ -143,7 +145,7 @@ bool CPVRGUIActionsPlayback::PlayRecording(const CFileItem& item, bool bCheckRes
parentItem->SetStartOffset(STARTOFFSET_RESUME);
auto queuedItems = std::make_unique<CFileItemList>();
- VIDEO_UTILS::GetItemsForPlayList(parentItem, *queuedItems);
+ VIDEO::UTILS::GetItemsForPlayList(parentItem, *queuedItems);
// figure out where to start playback
int pos = 0;
@@ -179,7 +181,7 @@ bool CPVRGUIActionsPlayback::PlayRecordingFolder(const CFileItem& item, bool bCh
// recursively add items to list
const auto itemToQueue = std::make_shared<CFileItem>(item);
auto queuedItems = std::make_unique<CFileItemList>();
- VIDEO_UTILS::GetItemsForPlayList(itemToQueue, *queuedItems);
+ VIDEO::UTILS::GetItemsForPlayList(itemToQueue, *queuedItems);
CServiceBroker::GetAppMessenger()->PostMsg(TMSG_MEDIA_PLAY, 0, -1,
static_cast<void*>(queuedItems.release()));
diff --git a/xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp b/xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp
index c69c909b9a..9609617be9 100644
--- a/xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionsRecordings.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIActionsRecordings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "dialogs/GUIDialogBusy.h"
diff --git a/xbmc/pvr/guilib/PVRGUIActionsUtils.cpp b/xbmc/pvr/guilib/PVRGUIActionsUtils.cpp
index 907c645dd3..c6399f1a26 100644
--- a/xbmc/pvr/guilib/PVRGUIActionsUtils.cpp
+++ b/xbmc/pvr/guilib/PVRGUIActionsUtils.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIActionsUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/Directory.h"
#include "pvr/PVRManager.h"
diff --git a/xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp b/xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp
index 26859dd63a..11045c98d8 100644
--- a/xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp
+++ b/xbmc/pvr/guilib/PVRGUIChannelIconUpdater.cpp
@@ -9,6 +9,7 @@
#include "PVRGUIChannelIconUpdater.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h b/xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h
index 80df2dfc96..eb1839b483 100644
--- a/xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h
+++ b/xbmc/pvr/guilib/PVRGUIRecordingsPlayActionProcessor.h
@@ -16,7 +16,8 @@
namespace PVR
{
-class CGUIPVRRecordingsPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase
+class CGUIPVRRecordingsPlayActionProcessor
+ : public KODI::VIDEO::GUILIB::CVideoPlayActionProcessorBase
{
public:
explicit CGUIPVRRecordingsPlayActionProcessor(const std::shared_ptr<CFileItem>& item)
diff --git a/xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp b/xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp
index 01b4336501..03b5ef0bdd 100644
--- a/xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp
+++ b/xbmc/pvr/guilib/guiinfo/PVRGUIInfo.cpp
@@ -439,6 +439,14 @@ bool CPVRGUIInfo::GetListItemAndPlayerLabel(const CFileItem* item,
case LISTITEM_CHANNEL_NUMBER:
case LISTITEM_PREMIERED:
break; // obtain value from channel/epg
+ case LISTITEM_BACKEND_INSTANCE_NAME:
+ {
+ strValue = CServiceBroker::GetPVRManager()
+ .Clients()
+ ->GetCreatedClient(timer->ClientID())
+ ->GetInstanceName();
+ return true;
+ }
default:
return false;
}
@@ -558,6 +566,14 @@ bool CPVRGUIInfo::GetListItemAndPlayerLabel(const CFileItem* item,
return true;
}
return false;
+ case LISTITEM_BACKEND_INSTANCE_NAME:
+ {
+ strValue = CServiceBroker::GetPVRManager()
+ .Clients()
+ ->GetCreatedClient(recording->ClientID())
+ ->GetInstanceName();
+ return true;
+ }
}
return false;
}
@@ -755,6 +771,14 @@ bool CPVRGUIInfo::GetListItemAndPlayerLabel(const CFileItem* item,
case LISTITEM_PARENTAL_RATING_CODE:
strValue = epgTag->ParentalRatingCode();
return true;
+ case LISTITEM_BACKEND_INSTANCE_NAME:
+ {
+ strValue = CServiceBroker::GetPVRManager()
+ .Clients()
+ ->GetCreatedClient(epgTag->ClientID())
+ ->GetInstanceName();
+ return true;
+ }
case VIDEOPLAYER_PREMIERED:
case LISTITEM_PREMIERED:
if (epgTag->FirstAired().IsValid())
diff --git a/xbmc/pvr/windows/GUIViewStatePVR.cpp b/xbmc/pvr/windows/GUIViewStatePVR.cpp
index d86f6fc2a6..a5004d8ba9 100644
--- a/xbmc/pvr/windows/GUIViewStatePVR.cpp
+++ b/xbmc/pvr/windows/GUIViewStatePVR.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStatePVR.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "pvr/PVRManager.h"
#include "pvr/addons/PVRClients.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp
index 71a800feda..ce891a80f7 100644
--- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRBase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
index e323c319be..8ccbdd68fa 100644
--- a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRChannels.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
index 3923cae6bb..6ce75fd5f2 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRGuide.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "addons/Skin.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp
index 363011a379..0e5886a52b 100644
--- a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp
@@ -8,6 +8,7 @@
#include "GUIWindowPVRRecordings.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
@@ -37,8 +38,8 @@
#include <mutex>
#include <string>
+using namespace KODI;
using namespace PVR;
-using namespace VIDEO::GUILIB;
CGUIWindowPVRRecordingsBase::CGUIWindowPVRRecordingsBase(bool bRadio,
int id,
@@ -257,7 +258,7 @@ protected:
bool OnQueueSelected() override
{
- VIDEO_UTILS::QueueItem(m_item, VIDEO_UTILS::QueuePosition::POSITION_END);
+ VIDEO::UTILS::QueueItem(m_item, VIDEO::UTILS::QueuePosition::POSITION_END);
return true;
}
@@ -278,7 +279,7 @@ private:
const int m_itemIndex{-1};
};
-class CVideoPlayActionProcessor : public CVideoPlayActionProcessorBase
+class CVideoPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase
{
public:
explicit CVideoPlayActionProcessor(const std::shared_ptr<CFileItem>& item)
diff --git a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
index 0c129c3e00..4a9ad6b10e 100644
--- a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRSearch.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogBusy.h"
#include "dialogs/GUIDialogYesNo.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp b/xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp
index 1b203d403d..1d532fa1ac 100644
--- a/xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRTimerRules.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRTimerRules.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "pvr/timers/PVRTimersPath.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRTimers.cpp b/xbmc/pvr/windows/GUIWindowPVRTimers.cpp
index 610571bcd5..0bc955d6c8 100644
--- a/xbmc/pvr/windows/GUIWindowPVRTimers.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRTimers.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRTimers.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "pvr/timers/PVRTimersPath.h"
#include "utils/URIUtils.h"
diff --git a/xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp b/xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp
index 41677eb873..68b1501e2b 100644
--- a/xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRTimersBase.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowPVRTimersBase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/rendering/RenderSystem.cpp b/xbmc/rendering/RenderSystem.cpp
index cabbea77b1..3baa8fecaa 100644
--- a/xbmc/rendering/RenderSystem.cpp
+++ b/xbmc/rendering/RenderSystem.cpp
@@ -73,7 +73,7 @@ void CRenderSystemBase::ShowSplash(const std::string& message)
}
CServiceBroker::GetWinSystem()->GetGfxContext().lock();
- CServiceBroker::GetWinSystem()->GetGfxContext().Clear();
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0xff000000);
RESOLUTION_INFO res = CServiceBroker::GetWinSystem()->GetGfxContext().GetResInfo();
CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(res, true);
diff --git a/xbmc/rendering/RenderSystem.h b/xbmc/rendering/RenderSystem.h
index 334b74b4f8..8e188cdf00 100644
--- a/xbmc/rendering/RenderSystem.h
+++ b/xbmc/rendering/RenderSystem.h
@@ -21,6 +21,13 @@
* This interface is very basic since a lot of the actual details will go in to the derived classes
*/
+enum DEPTH_CULLING
+{
+ DEPTH_CULLING_OFF = 0,
+ DEPTH_CULLING_BACK_TO_FRONT,
+ DEPTH_CULLING_FRONT_TO_BACK,
+};
+
class CGUIImage;
class CGUITextLayout;
@@ -37,6 +44,7 @@ public:
virtual bool BeginRender() = 0;
virtual bool EndRender() = 0;
virtual void PresentRender(bool rendered, bool videoLayer) = 0;
+ virtual void InvalidateColorBuffer() {}
virtual bool ClearBuffers(UTILS::COLOR::Color color) = 0;
virtual bool IsExtSupported(const char* extension) const = 0;
@@ -49,6 +57,8 @@ public:
virtual void SetScissors(const CRect &rect) = 0;
virtual void ResetScissors() = 0;
+ virtual void SetDepthCulling(DEPTH_CULLING culling) {}
+
virtual void CaptureStateBlock() = 0;
virtual void ApplyStateBlock() = 0;
diff --git a/xbmc/rendering/gl/GLShader.cpp b/xbmc/rendering/gl/GLShader.cpp
index e91af97b56..a67601e77c 100644
--- a/xbmc/rendering/gl/GLShader.cpp
+++ b/xbmc/rendering/gl/GLShader.cpp
@@ -1,12 +1,11 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*/
-
#include "GLShader.h"
#include "ServiceBroker.h"
@@ -49,6 +48,10 @@ void CGLShader::OnCompiledAndLinked()
// Variables passed directly to the Vertex shader
m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
+ m_hMatrix = glGetUniformLocation(ProgramHandle(), "m_matrix");
+ m_hShaderClip = glGetUniformLocation(ProgramHandle(), "m_shaderClip");
+ m_hCoordStep = glGetUniformLocation(ProgramHandle(), "m_cordStep");
+ m_hDepth = glGetUniformLocation(ProgramHandle(), "m_depth");
// Vertex attributes
m_hPos = glGetAttribLocation(ProgramHandle(), "m_attrpos");
diff --git a/xbmc/rendering/gl/GLShader.h b/xbmc/rendering/gl/GLShader.h
index d5b82f3a07..8355043281 100644
--- a/xbmc/rendering/gl/GLShader.h
+++ b/xbmc/rendering/gl/GLShader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -25,8 +25,12 @@ public:
GLint GetColLoc() {return m_hCol;}
GLint GetCord0Loc() {return m_hCord0;}
GLint GetCord1Loc() {return m_hCord1;}
+ GLint GetDepthLoc() { return m_hDepth; }
GLint GetUniColLoc() {return m_hUniCol;}
GLint GetModelLoc() {return m_hModel; }
+ GLint GetMatrixLoc() { return m_hMatrix; }
+ GLint GetShaderClipLoc() { return m_hShaderClip; }
+ GLint GetShaderCoordStepLoc() { return m_hCoordStep; }
bool HardwareClipIsPossible() {return m_clipPossible; }
GLfloat GetClipXFactor() {return m_clipXFactor; }
GLfloat GetClipXOffset() {return m_clipXOffset; }
@@ -39,10 +43,14 @@ protected:
GLint m_hUniCol = 0;
GLint m_hProj = 0;
GLint m_hModel = 0;
+ GLint m_hMatrix{0}; // m_hProj * m_hModel
+ GLint m_hShaderClip{0}; // clipping rect vec4(x1,y1,x2,y2)
+ GLint m_hCoordStep{0}; // step (1/resolution) for the two textures vec4(t1.x,t1.y,t2.x,t2.y)
GLint m_hPos = 0;
GLint m_hCol = 0;
GLint m_hCord0 = 0;
GLint m_hCord1 = 0;
+ GLint m_hDepth = 0;
const GLfloat *m_proj = nullptr;
const GLfloat *m_model = nullptr;
diff --git a/xbmc/rendering/gl/RenderSystemGL.cpp b/xbmc/rendering/gl/RenderSystemGL.cpp
index 4b80014d41..2e553e2ba5 100644
--- a/xbmc/rendering/gl/RenderSystemGL.cpp
+++ b/xbmc/rendering/gl/RenderSystemGL.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -222,8 +222,7 @@ bool CRenderSystemGL::ResetRenderSystem(int width, int height)
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- glEnable(GL_BLEND); // Turn Blending On
- glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND); // Turn Blending On
return true;
}
@@ -266,6 +265,30 @@ bool CRenderSystemGL::EndRender()
return true;
}
+void CRenderSystemGL::InvalidateColorBuffer()
+{
+ if (!m_bRenderCreated)
+ return;
+
+ /* clear is not affected by stipple pattern, so we can only clear on first frame */
+ if (m_stereoMode == RENDER_STEREO_MODE_INTERLACED && m_stereoView == RENDER_STEREO_VIEW_RIGHT)
+ return;
+
+ // some platforms prefer a clear, instead of rendering over
+ if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiGeometryClear)
+ {
+ ClearBuffers(0);
+ return;
+ }
+
+ if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering)
+ return;
+
+ glClearDepthf(0);
+ glDepthMask(GL_TRUE);
+ glClear(GL_DEPTH_BUFFER_BIT);
+}
+
bool CRenderSystemGL::ClearBuffers(UTILS::COLOR::Color color)
{
if (!m_bRenderCreated)
@@ -283,6 +306,14 @@ bool CRenderSystemGL::ClearBuffers(UTILS::COLOR::Color color)
glClearColor(r, g, b, a);
GLbitfield flags = GL_COLOR_BUFFER_BIT;
+
+ if (CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering)
+ {
+ glClearDepthf(0);
+ glDepthMask(GL_TRUE);
+ flags |= GL_DEPTH_BUFFER_BIT;
+ }
+
glClear(flags);
return true;
@@ -505,6 +536,27 @@ void CRenderSystemGL::ResetScissors()
SetScissors(CRect(0, 0, (float)m_width, (float)m_height));
}
+void CRenderSystemGL::SetDepthCulling(DEPTH_CULLING culling)
+{
+ if (culling == DEPTH_CULLING_OFF)
+ {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ }
+ else if (culling == DEPTH_CULLING_BACK_TO_FRONT)
+ {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ glDepthFunc(GL_GEQUAL);
+ }
+ else if (culling == DEPTH_CULLING_FRONT_TO_BACK)
+ {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ glDepthFunc(GL_GREATER);
+ }
+}
+
void CRenderSystemGL::GetGLSLVersion(int& major, int& minor)
{
major = m_glslMajor;
@@ -682,13 +734,24 @@ void CRenderSystemGL::InitialiseShaders()
CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_multi.glsl - compile and link failed");
}
- m_pShader[ShaderMethodGL::SM_FONTS] =
- std::make_unique<CGLShader>("gl_shader_frag_fonts.glsl", defines);
+ m_pShader[ShaderMethodGL::SM_FONTS] = std::make_unique<CGLShader>(
+ "gl_shader_vert_simple.glsl", "gl_shader_frag_fonts.glsl", defines);
if (!m_pShader[ShaderMethodGL::SM_FONTS]->CompileAndLink())
{
m_pShader[ShaderMethodGL::SM_FONTS]->Free();
m_pShader[ShaderMethodGL::SM_FONTS].reset();
- CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_fonts.glsl - compile and link failed");
+ CLog::Log(LOGERROR, "GUI Shader gl_shader_vert_simple.glsl + gl_shader_frag_fonts.glsl - "
+ "compile and link failed");
+ }
+
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP] =
+ std::make_unique<CGLShader>("gl_shader_vert_clip.glsl", "gl_shader_frag_fonts.glsl", defines);
+ if (!m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->CompileAndLink())
+ {
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->Free();
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP].reset();
+ CLog::Log(LOGERROR, "GUI Shader gl_shader_vert_clip.glsl + gl_shader_frag_fonts.glsl - compile "
+ "and link failed");
}
m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND] =
@@ -732,6 +795,10 @@ void CRenderSystemGL::ReleaseShaders()
m_pShader[ShaderMethodGL::SM_FONTS]->Free();
m_pShader[ShaderMethodGL::SM_FONTS].reset();
+ if (m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP])
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->Free();
+ m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP].reset();
+
if (m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND])
m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND]->Free();
m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND].reset();
@@ -795,6 +862,14 @@ GLint CRenderSystemGL::ShaderGetCoord1()
return -1;
}
+GLint CRenderSystemGL::ShaderGetDepth()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetDepthLoc();
+
+ return -1;
+}
+
GLint CRenderSystemGL::ShaderGetUniCol()
{
if (m_pShader[m_method])
@@ -811,6 +886,30 @@ GLint CRenderSystemGL::ShaderGetModel()
return -1;
}
+GLint CRenderSystemGL::ShaderGetMatrix()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetMatrixLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGL::ShaderGetClip()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetShaderClipLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGL::ShaderGetCoordStep()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetShaderCoordStepLoc();
+
+ return -1;
+}
+
std::string CRenderSystemGL::GetShaderPath(const std::string &filename)
{
std::string path = "GL/1.2/";
diff --git a/xbmc/rendering/gl/RenderSystemGL.h b/xbmc/rendering/gl/RenderSystemGL.h
index 191c97ff96..920024a37e 100644
--- a/xbmc/rendering/gl/RenderSystemGL.h
+++ b/xbmc/rendering/gl/RenderSystemGL.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -27,6 +27,7 @@ enum class ShaderMethodGL
SM_TEXTURE_LIM,
SM_MULTI,
SM_FONTS,
+ SM_FONTS_SHADER_CLIP,
SM_TEXTURE_NOBLEND,
SM_MULTI_BLENDCOLOR,
SM_MAX
@@ -52,6 +53,7 @@ private:
{ShaderMethodGL::SM_TEXTURE_LIM, "texture limited"},
{ShaderMethodGL::SM_MULTI, "multi"},
{ShaderMethodGL::SM_FONTS, "fonts"},
+ {ShaderMethodGL::SM_FONTS_SHADER_CLIP, "fonts with vertex shader based clipping"},
{ShaderMethodGL::SM_TEXTURE_NOBLEND, "texture no blending"},
{ShaderMethodGL::SM_MULTI_BLENDCOLOR, "multi blend colour"},
});
@@ -73,6 +75,7 @@ public:
bool BeginRender() override;
bool EndRender() override;
void PresentRender(bool rendered, bool videoLayer) override;
+ void InvalidateColorBuffer() override;
bool ClearBuffers(UTILS::COLOR::Color color) override;
bool IsExtSupported(const char* extension) const override;
@@ -87,6 +90,8 @@ public:
void SetScissors(const CRect &rect) override;
void ResetScissors() override;
+ void SetDepthCulling(DEPTH_CULLING culling) override;
+
void CaptureStateBlock() override;
void ApplyStateBlock() override;
@@ -112,8 +117,12 @@ public:
GLint ShaderGetCol();
GLint ShaderGetCoord0();
GLint ShaderGetCoord1();
+ GLint ShaderGetDepth();
GLint ShaderGetUniCol();
GLint ShaderGetModel();
+ GLint ShaderGetMatrix();
+ GLint ShaderGetClip();
+ GLint ShaderGetCoordStep();
protected:
virtual void SetVSyncImpl(bool enable) = 0;
diff --git a/xbmc/rendering/gles/GLESShader.cpp b/xbmc/rendering/gles/GLESShader.cpp
index 961c3f7961..1dfebf6cb7 100644
--- a/xbmc/rendering/gles/GLESShader.cpp
+++ b/xbmc/rendering/gles/GLESShader.cpp
@@ -54,6 +54,10 @@ void CGLESShader::OnCompiledAndLinked()
m_hProj = glGetUniformLocation(ProgramHandle(), "m_proj");
m_hModel = glGetUniformLocation(ProgramHandle(), "m_model");
m_hCoord0Matrix = glGetUniformLocation(ProgramHandle(), "m_coord0Matrix");
+ m_hMatrix = glGetUniformLocation(ProgramHandle(), "m_matrix");
+ m_hShaderClip = glGetUniformLocation(ProgramHandle(), "m_shaderClip");
+ m_hCoordStep = glGetUniformLocation(ProgramHandle(), "m_cordStep");
+ m_hDepth = glGetUniformLocation(ProgramHandle(), "m_depth");
// Vertex attributes
m_hPos = glGetAttribLocation(ProgramHandle(), "m_attrpos");
diff --git a/xbmc/rendering/gles/GLESShader.h b/xbmc/rendering/gles/GLESShader.h
index 1f59895740..2fd3b0716e 100644
--- a/xbmc/rendering/gles/GLESShader.h
+++ b/xbmc/rendering/gles/GLESShader.h
@@ -25,6 +25,7 @@ public:
GLint GetColLoc() { return m_hCol; }
GLint GetCord0Loc() { return m_hCord0; }
GLint GetCord1Loc() { return m_hCord1; }
+ GLint GetDepthLoc() { return m_hDepth; }
GLint GetUniColLoc() { return m_hUniCol; }
GLint GetCoord0MatrixLoc() { return m_hCoord0Matrix; }
GLint GetFieldLoc() { return m_hField; }
@@ -32,6 +33,9 @@ public:
GLint GetContrastLoc() { return m_hContrast; }
GLint GetBrightnessLoc() { return m_hBrightness; }
GLint GetModelLoc() { return m_hModel; }
+ GLint GetMatrixLoc() { return m_hMatrix; }
+ GLint GetShaderClipLoc() { return m_hShaderClip; }
+ GLint GetShaderCoordStepLoc() { return m_hCoordStep; }
bool HardwareClipIsPossible() { return m_clipPossible; }
GLfloat GetClipXFactor() { return m_clipXFactor; }
GLfloat GetClipXOffset() { return m_clipXOffset; }
@@ -44,6 +48,9 @@ protected:
GLint m_hUniCol = 0;
GLint m_hProj = 0;
GLint m_hModel = 0;
+ GLint m_hMatrix{0}; // m_hProj * m_hModel
+ GLint m_hShaderClip{0}; // clipping rect vec4(x1,y1,x2,y2)
+ GLint m_hCoordStep{0}; // step (1/resolution) for the two textures vec4(t1.x,t1.y,t2.x,t2.y)
GLint m_hPos = 0;
GLint m_hCol = 0;
GLint m_hCord0 = 0;
@@ -53,6 +60,7 @@ protected:
GLint m_hStep = 0;
GLint m_hContrast = 0;
GLint m_hBrightness = 0;
+ GLint m_hDepth = 0;
const GLfloat *m_proj;
const GLfloat *m_model;
diff --git a/xbmc/rendering/gles/RenderSystemGLES.cpp b/xbmc/rendering/gles/RenderSystemGLES.cpp
index f25f783960..52b734f433 100644
--- a/xbmc/rendering/gles/RenderSystemGLES.cpp
+++ b/xbmc/rendering/gles/RenderSystemGLES.cpp
@@ -135,8 +135,7 @@ bool CRenderSystemGLES::ResetRenderSystem(int width, int height)
glMatrixTexture.Load();
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- glEnable(GL_BLEND); // Turn Blending On
- glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND); // Turn Blending On
return true;
}
@@ -187,6 +186,23 @@ bool CRenderSystemGLES::EndRender()
return true;
}
+void CRenderSystemGLES::InvalidateColorBuffer()
+{
+ if (!m_bRenderCreated)
+ return;
+
+ // some platforms prefer a clear, instead of rendering over
+ if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiGeometryClear)
+ ClearBuffers(0);
+
+ if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering)
+ return;
+
+ glClearDepthf(0);
+ glDepthMask(true);
+ glClear(GL_DEPTH_BUFFER_BIT);
+}
+
bool CRenderSystemGLES::ClearBuffers(UTILS::COLOR::Color color)
{
if (!m_bRenderCreated)
@@ -200,6 +216,14 @@ bool CRenderSystemGLES::ClearBuffers(UTILS::COLOR::Color color)
glClearColor(r, g, b, a);
GLbitfield flags = GL_COLOR_BUFFER_BIT;
+
+ if (CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering)
+ {
+ glClearDepthf(0);
+ glDepthMask(GL_TRUE);
+ flags |= GL_DEPTH_BUFFER_BIT;
+ }
+
glClear(flags);
return true;
@@ -383,6 +407,27 @@ void CRenderSystemGLES::ResetScissors()
SetScissors(CRect(0, 0, (float)m_width, (float)m_height));
}
+void CRenderSystemGLES::SetDepthCulling(DEPTH_CULLING culling)
+{
+ if (culling == DEPTH_CULLING_OFF)
+ {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ }
+ else if (culling == DEPTH_CULLING_BACK_TO_FRONT)
+ {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ glDepthFunc(GL_GEQUAL);
+ }
+ else if (culling == DEPTH_CULLING_FRONT_TO_BACK)
+ {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ glDepthFunc(GL_GREATER);
+ }
+}
+
void CRenderSystemGLES::InitialiseShaders()
{
std::string defines;
@@ -425,7 +470,7 @@ void CRenderSystemGLES::InitialiseShaders()
}
m_pShader[ShaderMethodGLES::SM_FONTS] =
- std::make_unique<CGLESShader>("gles_shader_fonts.frag", defines);
+ std::make_unique<CGLESShader>("gles_shader_simple.vert", "gles_shader_fonts.frag", defines);
if (!m_pShader[ShaderMethodGLES::SM_FONTS]->CompileAndLink())
{
m_pShader[ShaderMethodGLES::SM_FONTS]->Free();
@@ -433,6 +478,16 @@ void CRenderSystemGLES::InitialiseShaders()
CLog::Log(LOGERROR, "GUI Shader gles_shader_fonts.frag - compile and link failed");
}
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP] =
+ std::make_unique<CGLESShader>("gles_shader_clip.vert", "gles_shader_fonts.frag", defines);
+ if (!m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP]->CompileAndLink())
+ {
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP]->Free();
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP].reset();
+ CLog::Log(LOGERROR, "GUI Shader gles_shader_clip.vert + gles_shader_fonts.frag - compile "
+ "and link failed");
+ }
+
m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND] =
std::make_unique<CGLESShader>("gles_shader_texture_noblend.frag", defines);
if (!m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND]->CompileAndLink())
@@ -528,6 +583,10 @@ void CRenderSystemGLES::ReleaseShaders()
m_pShader[ShaderMethodGLES::SM_FONTS]->Free();
m_pShader[ShaderMethodGLES::SM_FONTS].reset();
+ if (m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP])
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP]->Free();
+ m_pShader[ShaderMethodGLES::SM_FONTS_SHADER_CLIP].reset();
+
if (m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND])
m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND]->Free();
m_pShader[ShaderMethodGLES::SM_TEXTURE_NOBLEND].reset();
@@ -615,6 +674,14 @@ GLint CRenderSystemGLES::GUIShaderGetCoord1()
return -1;
}
+GLint CRenderSystemGLES::GUIShaderGetDepth()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetDepthLoc();
+
+ return -1;
+}
+
GLint CRenderSystemGLES::GUIShaderGetUniCol()
{
if (m_pShader[m_method])
@@ -675,3 +742,27 @@ GLint CRenderSystemGLES::GUIShaderGetModel()
return -1;
}
+
+GLint CRenderSystemGLES::GUIShaderGetMatrix()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetMatrixLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGLES::GUIShaderGetClip()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetShaderClipLoc();
+
+ return -1;
+}
+
+GLint CRenderSystemGLES::GUIShaderGetCoordStep()
+{
+ if (m_pShader[m_method])
+ return m_pShader[m_method]->GetShaderCoordStepLoc();
+
+ return -1;
+}
diff --git a/xbmc/rendering/gles/RenderSystemGLES.h b/xbmc/rendering/gles/RenderSystemGLES.h
index e0cd72b9c1..a6be00933e 100644
--- a/xbmc/rendering/gles/RenderSystemGLES.h
+++ b/xbmc/rendering/gles/RenderSystemGLES.h
@@ -25,6 +25,7 @@ enum class ShaderMethodGLES
SM_TEXTURE,
SM_MULTI,
SM_FONTS,
+ SM_FONTS_SHADER_CLIP,
SM_TEXTURE_NOBLEND,
SM_MULTI_BLENDCOLOR,
SM_TEXTURE_RGBA,
@@ -55,6 +56,7 @@ private:
{ShaderMethodGLES::SM_TEXTURE, "texture"},
{ShaderMethodGLES::SM_MULTI, "multi"},
{ShaderMethodGLES::SM_FONTS, "fonts"},
+ {ShaderMethodGLES::SM_FONTS_SHADER_CLIP, "fonts with vertex shader based clipping"},
{ShaderMethodGLES::SM_TEXTURE_NOBLEND, "texture no blending"},
{ShaderMethodGLES::SM_MULTI_BLENDCOLOR, "multi blend colour"},
{ShaderMethodGLES::SM_TEXTURE_RGBA, "texure rgba"},
@@ -83,6 +85,7 @@ public:
bool BeginRender() override;
bool EndRender() override;
void PresentRender(bool rendered, bool videoLayer) override;
+ void InvalidateColorBuffer() override;
bool ClearBuffers(UTILS::COLOR::Color color) override;
bool IsExtSupported(const char* extension) const override;
@@ -97,6 +100,8 @@ public:
void SetScissors(const CRect& rect) override;
void ResetScissors() override;
+ void SetDepthCulling(DEPTH_CULLING culling) override;
+
void CaptureStateBlock() override;
void ApplyStateBlock() override;
@@ -124,6 +129,10 @@ public:
GLint GUIShaderGetContrast();
GLint GUIShaderGetBrightness();
GLint GUIShaderGetModel();
+ GLint GUIShaderGetMatrix();
+ GLint GUIShaderGetClip();
+ GLint GUIShaderGetCoordStep();
+ GLint GUIShaderGetDepth();
protected:
virtual void SetVSyncImpl(bool enable) = 0;
diff --git a/xbmc/settings/AdvancedSettings.cpp b/xbmc/settings/AdvancedSettings.cpp
index a9f0f41cc5..7b78c32299 100644
--- a/xbmc/settings/AdvancedSettings.cpp
+++ b/xbmc/settings/AdvancedSettings.cpp
@@ -1224,6 +1224,8 @@ void CAdvancedSettings::ParseSettingsFile(const std::string &file)
XMLUtils::GetInt(pElement, "algorithmdirtyregions", m_guiAlgorithmDirtyRegions);
XMLUtils::GetBoolean(pElement, "smartredraw", m_guiSmartRedraw);
XMLUtils::GetInt(pElement, "anisotropicfiltering", m_guiAnisotropicFiltering);
+ XMLUtils::GetBoolean(pElement, "fronttobackrendering", m_guiFrontToBackRendering);
+ XMLUtils::GetBoolean(pElement, "geometryclear", m_guiGeometryClear);
}
std::string seekSteps;
diff --git a/xbmc/settings/AdvancedSettings.h b/xbmc/settings/AdvancedSettings.h
index 8db9a89a56..e9adb76b61 100644
--- a/xbmc/settings/AdvancedSettings.h
+++ b/xbmc/settings/AdvancedSettings.h
@@ -334,6 +334,8 @@ class CAdvancedSettings : public ISettingCallback, public ISettingsHandler
int m_guiAlgorithmDirtyRegions;
bool m_guiSmartRedraw;
int32_t m_guiAnisotropicFiltering{0};
+ bool m_guiFrontToBackRendering{false};
+ bool m_guiGeometryClear{true};
unsigned int m_addonPackageFolderSize;
bool m_jsonOutputCompact;
diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
index 61a5edc454..70d12f6866 100644
--- a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
+++ b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp
@@ -43,7 +43,7 @@
#define SETTING_ALL_EXTERNAL_AUDIO "allexternalaudio"
using namespace ADDON;
-
+using namespace KODI;
CGUIDialogContentSettings::CGUIDialogContentSettings()
: CGUIDialogSettingsManualBase(WINDOW_DIALOG_CONTENT_SETTINGS, "DialogSettings.xml")
diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.h b/xbmc/settings/dialogs/GUIDialogContentSettings.h
index c0d7c81942..e933280d0d 100644
--- a/xbmc/settings/dialogs/GUIDialogContentSettings.h
+++ b/xbmc/settings/dialogs/GUIDialogContentSettings.h
@@ -14,7 +14,7 @@
#include <map>
#include <utility>
-namespace VIDEO
+namespace KODI::VIDEO
{
struct SScanSettings;
}
@@ -35,7 +35,7 @@ public:
const ADDON::ScraperPtr& GetScraper() const { return m_scraper; }
void SetScraper(ADDON::ScraperPtr scraper) { m_scraper = std::move(scraper); }
- void SetScanSettings(const VIDEO::SScanSettings &scanSettings);
+ void SetScanSettings(const KODI::VIDEO::SScanSettings& scanSettings);
bool GetScanRecursive() const { return m_scanRecursive; }
bool GetUseDirectoryNames() const { return m_useDirectoryNames; }
bool GetContainsSingleItem() const { return m_containsSingleItem; }
@@ -44,7 +44,9 @@ public:
bool GetUseAllExternalAudio() const { return m_allExternalAudio; }
static bool Show(ADDON::ScraperPtr& scraper, CONTENT_TYPE content = CONTENT_NONE);
- static bool Show(ADDON::ScraperPtr& scraper, VIDEO::SScanSettings& settings, CONTENT_TYPE content = CONTENT_NONE);
+ static bool Show(ADDON::ScraperPtr& scraper,
+ KODI::VIDEO::SScanSettings& settings,
+ CONTENT_TYPE content = CONTENT_NONE);
protected:
// specializations of CGUIWindow
diff --git a/xbmc/settings/dialogs/GUIDialogSettingsBase.h b/xbmc/settings/dialogs/GUIDialogSettingsBase.h
index 38fe7c9e0f..63862e6643 100644
--- a/xbmc/settings/dialogs/GUIDialogSettingsBase.h
+++ b/xbmc/settings/dialogs/GUIDialogSettingsBase.h
@@ -24,8 +24,8 @@
#define CONTROL_SETTINGS_CANCEL_BUTTON 29
#define CONTROL_SETTINGS_CUSTOM_BUTTON 30
-#define CONTROL_SETTINGS_START_BUTTONS -100
-#define CONTROL_SETTINGS_START_CONTROL -80
+#define CONTROL_SETTINGS_START_BUTTONS -200
+#define CONTROL_SETTINGS_START_CONTROL -180
#define SETTINGS_RESET_SETTING_ID "settings.reset"
#define SETTINGS_EMPTY_CATEGORY_ID "categories.empty"
diff --git a/xbmc/settings/windows/GUIControlSettings.cpp b/xbmc/settings/windows/GUIControlSettings.cpp
index fdb1a439fd..ea45b0deed 100644
--- a/xbmc/settings/windows/GUIControlSettings.cpp
+++ b/xbmc/settings/windows/GUIControlSettings.cpp
@@ -9,6 +9,7 @@
#include "GUIControlSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "addons/AddonManager.h"
diff --git a/xbmc/test/TestBasicEnvironment.cpp b/xbmc/test/TestBasicEnvironment.cpp
index 7a357765a0..7a33e9d851 100644
--- a/xbmc/test/TestBasicEnvironment.cpp
+++ b/xbmc/test/TestBasicEnvironment.cpp
@@ -9,6 +9,7 @@
#include "TestBasicEnvironment.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "ServiceManager.h"
#include "TestUtils.h"
diff --git a/xbmc/utils/ExecString.cpp b/xbmc/utils/ExecString.cpp
index cd392c26db..95164ce7eb 100644
--- a/xbmc/utils/ExecString.cpp
+++ b/xbmc/utils/ExecString.cpp
@@ -12,14 +12,18 @@
#include "ServiceBroker.h"
#include "URL.h"
#include "Util.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingsComponent.h"
#include "utils/StringUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
+using namespace KODI;
+
CExecString::CExecString(const std::string& execString)
{
m_valid = Parse(execString);
@@ -123,9 +127,9 @@ bool CExecString::Parse(const CFileItem& item, const std::string& contextWindow)
Build("StartAndroidActivity", {StringUtils::Paramify(item.GetPath().substr(26))});
else // assume a media file
{
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(item) && item.HasVideoInfoTag())
BuildPlayMedia(item, StringUtils::Paramify(item.GetVideoInfoTag()->m_strFileNameAndPath));
- else if (item.IsMusicDb() && item.HasMusicInfoTag())
+ else if (MUSIC::IsMusicDb(item) && item.HasMusicInfoTag())
BuildPlayMedia(item, StringUtils::Paramify(item.GetMusicInfoTag()->GetURL()));
else if (item.IsPicture())
Build("ShowPicture", {StringUtils::Paramify(item.GetPath())});
diff --git a/xbmc/utils/FileOperationJob.h b/xbmc/utils/FileOperationJob.h
index 7284c62b6b..5dad5403bd 100644
--- a/xbmc/utils/FileOperationJob.h
+++ b/xbmc/utils/FileOperationJob.h
@@ -9,6 +9,7 @@
#pragma once
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/IFileTypes.h"
#include "utils/ProgressJob.h"
diff --git a/xbmc/utils/FontUtils.cpp b/xbmc/utils/FontUtils.cpp
index 2c23b90c69..8e6af68907 100644
--- a/xbmc/utils/FontUtils.cpp
+++ b/xbmc/utils/FontUtils.cpp
@@ -9,6 +9,7 @@
#include "FontUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "StringUtils.h"
#include "URIUtils.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/utils/Geometry.h b/xbmc/utils/Geometry.h
index 31557fc647..90e4275165 100644
--- a/xbmc/utils/Geometry.h
+++ b/xbmc/utils/Geometry.h
@@ -177,7 +177,7 @@ public:
return {m_w, m_h};
}
- template<class U> explicit CSizeGen<T>(const CSizeGen<U>& rhs)
+ template<class U> explicit CSizeGen(const CSizeGen<U>& rhs)
{
CheckSet(static_cast<T> (rhs.m_w), static_cast<T> (rhs.m_h));
}
@@ -281,6 +281,11 @@ public:
return (x1 <= point.x && point.x <= x2 && y1 <= point.y && point.y <= y2);
};
+ constexpr bool Intersects(const this_type& rect) const
+ {
+ return (x1 < rect.x2 && x2 > rect.x1 && y1 < rect.y2 && y2 > rect.y1);
+ };
+
this_type& operator-=(const point_type &point) XBMC_FORCE_INLINE
{
x1 -= point.x;
diff --git a/xbmc/utils/GroupUtils.cpp b/xbmc/utils/GroupUtils.cpp
index b3c00efc18..348b574880 100644
--- a/xbmc/utils/GroupUtils.cpp
+++ b/xbmc/utils/GroupUtils.cpp
@@ -9,15 +9,19 @@
#include "GroupUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/MultiPathDirectory.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include <map>
#include <set>
+using namespace KODI;
+
using SetMap = std::map<int, std::set<CFileItemPtr> >;
bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, CFileItemList &groupedItems, GroupAttribute groupAttributes /* = GroupAttributeNone */)
@@ -127,7 +131,7 @@ bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileI
//accumulate the path for a multipath construction
CFileItem video(movieInfo->m_basePath, false);
- if (video.IsVideo())
+ if (VIDEO::IsVideo(video))
pathSet.insert(URIUtils::GetParentPath(movieInfo->m_basePath));
else
pathSet.insert(movieInfo->m_basePath);
diff --git a/xbmc/utils/PlayerUtils.cpp b/xbmc/utils/PlayerUtils.cpp
index b2f087d161..de3b720300 100644
--- a/xbmc/utils/PlayerUtils.cpp
+++ b/xbmc/utils/PlayerUtils.cpp
@@ -14,6 +14,8 @@
#include "utils/Variant.h"
#include "video/guilib/VideoGUIUtils.h"
+using namespace KODI;
+
bool CPlayerUtils::IsItemPlayable(const CFileItem& itemIn)
{
const CFileItem item(itemIn.GetItemToPlay());
@@ -31,7 +33,7 @@ bool CPlayerUtils::IsItemPlayable(const CFileItem& itemIn)
return true;
// Movies / TV Shows / Music Videos
- if (VIDEO_UTILS::IsItemPlayable(item))
+ if (VIDEO::UTILS::IsItemPlayable(item))
return true;
//! @todo add more types on demand.
diff --git a/xbmc/utils/RecentlyAddedJob.cpp b/xbmc/utils/RecentlyAddedJob.cpp
index fca1f6d997..3a845ac2ac 100644
--- a/xbmc/utils/RecentlyAddedJob.cpp
+++ b/xbmc/utils/RecentlyAddedJob.cpp
@@ -9,6 +9,7 @@
#include "RecentlyAddedJob.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindow.h"
diff --git a/xbmc/utils/SaveFileStateJob.cpp b/xbmc/utils/SaveFileStateJob.cpp
index aa23b11508..b71620769d 100644
--- a/xbmc/utils/SaveFileStateJob.cpp
+++ b/xbmc/utils/SaveFileStateJob.cpp
@@ -23,11 +23,16 @@
#include "interfaces/AnnouncementManager.h"
#include "log.h"
#include "music/MusicDatabase.h"
+#include "music/MusicFileItemClassify.h"
#include "music/tags/MusicInfoTag.h"
#include "network/upnp/UPnP.h"
#include "utils/Variant.h"
#include "video/Bookmark.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
+
+using namespace KODI;
+using namespace KODI::VIDEO;
void CSaveFileState::DoWork(CFileItem& item,
CBookmark& bookmark,
@@ -35,15 +40,24 @@ void CSaveFileState::DoWork(CFileItem& item,
{
std::string progressTrackingFile = item.GetPath();
- if (item.HasVideoInfoTag() && StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://"))
- progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified
- else if (item.HasVideoInfoTag() && item.IsVideoDb())
- progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // we need the file url of the video db item to create the bookmark
+ if (item.HasVideoInfoTag() &&
+ StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://"))
+ progressTrackingFile =
+ item.GetVideoInfoTag()
+ ->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified
+ else if (IsBlurayPlaylist(item) && (item.GetVideoContentType() == VideoDbContentType::MOVIES ||
+ item.GetVideoContentType() == VideoDbContentType::EPISODES))
+ progressTrackingFile = item.GetDynPath();
+ else if (item.HasVideoInfoTag() && IsVideoDb(item))
+ progressTrackingFile =
+ item.GetVideoInfoTag()
+ ->m_strFileNameAndPath; // we need the file url of the video db item to create the bookmark
else if (item.HasProperty("original_listitem_url"))
{
// only use original_listitem_url for Python, UPnP and Bluray sources
std::string original = item.GetProperty("original_listitem_url").asString();
- if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) || URIUtils::IsBluray(item.GetPath()))
+ if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) ||
+ URIUtils::IsBluray(item.GetPath()))
progressTrackingFile = original;
}
@@ -57,7 +71,7 @@ void CSaveFileState::DoWork(CFileItem& item,
return;
}
#endif
- if (item.IsVideo())
+ if (IsVideo(item))
{
std::string redactPath = CURL::GetRedacted(progressTrackingFile);
CLog::Log(LOGDEBUG, "{} - Saving file state for video item {}", __FUNCTION__, redactPath);
@@ -159,7 +173,14 @@ void CSaveFileState::DoWork(CFileItem& item,
if (!videodatabase.GetStreamDetails(dbItem) ||
dbItem.GetVideoInfoTag()->m_streamDetails != item.GetVideoInfoTag()->m_streamDetails)
{
- videodatabase.SetStreamDetailsForFile(item.GetVideoInfoTag()->m_streamDetails, progressTrackingFile);
+ const int idFile = videodatabase.SetStreamDetailsForFile(
+ item.GetVideoInfoTag()->m_streamDetails, item.GetDynPath());
+ if (item.GetVideoContentType() == VideoDbContentType::MOVIES)
+ videodatabase.SetFileForMovie(item.GetDynPath(), item.GetVideoInfoTag()->m_iDbId,
+ idFile);
+ else if (item.GetVideoContentType() == VideoDbContentType::EPISODES)
+ videodatabase.SetFileForEpisode(item.GetDynPath(), item.GetVideoInfoTag()->m_iDbId,
+ idFile);
updateListing = true;
}
}
@@ -189,7 +210,7 @@ void CSaveFileState::DoWork(CFileItem& item,
}
}
- if (item.IsAudio())
+ if (MUSIC::IsAudio(item))
{
std::string redactPath = CURL::GetRedacted(progressTrackingFile);
CLog::Log(LOGDEBUG, "{} - Saving file state for audio item {}", __FUNCTION__, redactPath);
@@ -212,7 +233,7 @@ void CSaveFileState::DoWork(CFileItem& item,
// UPnP announce resume point changes to clients
// however not if playcount is modified as that already announces
- if (item.IsMusicDb())
+ if (MUSIC::IsMusicDb(item))
{
CVariant data;
data["id"] = item.GetMusicInfoTag()->GetDatabaseId();
@@ -223,7 +244,7 @@ void CSaveFileState::DoWork(CFileItem& item,
}
}
- if (item.IsAudioBook())
+ if (MUSIC::IsAudioBook(item))
{
musicdatabase.Open();
musicdatabase.SetResumeBookmarkForAudioBook(
diff --git a/xbmc/utils/TransformMatrix.h b/xbmc/utils/TransformMatrix.h
index a9bf8fdc74..0287ad55c5 100644
--- a/xbmc/utils/TransformMatrix.h
+++ b/xbmc/utils/TransformMatrix.h
@@ -36,6 +36,7 @@ public:
m[2][0] = m[2][1] = m[2][3] = 0.0f; m[2][2] = 1.0f;
alpha = red = green = blue = 1.0f;
identity = true;
+ depth = 0;
};
static TransformMatrix CreateTranslation(float transX, float transY, float transZ = 0)
{
@@ -50,6 +51,7 @@ public:
m[2][0] = m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = transZ;
alpha = red = green = blue = 1.0f;
identity = (transX == 0 && transY == 0 && transZ == 0);
+ depth = 0;
}
static TransformMatrix CreateScaler(float scaleX, float scaleY, float scaleZ = 1.0f)
{
@@ -69,6 +71,7 @@ public:
m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = scaleZ; m[2][3] = centerZ*(1-scaleZ);
alpha = red = green = blue = 1.0f;
identity = (scaleX == 1 && scaleY == 1);
+ depth = 0;
};
void SetXRotation(float angle, float y, float z, float ar = 1.0f)
{ // angle about the X axis, centered at y,z where our coordinate system has aspect ratio ar.
@@ -79,6 +82,7 @@ public:
m[2][0] = 0.0f; m[2][1] = s; m[2][2] = c; m[2][3] = (-y*s-c*z) + z;
alpha = red = green = blue = 1.0f;
identity = (angle == 0);
+ depth = 0;
}
void SetYRotation(float angle, float x, float z, float ar = 1.0f)
{ // angle about the Y axis, centered at x,z where our coordinate system has aspect ratio ar.
@@ -89,6 +93,7 @@ public:
m[2][0] = ar*s; m[2][1] = 0.0f; m[2][2] = c; m[2][3] = -ar*x*s - c*z + z;
alpha = red = green = blue = 1.0f;
identity = (angle == 0);
+ depth = 0;
}
static TransformMatrix CreateZRotation(float angle, float x, float y, float ar = 1.0f)
{ // angle about the Z axis, centered at x,y where our coordinate system has aspect ratio ar.
@@ -106,6 +111,7 @@ public:
m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = 0.0f;
alpha = red = green = blue = 1.0f;
identity = (angle == 0);
+ depth = 0;
}
static TransformMatrix CreateFader(float a)
{
@@ -127,6 +133,7 @@ public:
alpha = a;
red = green = blue = 1.0f;
identity = (a == 1.0f);
+ depth = 0;
}
void SetFader(float a, float r, float g, float b)
@@ -139,6 +146,7 @@ public:
green = g;
blue = b;
identity = ((a == 1.0f) && (r == 1.0f) && (g == 1.0f) && (b == 1.0f));
+ depth = 0;
}
// multiplication operators
@@ -171,6 +179,7 @@ public:
green *= right.green;
blue *= right.blue;
identity = false;
+ depth = std::max(depth, right.depth);
return *this;
}
@@ -198,6 +207,7 @@ public:
result.green = green * right.green;
result.blue = blue * right.blue;
result.identity = false;
+ result.depth = std::max(depth, right.depth);
return result;
}
@@ -278,12 +288,14 @@ public:
float green;
float blue;
bool identity;
+ uint32_t depth{0};
};
inline bool operator==(const TransformMatrix &a, const TransformMatrix &b)
{
bool comparison =
a.alpha == b.alpha && a.red == b.red && a.green == b.green && a.blue == b.blue &&
+ a.depth == b.depth &&
((a.identity && b.identity) ||
(!a.identity && !b.identity &&
std::equal(&a.m[0][0], &a.m[0][0] + sizeof(a.m) / sizeof(a.m[0][0]), &b.m[0][0])));
diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp
index ca65b57b65..9b862a7f43 100644
--- a/xbmc/utils/URIUtils.cpp
+++ b/xbmc/utils/URIUtils.cpp
@@ -6,19 +6,21 @@
* See LICENSES/README.md for more information.
*/
-#include "network/Network.h"
#include "URIUtils.h"
+
#include "FileItem.h"
+#include "FileItemList.h"
+#include "ServiceBroker.h"
+#include "StringUtils.h"
+#include "URL.h"
#include "filesystem/MultiPathDirectory.h"
#include "filesystem/SpecialProtocol.h"
#include "filesystem/StackDirectory.h"
#include "network/DNSNameCache.h"
+#include "network/Network.h"
#include "pvr/channels/PVRChannelsPath.h"
#include "settings/AdvancedSettings.h"
-#include "URL.h"
#include "utils/FileExtensionProvider.h"
-#include "ServiceBroker.h"
-#include "StringUtils.h"
#include "utils/log.h"
#if defined(TARGET_WINDOWS)
diff --git a/xbmc/utils/test/TestVariant.cpp b/xbmc/utils/test/TestVariant.cpp
index f5bf687ea6..60eafddf04 100644
--- a/xbmc/utils/test/TestVariant.cpp
+++ b/xbmc/utils/test/TestVariant.cpp
@@ -294,7 +294,7 @@ TEST(TestVariant, empty)
std::map<std::string, std::string> strmap;
EXPECT_TRUE(CVariant(strmap).empty());
- strmap.emplace(std::string("key"), std::string("value"));
+ strmap.emplace("key", "value");
EXPECT_FALSE(CVariant(strmap).empty());
std::string str;
diff --git a/xbmc/video/CMakeLists.txt b/xbmc/video/CMakeLists.txt
index 8586c30626..d867cdbace 100644
--- a/xbmc/video/CMakeLists.txt
+++ b/xbmc/video/CMakeLists.txt
@@ -7,6 +7,7 @@ set(SOURCES Bookmark.cpp
VideoDatabase.cpp
VideoDbUrl.cpp
VideoEmbeddedImageFileLoader.cpp
+ VideoFileItemClassify.cpp
VideoGeneratedImageFileLoader.cpp
VideoInfoDownloader.cpp
VideoInfoScanner.cpp
@@ -28,6 +29,7 @@ set(HEADERS Bookmark.h
VideoDatabase.h
VideoDbUrl.h
VideoEmbeddedImageFileLoader.h
+ VideoFileItemClassify.h
VideoGeneratedImageFileLoader.h
VideoInfoDownloader.h
VideoInfoScanner.h
diff --git a/xbmc/video/ContextMenus.cpp b/xbmc/video/ContextMenus.cpp
index a7a724e082..6bfd70fafd 100644
--- a/xbmc/video/ContextMenus.cpp
+++ b/xbmc/video/ContextMenus.cpp
@@ -18,12 +18,14 @@
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
+#include "music/MusicFileItemClassify.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/ContentUtils.h"
#include "utils/ExecString.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoManagerTypes.h"
#include "video/VideoUtils.h"
@@ -35,6 +37,8 @@
#include <utility>
+using namespace KODI;
+
namespace CONTEXTMENU
{
@@ -67,7 +71,7 @@ bool CVideoRemoveResumePoint::IsVisible(const CFileItem& itemIn) const
return false;
// Folders don't have a resume point
- return !item.m_bIsFolder && VIDEO_UTILS::GetItemResumeInformation(item).isResumable;
+ return !item.m_bIsFolder && VIDEO::UTILS::GetItemResumeInformation(item).isResumable;
}
bool CVideoRemoveResumePoint::Execute(const std::shared_ptr<CFileItem>& item) const
@@ -87,7 +91,7 @@ bool CVideoMarkWatched::IsVisible(const CFileItem& item) const
if (item.m_bIsFolder) // Only allow video db content, video and recording folders to be updated recursively
{
if (item.HasVideoInfoTag())
- return item.IsVideoDb();
+ return VIDEO::IsVideoDb(item);
else if (item.GetProperty("IsVideoFolder").asBoolean())
return true;
else
@@ -116,7 +120,7 @@ bool CVideoMarkUnWatched::IsVisible(const CFileItem& item) const
if (item.m_bIsFolder) // Only allow video db content, video and recording folders to be updated recursively
{
if (item.HasVideoInfoTag())
- return item.IsVideoDb();
+ return VIDEO::IsVideoDb(item);
else if (item.GetProperty("IsVideoFolder").asBoolean())
return true;
else
@@ -137,7 +141,7 @@ bool CVideoMarkUnWatched::Execute(const std::shared_ptr<CFileItem>& item) const
bool CVideoBrowse::IsVisible(const CFileItem& item) const
{
return ((item.m_bIsFolder || item.IsFileFolder(EFILEFOLDER_MASK_ONBROWSE)) &&
- VIDEO_UTILS::IsItemPlayable(item));
+ VIDEO::UTILS::IsItemPlayable(item));
}
bool CVideoBrowse::Execute(const std::shared_ptr<CFileItem>& item) const
@@ -254,7 +258,7 @@ bool CVideoChooseVersion::Execute(const std::shared_ptr<CFileItem>& item) const
std::string CVideoResume::GetLabel(const CFileItem& item) const
{
- return VIDEO_UTILS::GetResumeString(item.GetItemToPlay());
+ return VIDEO::UTILS::GetResumeString(item.GetItemToPlay());
}
bool CVideoResume::IsVisible(const CFileItem& itemIn) const
@@ -263,7 +267,7 @@ bool CVideoResume::IsVisible(const CFileItem& itemIn) const
if (item.IsDeleted()) // e.g. trashed pvr recording
return false;
- return VIDEO_UTILS::GetItemResumeInformation(item).isResumable;
+ return VIDEO::UTILS::GetItemResumeInformation(item).isResumable;
}
namespace
@@ -272,7 +276,7 @@ std::vector<std::string> GetPlayers(const CPlayerCoreFactory& playerCoreFactory,
const CFileItem& item)
{
std::vector<std::string> players;
- if (item.IsVideoDb())
+ if (VIDEO::IsVideoDb(item))
{
//! @todo CPlayerCoreFactory and classes called from there do not handle dyn path correctly.
CFileItem item2{item};
@@ -327,7 +331,7 @@ private:
const ContentUtils::PlayMode mode{m_item->GetProperty("CheckAutoPlayNextItem").asBoolean()
? ContentUtils::PlayMode::CHECK_AUTO_PLAY_NEXT_ITEM
: ContentUtils::PlayMode::PLAY_ONLY_THIS};
- VIDEO_UTILS::PlayItem(m_item, player, mode);
+ VIDEO::UTILS::PlayItem(m_item, player, mode);
}
const bool m_choosePlayer{false};
@@ -351,7 +355,7 @@ void SetPathAndPlay(const std::shared_ptr<CFileItem>& item, PlayMode mode)
else
{
const auto itemCopy{std::make_shared<CFileItem>(*item)};
- if (itemCopy->IsVideoDb())
+ if (VIDEO::IsVideoDb(*itemCopy))
{
if (!itemCopy->m_bIsFolder)
{
@@ -379,7 +383,7 @@ void SetPathAndPlay(const std::shared_ptr<CFileItem>& item, PlayMode mode)
const bool choosePlayer{mode == PlayMode::PLAY_USING || mode == PlayMode::PLAY_VERSION_USING};
CVideoPlayActionProcessor proc{itemCopy, choosePlayer};
if (mode == PlayMode::RESUME && (itemCopy->GetStartOffset() == STARTOFFSET_RESUME ||
- VIDEO_UTILS::GetItemResumeInformation(*item).isResumable))
+ VIDEO::UTILS::GetItemResumeInformation(*item).isResumable))
proc.ProcessAction(VIDEO::GUILIB::ACTION_RESUME);
else // all other modes are actually PLAY
proc.ProcessAction(VIDEO::GUILIB::ACTION_PLAY_FROM_BEGINNING);
@@ -391,7 +395,7 @@ bool CVideoResume::Execute(const std::shared_ptr<CFileItem>& itemIn) const
{
const auto item{std::make_shared<CFileItem>(itemIn->GetItemToPlay())};
#ifdef HAS_OPTICAL_DRIVE
- if (item->IsDVD() || item->IsCDDA())
+ if (item->IsDVD() || MUSIC::IsCDDA(*item))
return MEDIA_DETECT::CAutorun::PlayDisc(item->GetPath(), true, false);
#endif
@@ -405,21 +409,21 @@ std::string CVideoPlay::GetLabel(const CFileItem& itemIn) const
CFileItem item(itemIn.GetItemToPlay());
if (item.IsLiveTV())
return g_localizeStrings.Get(19000); // Switch to channel
- if (VIDEO_UTILS::GetItemResumeInformation(item).isResumable)
+ if (VIDEO::UTILS::GetItemResumeInformation(item).isResumable)
return g_localizeStrings.Get(12021); // Play from beginning
return g_localizeStrings.Get(208); // Play
}
bool CVideoPlay::IsVisible(const CFileItem& item) const
{
- return VIDEO_UTILS::IsItemPlayable(item);
+ return VIDEO::UTILS::IsItemPlayable(item);
}
bool CVideoPlay::Execute(const std::shared_ptr<CFileItem>& itemIn) const
{
const auto item{std::make_shared<CFileItem>(itemIn->GetItemToPlay())};
#ifdef HAS_OPTICAL_DRIVE
- if (item->IsDVD() || item->IsCDDA())
+ if (item->IsDVD() || MUSIC::IsCDDA(*item))
return MEDIA_DETECT::CAutorun::PlayDisc(item->GetPath(), true, true);
#endif
SetPathAndPlay(item, PlayMode::PLAY);
@@ -438,7 +442,7 @@ bool CVideoPlayUsing::IsVisible(const CFileItem& item) const
return false;
const CPlayerCoreFactory& playerCoreFactory{CServiceBroker::GetPlayerCoreFactory()};
- return (GetPlayers(playerCoreFactory, item).size() > 1) && VIDEO_UTILS::IsItemPlayable(item);
+ return (GetPlayers(playerCoreFactory, item).size() > 1) && VIDEO::UTILS::IsItemPlayable(item);
}
bool CVideoPlayUsing::Execute(const std::shared_ptr<CFileItem>& itemIn) const
@@ -502,12 +506,12 @@ bool CVideoQueue::IsVisible(const CFileItem& item) const
if (!CanQueue(item))
return false;
- return VIDEO_UTILS::IsItemPlayable(item);
+ return VIDEO::UTILS::IsItemPlayable(item);
}
bool CVideoQueue::Execute(const std::shared_ptr<CFileItem>& item) const
{
- VIDEO_UTILS::QueueItem(item, VIDEO_UTILS::QueuePosition::POSITION_END);
+ VIDEO::UTILS::QueueItem(item, VIDEO::UTILS::QueuePosition::POSITION_END);
// Set selection to next item in active window's view.
const int windowID = CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow();
@@ -521,18 +525,18 @@ bool CVideoPlayNext::IsVisible(const CFileItem& item) const
if (!CanQueue(item))
return false;
- return VIDEO_UTILS::IsItemPlayable(item);
+ return VIDEO::UTILS::IsItemPlayable(item);
}
bool CVideoPlayNext::Execute(const std::shared_ptr<CFileItem>& item) const
{
- VIDEO_UTILS::QueueItem(item, VIDEO_UTILS::QueuePosition::POSITION_BEGIN);
+ VIDEO::UTILS::QueueItem(item, VIDEO::UTILS::QueuePosition::POSITION_BEGIN);
return true;
};
std::string CVideoPlayAndQueue::GetLabel(const CFileItem& item) const
{
- if (VIDEO_UTILS::IsAutoPlayNextItem(item))
+ if (VIDEO::UTILS::IsAutoPlayNextItem(item))
return g_localizeStrings.Get(13434); // Play only this
else
return g_localizeStrings.Get(13412); // Play from here
@@ -557,10 +561,10 @@ bool CVideoPlayAndQueue::Execute(const std::shared_ptr<CFileItem>& item) const
if ((windowId == WINDOW_TV_RECORDINGS || windowId == WINDOW_RADIO_RECORDINGS) &&
item->IsUsablePVRRecording())
{
- const ContentUtils::PlayMode mode = VIDEO_UTILS::IsAutoPlayNextItem(*item)
+ const ContentUtils::PlayMode mode = VIDEO::UTILS::IsAutoPlayNextItem(*item)
? ContentUtils::PlayMode::PLAY_ONLY_THIS
: ContentUtils::PlayMode::PLAY_FROM_HERE;
- VIDEO_UTILS::PlayItem(item, "", mode);
+ VIDEO::UTILS::PlayItem(item, "", mode);
return true;
}
diff --git a/xbmc/video/Episode.h b/xbmc/video/Episode.h
index 833f9e3306..f7722bd81a 100644
--- a/xbmc/video/Episode.h
+++ b/xbmc/video/Episode.h
@@ -18,7 +18,7 @@
class CFileItem;
// single episode information
-namespace VIDEO
+namespace KODI::VIDEO
{
struct EPISODE
{
diff --git a/xbmc/video/GUIViewStateVideo.cpp b/xbmc/video/GUIViewStateVideo.cpp
index 278bec56b4..1cf1a0115c 100644
--- a/xbmc/video/GUIViewStateVideo.cpp
+++ b/xbmc/video/GUIViewStateVideo.cpp
@@ -9,6 +9,7 @@
#include "GUIViewStateVideo.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "VideoDatabase.h"
#include "filesystem/Directory.h"
@@ -21,8 +22,10 @@
#include "settings/SettingsComponent.h"
#include "utils/FileExtensionProvider.h"
#include "utils/SortUtils.h"
+#include "video/VideoFileItemClassify.h"
#include "view/ViewStateSettings.h"
+using namespace KODI::VIDEO;
using namespace XFILE;
using namespace VIDEODATABASEDIRECTORY;
@@ -69,7 +72,7 @@ CGUIViewStateWindowVideoNav::CGUIViewStateWindowVideoNav(const CFileItemList& it
SetSortOrder(SortOrderNone);
}
- else if (items.IsVideoDb())
+ else if (IsVideoDb(items))
{
NODE_TYPE NodeType=CVideoDatabaseDirectory::GetDirectoryChildType(items.GetPath());
CQueryParams params;
@@ -337,7 +340,7 @@ CGUIViewStateWindowVideoNav::CGUIViewStateWindowVideoNav(const CFileItemList& it
void CGUIViewStateWindowVideoNav::SaveViewState()
{
- if (m_items.IsVideoDb())
+ if (IsVideoDb(m_items))
{
NODE_TYPE NodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_items.GetPath());
CQueryParams params;
diff --git a/xbmc/video/VideoChapterImageFileLoader.cpp b/xbmc/video/VideoChapterImageFileLoader.cpp
index 49bfd2dc06..92f1d5c4d2 100644
--- a/xbmc/video/VideoChapterImageFileLoader.cpp
+++ b/xbmc/video/VideoChapterImageFileLoader.cpp
@@ -16,16 +16,18 @@
#include "settings/SettingsComponent.h"
#include "utils/log.h"
+namespace KODI::VIDEO
+{
+
bool VIDEO::CVideoChapterImageFileLoader::CanLoad(const std::string& specialType) const
{
return specialType == "videochapter";
}
-std::unique_ptr<CTexture> VIDEO::CVideoChapterImageFileLoader::Load(
- const std::string& specialType,
- const std::string& goofyChapterPath,
- unsigned int,
- unsigned int) const
+std::unique_ptr<CTexture> CVideoChapterImageFileLoader::Load(const std::string& specialType,
+ const std::string& goofyChapterPath,
+ unsigned int,
+ unsigned int) const
{
// "goofy" chapter path because these paths don't yet conform to 'image://' path standard
@@ -52,3 +54,5 @@ std::unique_ptr<CTexture> VIDEO::CVideoChapterImageFileLoader::Load(
CFileItem item{cleanname, false};
return CDVDFileInfo::ExtractThumbToTexture(item, chapterNum);
}
+
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoChapterImageFileLoader.h b/xbmc/video/VideoChapterImageFileLoader.h
index 9cd2eab496..ce64991005 100644
--- a/xbmc/video/VideoChapterImageFileLoader.h
+++ b/xbmc/video/VideoChapterImageFileLoader.h
@@ -10,7 +10,7 @@
#include "imagefiles/SpecialImageFileLoader.h"
-namespace VIDEO
+namespace KODI::VIDEO
{
/*!
* @brief Generates a texture for a thumbnail of a video chapter.
@@ -28,4 +28,4 @@ public:
unsigned int preferredHeight) const override;
};
-} // namespace VIDEO
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp
index 1372e54173..d23851bbc0 100644
--- a/xbmc/video/VideoDatabase.cpp
+++ b/xbmc/video/VideoDatabase.cpp
@@ -9,6 +9,7 @@
#include "VideoDatabase.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
@@ -52,6 +53,7 @@
#include "utils/XMLUtils.h"
#include "utils/log.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoLibraryQueue.h"
#include "video/VideoManagerTypes.h"
@@ -66,10 +68,11 @@
using namespace dbiplus;
using namespace XFILE;
-using namespace VIDEO;
using namespace ADDON;
+using namespace KODI;
using namespace KODI::MESSAGING;
using namespace KODI::GUILIB;
+using namespace KODI::VIDEO;
//********************************************************************************************************************************
CVideoDatabase::CVideoDatabase(void) = default;
@@ -366,6 +369,10 @@ void CVideoDatabase::CreateAnalytics()
"DELETE FROM videoversion WHERE idFile=old.idFile; "
"DELETE FROM art WHERE media_id=old.idFile AND media_type='videoversion'; "
"END");
+ m_pDS->exec("CREATE TRIGGER delete_videoversion AFTER DELETE ON videoversion FOR EACH ROW BEGIN "
+ "DELETE FROM art WHERE media_id=old.idFile AND media_type='videoversion'; "
+ "DELETE FROM streamdetails WHERE idFile=old.idFile; "
+ "END");
CreateViews();
}
@@ -1040,7 +1047,7 @@ int CVideoDatabase::AddFile(const std::string& strFileNameAndPath,
int CVideoDatabase::AddFile(const CFileItem& item)
{
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
{
const auto videoInfoTag = item.GetVideoInfoTag();
if (videoInfoTag->m_iFileId != -1)
@@ -3017,6 +3024,49 @@ int CVideoDatabase::SetDetailsForSeason(const CVideoInfoTag& details, const std:
return -1;
}
+bool CVideoDatabase::SetFileForEpisode(const std::string& fileAndPath, int idEpisode, int idFile)
+{
+ try
+ {
+ BeginTransaction();
+ std::string sql = PrepareSQL("UPDATE episode SET c18='%s', idFile=%i WHERE idEpisode=%i",
+ fileAndPath.c_str(), idFile, idEpisode);
+ m_pDS->exec(sql);
+ CommitTransaction();
+
+ return true;
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "{} ({}) failed", __FUNCTION__, idEpisode);
+ }
+ RollbackTransaction();
+ return false;
+}
+
+bool CVideoDatabase::SetFileForMovie(const std::string& fileAndPath, int idMovie, int idFile)
+{
+ try
+ {
+ BeginTransaction();
+ std::string sql = PrepareSQL("UPDATE movie SET c22='%s', idFile=%i WHERE idMovie=%i",
+ fileAndPath.c_str(), idFile, idMovie);
+ m_pDS->exec(sql);
+ sql = PrepareSQL("UPDATE videoversion SET idFile=%i WHERE idMedia=%i AND media_type='movie'",
+ idFile, idMovie);
+ m_pDS->exec(sql);
+ CommitTransaction();
+
+ return true;
+ }
+ catch (...)
+ {
+ CLog::Log(LOGERROR, "{} ({}) failed", __FUNCTION__, idMovie);
+ }
+ RollbackTransaction();
+ return false;
+}
+
int CVideoDatabase::SetDetailsForEpisode(CVideoInfoTag& details,
const std::map<std::string, std::string>& artwork,
int idShow,
@@ -3206,13 +3256,15 @@ int CVideoDatabase::SetDetailsForMusicVideo(CVideoInfoTag& details,
return -1;
}
-void CVideoDatabase::SetStreamDetailsForFile(const CStreamDetails& details, const std::string &strFileNameAndPath)
+int CVideoDatabase::SetStreamDetailsForFile(const CStreamDetails& details,
+ const std::string& strFileNameAndPath)
{
// AddFile checks to make sure the file isn't already in the DB first
int idFile = AddFile(strFileNameAndPath);
if (idFile < 0)
- return;
+ return -1;
SetStreamDetailsForFileId(details, idFile);
+ return idFile;
}
void CVideoDatabase::SetStreamDetailsForFileId(const CStreamDetails& details, int idFile)
@@ -3672,19 +3724,38 @@ void CVideoDatabase::DeleteMovie(int idMovie,
// the ancillary tables are still purged
if (!bKeepId)
{
- std::string path = GetSingleValue(PrepareSQL("SELECT strPath FROM path JOIN files ON files.idPath=path.idPath WHERE files.idFile=%i", idFile));
+ const std::string path = GetSingleValue(PrepareSQL(
+ "SELECT strPath FROM path JOIN files ON files.idPath=path.idPath WHERE files.idFile=%i",
+ idFile));
if (!path.empty())
InvalidatePathHash(path);
- std::string strSQL = PrepareSQL("delete from movie where idMovie=%i", idMovie);
+ const std::string strSQL = PrepareSQL("delete from movie where idMovie=%i", idMovie);
m_pDS->exec(strSQL);
if (ca == DeleteMovieCascadeAction::ALL_ASSETS)
{
- const std::string strSQL{
- PrepareSQL("DELETE FROM videoversion WHERE idMedia = %i AND media_type = '%s'", idMovie,
- MediaTypeMovie)};
- m_pDS->exec(strSQL);
+ // The default version of the movie was removed by a delete trigger.
+ // Clean up the other assets attached to the movie, if any.
+
+ // need local dataset due to nested DeleteVideoAsset query
+ std::unique_ptr<Dataset> pDS{m_pDB->CreateDataset()};
+
+ pDS->query(
+ PrepareSQL("SELECT idFile FROM videoversion WHERE idMedia=%i AND media_type='%s'",
+ idMovie, MediaTypeMovie));
+
+ while (!pDS->eof())
+ {
+ if (!DeleteVideoAsset(pDS->fv(0).get_asInt()))
+ {
+ RollbackTransaction();
+ pDS->close();
+ return;
+ }
+ pDS->next();
+ }
+ pDS->close();
}
}
@@ -3697,7 +3768,7 @@ void CVideoDatabase::DeleteMovie(int idMovie,
}
catch (...)
{
- CLog::Log(LOGERROR, "{} failed", __FUNCTION__);
+ CLog::LogF(LOGERROR, "failed");
RollbackTransaction();
}
}
@@ -4172,7 +4243,6 @@ bool CVideoDatabase::GetStreamDetails(CFileItem& item)
if (item.HasVideoInfoTag())
fileId = item.GetVideoInfoTag()->m_iFileId;
-
if (fileId < 0)
fileId = GetFileId(item);
@@ -4184,9 +4254,17 @@ bool CVideoDatabase::GetStreamDetails(CFileItem& item)
return GetStreamDetails(*item.GetVideoInfoTag());
}
-bool CVideoDatabase::GetStreamDetails(CVideoInfoTag& tag) const
+bool CVideoDatabase::GetStreamDetails(CVideoInfoTag& tag)
{
- if (tag.m_iFileId < 0)
+
+ const std::string path = tag.m_strFileNameAndPath;
+ int fileId{-1};
+ if (URIUtils::GetExtension(path) == ".mpls")
+ fileId = GetFileId(path);
+ else
+ fileId = tag.m_iFileId;
+
+ if (fileId < 0)
return false;
bool retVal = false;
@@ -4197,7 +4275,7 @@ bool CVideoDatabase::GetStreamDetails(CVideoInfoTag& tag) const
std::unique_ptr<Dataset> pDS(m_pDB->CreateDataset());
try
{
- std::string strSQL = PrepareSQL("SELECT * FROM streamdetails WHERE idFile = %i", tag.m_iFileId);
+ std::string strSQL = PrepareSQL("SELECT * FROM streamdetails WHERE idFile = %i", fileId);
pDS->query(strSQL);
while (!pDS->eof())
@@ -6378,7 +6456,7 @@ void CVideoDatabase::UpdateTables(int iVersion)
int CVideoDatabase::GetSchemaVersion() const
{
- return 131;
+ return 132;
}
bool CVideoDatabase::LookupByFolders(const std::string &path, bool shows)
@@ -6527,7 +6605,10 @@ int CVideoDatabase::GetPlayCount(const std::string& strFilenameAndPath)
int CVideoDatabase::GetPlayCount(const CFileItem &item)
{
- return GetPlayCount(GetFileId(item));
+ if (IsBlurayPlaylist(item))
+ return GetPlayCount(GetFileId(item.GetDynPath()));
+ else
+ return GetPlayCount(GetFileId(item));
}
CDateTime CVideoDatabase::GetLastPlayed(int iFileId)
@@ -6597,9 +6678,11 @@ void CVideoDatabase::UpdateFanart(const CFileItem& item, VideoDbContentType type
CDateTime CVideoDatabase::SetPlayCount(const CFileItem& item, int count, const CDateTime& date)
{
- int id;
- if (item.HasProperty("original_listitem_url") &&
- URIUtils::IsPlugin(item.GetProperty("original_listitem_url").asString()))
+ int id{-1};
+ if (IsBlurayPlaylist(item))
+ id = AddFile(item.GetDynPath());
+ else if (item.HasProperty("original_listitem_url") &&
+ URIUtils::IsPlugin(item.GetProperty("original_listitem_url").asString()))
{
CFileItem item2(item);
item2.SetPath(item.GetProperty("original_listitem_url").asString());
@@ -12401,31 +12484,41 @@ bool CVideoDatabase::IsDefaultVideoVersion(int idFile)
return false;
}
-bool CVideoDatabase::RemoveVideoVersion(int dbId)
+bool CVideoDatabase::DeleteVideoAsset(int idFile)
{
if (!m_pDB || !m_pDS)
return false;
- if (IsDefaultVideoVersion(dbId))
+ if (IsDefaultVideoVersion(idFile))
return false;
+ const bool inTransaction{m_pDB->in_transaction()};
+
try
{
- std::string path = GetSingleValue(PrepareSQL(
+ if (!inTransaction)
+ BeginTransaction();
+
+ const std::string path = GetSingleValue(PrepareSQL(
"SELECT strPath FROM path JOIN files ON files.idPath=path.idPath WHERE files.idFile=%i",
- dbId));
+ idFile));
if (!path.empty())
InvalidatePathHash(path);
- m_pDS->exec(PrepareSQL("DELETE FROM videoversion WHERE idFile = %i", dbId));
+ m_pDS->exec(PrepareSQL("DELETE FROM videoversion WHERE idFile=%i", idFile));
+
+ if (!inTransaction)
+ CommitTransaction();
return true;
}
catch (...)
{
- CLog::Log(LOGERROR, "{} failed for {}", __FUNCTION__, dbId);
+ CLog::LogF(LOGERROR, "failed for {}", idFile);
+ if (!inTransaction)
+ RollbackTransaction();
+ return false;
}
- return false;
}
void CVideoDatabase::SetVideoVersion(int idFile, int idVideoVersion)
@@ -12444,31 +12537,17 @@ void CVideoDatabase::SetVideoVersion(int idFile, int idVideoVersion)
}
}
-void CVideoDatabase::AddPrimaryVideoVersion(VideoDbContentType itemType,
- int dbId,
- int idVideoVersion,
- CFileItem& item)
-{
- AddVideoVersion(itemType, dbId, idVideoVersion, VideoAssetType::VERSION, item);
-}
-
-void CVideoDatabase::AddExtrasVideoVersion(VideoDbContentType itemType,
- int dbId,
- int idVideoVersion,
- CFileItem& item)
-{
- AddVideoVersion(itemType, dbId, idVideoVersion, VideoAssetType::EXTRA, item);
-}
-
-void CVideoDatabase::AddVideoVersion(VideoDbContentType itemType,
- int dbId,
- int idVideoVersion,
- VideoAssetType videoAssetType,
- CFileItem& item)
+void CVideoDatabase::AddVideoAsset(VideoDbContentType itemType,
+ int dbId,
+ int idVideoVersion,
+ VideoAssetType videoAssetType,
+ CFileItem& item)
{
if (!m_pDB || !m_pDS)
return;
+ assert(m_pDB->in_transaction() == false);
+
MediaType mediaType;
if (itemType == VideoDbContentType::MOVIES)
{
@@ -12483,6 +12562,8 @@ void CVideoDatabase::AddVideoVersion(VideoDbContentType itemType,
try
{
+ BeginTransaction();
+
m_pDS->query(PrepareSQL("SELECT idFile FROM videoversion WHERE idFile = %i", idFile));
if (m_pDS->num_rows() == 0)
@@ -12498,10 +12579,13 @@ void CVideoDatabase::AddVideoVersion(VideoDbContentType itemType,
if (videoAssetType == VideoAssetType::VERSION)
SetVideoVersionDefaultArt(idFile, item.GetVideoInfoTag()->m_iDbId, itemType);
+
+ CommitTransaction();
}
catch (...)
{
- CLog::Log(LOGERROR, "{} failed for video {}", __FUNCTION__, dbId);
+ CLog::LogF(LOGERROR, "failed for video {}", dbId);
+ RollbackTransaction();
}
}
diff --git a/xbmc/video/VideoDatabase.h b/xbmc/video/VideoDatabase.h
index aa0bee416d..c6dd001391 100644
--- a/xbmc/video/VideoDatabase.h
+++ b/xbmc/video/VideoDatabase.h
@@ -56,7 +56,7 @@ namespace dbiplus
typedef std::vector<CVideoInfoTag> VECMOVIES;
-namespace VIDEO
+namespace KODI::VIDEO
{
class IVideoInfoScannerObserver;
struct SScanSettings;
@@ -584,10 +584,12 @@ public:
const std::map<std::string, std::string>& artwork,
int idShow,
int idEpisode = -1);
+ bool SetFileForEpisode(const std::string& fileAndPath, int idEpisode, int idFile);
+ bool SetFileForMovie(const std::string& fileAndPath, int idMovie, int idFile);
int SetDetailsForMusicVideo(CVideoInfoTag& details,
const std::map<std::string, std::string>& artwork,
int idMVideo = -1);
- void SetStreamDetailsForFile(const CStreamDetails& details, const std::string &strFileNameAndPath);
+ int SetStreamDetailsForFile(const CStreamDetails& details, const std::string& strFileNameAndPath);
void SetStreamDetailsForFileId(const CStreamDetails& details, int idFile);
bool SetSingleValue(VideoDbContentType type, int dbId, int dbField, const std::string& strValue);
@@ -686,14 +688,17 @@ public:
void DeleteBookMarkForEpisode(const CVideoInfoTag& tag);
bool GetResumePoint(CVideoInfoTag& tag);
bool GetStreamDetails(CFileItem& item);
- bool GetStreamDetails(CVideoInfoTag& tag) const;
+ bool GetStreamDetails(CVideoInfoTag& tag);
bool GetDetailsByTypeAndId(CFileItem& item, VideoDbContentType type, int id);
CVideoInfoTag GetDetailsByTypeAndId(VideoDbContentType type, int id);
// scraper settings
- void SetScraperForPath(const std::string& filePath, const ADDON::ScraperPtr& info, const VIDEO::SScanSettings& settings);
+ void SetScraperForPath(const std::string& filePath,
+ const ADDON::ScraperPtr& info,
+ const KODI::VIDEO::SScanSettings& settings);
ADDON::ScraperPtr GetScraperForPath(const std::string& strPath);
- ADDON::ScraperPtr GetScraperForPath(const std::string& strPath, VIDEO::SScanSettings& settings);
+ ADDON::ScraperPtr GetScraperForPath(const std::string& strPath,
+ KODI::VIDEO::SScanSettings& settings);
/*! \brief Retrieve the scraper and settings we should use for the specified path
If the scraper is not set on this particular path, we'll recursively check parent folders.
@@ -703,7 +708,9 @@ public:
\return A ScraperPtr containing the scraper information. Returns NULL if a trivial (Content == CONTENT_NONE)
scraper or no scraper is found.
*/
- ADDON::ScraperPtr GetScraperForPath(const std::string& strPath, VIDEO::SScanSettings& settings, bool& foundDirectly);
+ ADDON::ScraperPtr GetScraperForPath(const std::string& strPath,
+ KODI::VIDEO::SScanSettings& settings,
+ bool& foundDirectly);
/*! \brief Retrieve the content type of videos in the given path
If content is set on the folder, we return the given content type, except in the case of tvshows,
@@ -750,7 +757,9 @@ public:
bool GetSubPaths(const std::string& basepath, std::vector< std::pair<int, std::string> >& subpaths);
bool GetSourcePath(const std::string &path, std::string &sourcePath);
- bool GetSourcePath(const std::string &path, std::string &sourcePath, VIDEO::SScanSettings& settings);
+ bool GetSourcePath(const std::string& path,
+ std::string& sourcePath,
+ KODI::VIDEO::SScanSettings& settings);
// for music + musicvideo linkups - if no album and title given it will return the artist id, else the id of the matching video
int GetMatchingMusicVideo(const std::string& strArtist, const std::string& strAlbum = "", const std::string& strTitle = "");
@@ -1061,20 +1070,12 @@ public:
int AddVideoVersionType(const std::string& typeVideoVersion,
VideoAssetTypeOwner owner,
VideoAssetType assetType);
- void AddVideoVersion(VideoDbContentType itemType,
- int dbId,
- int idVideoVersion,
- VideoAssetType videoAssetType,
- CFileItem& item);
- void AddPrimaryVideoVersion(VideoDbContentType itemType,
- int dbId,
- int idVideoVersion,
- CFileItem& item);
- void AddExtrasVideoVersion(VideoDbContentType itemType,
- int dbId,
- int idVideoVersion,
- CFileItem& item);
- bool RemoveVideoVersion(int dbId);
+ void AddVideoAsset(VideoDbContentType itemType,
+ int dbId,
+ int idVideoVersion,
+ VideoAssetType videoAssetType,
+ CFileItem& item);
+ bool DeleteVideoAsset(int idFile);
bool IsDefaultVideoVersion(int idFile);
bool GetVideoVersionTypes(VideoDbContentType idContent,
VideoAssetType asset,
diff --git a/xbmc/video/VideoEmbeddedImageFileLoader.cpp b/xbmc/video/VideoEmbeddedImageFileLoader.cpp
index f5f9c813b2..0403024b03 100644
--- a/xbmc/video/VideoEmbeddedImageFileLoader.cpp
+++ b/xbmc/video/VideoEmbeddedImageFileLoader.cpp
@@ -16,7 +16,8 @@
#include "video/tags/IVideoInfoTagLoader.h"
#include "video/tags/VideoInfoTagLoaderFactory.h"
-using namespace VIDEO;
+namespace KODI::VIDEO
+{
bool CVideoEmbeddedImageFileLoader::CanLoad(const std::string& specialType) const
{
@@ -47,10 +48,11 @@ bool GetEmbeddedThumb(const std::string& path, const std::string& type, Embedded
}
} // namespace
-std::unique_ptr<CTexture> CVideoEmbeddedImageFileLoader::Load(const std::string& specialType,
- const std::string& filePath,
- unsigned int preferredWidth,
- unsigned int preferredHeight) const
+std::unique_ptr<CTexture> VIDEO::CVideoEmbeddedImageFileLoader::Load(
+ const std::string& specialType,
+ const std::string& filePath,
+ unsigned int preferredWidth,
+ unsigned int preferredHeight) const
{
EmbeddedArt art;
if (GetEmbeddedThumb(filePath, specialType.substr(6), art))
@@ -58,3 +60,5 @@ std::unique_ptr<CTexture> CVideoEmbeddedImageFileLoader::Load(const std::string&
preferredHeight);
return {};
}
+
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoEmbeddedImageFileLoader.h b/xbmc/video/VideoEmbeddedImageFileLoader.h
index 1a37a91c4e..f29a0c1a90 100644
--- a/xbmc/video/VideoEmbeddedImageFileLoader.h
+++ b/xbmc/video/VideoEmbeddedImageFileLoader.h
@@ -10,7 +10,7 @@
#include "imagefiles/SpecialImageFileLoader.h"
-namespace VIDEO
+namespace KODI::VIDEO
{
/*!
* @brief Generates a texture for an image embedded in a video file.
@@ -28,4 +28,4 @@ public:
unsigned int preferredHeight) const override;
};
-} // namespace VIDEO
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoFileItemClassify.cpp b/xbmc/video/VideoFileItemClassify.cpp
new file mode 100644
index 0000000000..afeaafcb65
--- /dev/null
+++ b/xbmc/video/VideoFileItemClassify.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2005-2020 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "video/VideoFileItemClassify.h"
+
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "URL.h"
+#include "utils/FileExtensionProvider.h"
+#include "utils/FileUtils.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "video/VideoInfoTag.h"
+
+namespace KODI::VIDEO
+{
+
+bool IsBDFile(const CFileItem& item)
+{
+ const std::string strFileName = URIUtils::GetFileName(item.GetDynPath());
+ return (StringUtils::EqualsNoCase(strFileName, "index.bdmv") ||
+ StringUtils::EqualsNoCase(strFileName, "MovieObject.bdmv") ||
+ StringUtils::EqualsNoCase(strFileName, "INDEX.BDM") ||
+ StringUtils::EqualsNoCase(strFileName, "MOVIEOBJ.BDM"));
+}
+
+bool IsDiscStub(const CFileItem& item)
+{
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
+ {
+ CFileItem dbItem(item.m_bIsFolder ? item.GetVideoInfoTag()->m_strPath
+ : item.GetVideoInfoTag()->m_strFileNameAndPath,
+ item.m_bIsFolder);
+ return IsDiscStub(dbItem);
+ }
+
+ return URIUtils::HasExtension(item.GetPath(),
+ CServiceBroker::GetFileExtensionProvider().GetDiscStubExtensions());
+}
+
+bool IsDVDFile(const CFileItem& item, bool bVobs /*= true*/, bool bIfos /*= true*/)
+{
+ const std::string strFileName = URIUtils::GetFileName(item.GetDynPath());
+ if (bIfos)
+ {
+ if (StringUtils::EqualsNoCase(strFileName, "video_ts.ifo"))
+ return true;
+ if (StringUtils::StartsWithNoCase(strFileName, "vts_") &&
+ StringUtils::EndsWithNoCase(strFileName, "_0.ifo") && strFileName.length() == 12)
+ return true;
+ }
+ if (bVobs)
+ {
+ if (StringUtils::EqualsNoCase(strFileName, "video_ts.vob"))
+ return true;
+ if (StringUtils::StartsWithNoCase(strFileName, "vts_") &&
+ StringUtils::EndsWithNoCase(strFileName, ".vob"))
+ return true;
+ }
+
+ return false;
+}
+
+bool IsProtectedBlurayDisc(const CFileItem& item)
+{
+ const std::string path = URIUtils::AddFileToFolder(item.GetPath(), "AACS", "Unit_Key_RO.inf");
+ return CFileUtils::Exists(path);
+}
+
+bool IsBlurayPlaylist(const CFileItem& item)
+{
+ return StringUtils::EqualsNoCase(URIUtils::GetExtension(item.GetDynPath()), ".mpls");
+}
+
+bool IsSubtitle(const CFileItem& item)
+{
+ return URIUtils::HasExtension(item.GetPath(),
+ CServiceBroker::GetFileExtensionProvider().GetSubtitleExtensions());
+}
+
+bool IsVideo(const CFileItem& item)
+{
+ /* check preset mime type */
+ if (StringUtils::StartsWithNoCase(item.GetMimeType(), "video/"))
+ return true;
+
+ if (item.HasVideoInfoTag())
+ return true;
+
+ if (item.HasGameInfoTag())
+ return false;
+
+ if (item.HasMusicInfoTag())
+ return false;
+
+ if (item.HasPictureInfoTag())
+ return false;
+
+ // TV recordings are videos...
+ if (!item.m_bIsFolder && URIUtils::IsPVRTVRecordingFileOrFolder(item.GetPath()))
+ return true;
+
+ // ... all other PVR items are not.
+ if (item.IsPVR())
+ return false;
+
+ if (URIUtils::IsDVD(item.GetPath()))
+ return true;
+
+ std::string extension;
+ if (StringUtils::StartsWithNoCase(item.GetMimeType(), "application/"))
+ { /* check for some standard types */
+ extension = item.GetMimeType().substr(12);
+ if (StringUtils::EqualsNoCase(extension, "ogg") ||
+ StringUtils::EqualsNoCase(extension, "mp4") || StringUtils::EqualsNoCase(extension, "mxf"))
+ return true;
+ }
+
+ //! @todo If the file is a zip file, ask the game clients if any support this
+ // file before assuming it is video.
+
+ return URIUtils::HasExtension(item.GetPath(),
+ CServiceBroker::GetFileExtensionProvider().GetVideoExtensions());
+}
+
+bool IsVideoAssetFile(const CFileItem& item)
+{
+ if (item.m_bIsFolder || !IsVideoDb(item))
+ return false;
+
+ // @todo maybe in the future look for prefix videodb://movies/videoversions in path instead
+ // @todo better encoding of video assets as path, they won't always be tied with movies.
+ return CURL(item.GetPath()).HasOption("videoversionid");
+}
+
+bool IsVideoDb(const CFileItem& item)
+{
+ return URIUtils::IsVideoDb(item.GetPath());
+}
+
+bool IsVideoExtrasFolder(const CFileItem& item)
+{
+ return item.m_bIsFolder &&
+ StringUtils::EqualsNoCase(URIUtils::GetFileOrFolderName(item.GetPath()), "extras");
+}
+
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoFileItemClassify.h b/xbmc/video/VideoFileItemClassify.h
new file mode 100644
index 0000000000..7a24113fde
--- /dev/null
+++ b/xbmc/video/VideoFileItemClassify.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+class CFileItem;
+
+namespace KODI::VIDEO
+{
+
+//! \brief Check whether an item is a blu-ray file.
+bool IsBDFile(const CFileItem& item);
+
+//! \brief Check whether an item is a disc stub.
+bool IsDiscStub(const CFileItem& item);
+
+//! \brief Check whether an item is a DVD file.
+bool IsDVDFile(const CFileItem& item, bool bVobs = true, bool bIfos = true);
+
+//! \brief Checks whether item points to a protected blu-ray disc.
+bool IsProtectedBlurayDisc(const CFileItem& item);
+
+//! \brief Checks whether item points to a blu-ray playlist (.mpls)
+bool IsBlurayPlaylist(const CFileItem& item);
+
+//! \brief Check whether an item is a subtitle file.
+bool IsSubtitle(const CFileItem& item);
+
+//! \brief Check whether an item is a video item.
+//! \details Note that this returns true for anything with a video info tag,
+//! so that may include eg. folders.
+bool IsVideo(const CFileItem& item);
+
+//! \brief Is the item a video asset, excluding folders
+//! \param[in] item the item
+//! \return true if it is, false otherwise
+bool IsVideoAssetFile(const CFileItem& item);
+
+//! \brief Check whether an item is a video database item.
+bool IsVideoDb(const CFileItem& item);
+
+//! \brief Check whether an item is a video extras folder item.
+bool IsVideoExtrasFolder(const CFileItem& item);
+
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoGeneratedImageFileLoader.cpp b/xbmc/video/VideoGeneratedImageFileLoader.cpp
index e39f5960cf..d270b01d06 100644
--- a/xbmc/video/VideoGeneratedImageFileLoader.cpp
+++ b/xbmc/video/VideoGeneratedImageFileLoader.cpp
@@ -17,9 +17,13 @@
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
-bool VIDEO::CVideoGeneratedImageFileLoader::CanLoad(const std::string& specialType) const
+namespace KODI::VIDEO
+{
+
+bool CVideoGeneratedImageFileLoader::CanLoad(const std::string& specialType) const
{
return specialType == "video";
}
@@ -29,7 +33,7 @@ namespace
void SetupRarOptions(CFileItem& item, const std::string& path)
{
std::string path2(path);
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
path2 = item.GetVideoInfoTag()->m_strFileNameAndPath;
CURL url(path2);
std::string opts = url.GetOptions();
@@ -40,7 +44,7 @@ void SetupRarOptions(CFileItem& item, const std::string& path)
else
opts = "?flags=8";
url.SetOptions(opts);
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (IsVideoDb(item) && item.HasVideoInfoTag())
item.GetVideoInfoTag()->m_strFileNameAndPath = url.Get();
else
item.SetPath(url.Get());
@@ -64,3 +68,5 @@ std::unique_ptr<CTexture> VIDEO::CVideoGeneratedImageFileLoader::Load(
return CDVDFileInfo::ExtractThumbToTexture(item);
}
+
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoGeneratedImageFileLoader.h b/xbmc/video/VideoGeneratedImageFileLoader.h
index d25dfe6f27..d3b8ab6191 100644
--- a/xbmc/video/VideoGeneratedImageFileLoader.h
+++ b/xbmc/video/VideoGeneratedImageFileLoader.h
@@ -10,7 +10,7 @@
#include "imagefiles/SpecialImageFileLoader.h"
-namespace VIDEO
+namespace KODI::VIDEO
{
/*!
* @brief Generates a texture for a thumbnail of a video file, from a frame approx 1/3 into the video.
@@ -25,4 +25,4 @@ public:
unsigned int preferredHeight) const override;
};
-} // namespace VIDEO
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoInfoDownloader.cpp b/xbmc/video/VideoInfoDownloader.cpp
index 9f63e386ae..076b7ed80d 100644
--- a/xbmc/video/VideoInfoDownloader.cpp
+++ b/xbmc/video/VideoInfoDownloader.cpp
@@ -14,7 +14,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
-using namespace VIDEO;
+using namespace KODI;
using namespace KODI::MESSAGING;
using namespace std::chrono_literals;
@@ -220,8 +220,8 @@ bool CVideoInfoDownloader::GetEpisodeDetails(const CScraperUrl &url,
}
bool CVideoInfoDownloader::GetEpisodeList(const CScraperUrl& url,
- EPISODELIST& movieDetails,
- CGUIDialogProgress *pProgress /* = NULL */)
+ VIDEO::EPISODELIST& movieDetails,
+ CGUIDialogProgress* pProgress /* = NULL */)
{
//CLog::Log(LOGDEBUG,"CVideoInfoDownloader::GetDetails({})", url.m_strURL);
m_url = url;
diff --git a/xbmc/video/VideoInfoDownloader.h b/xbmc/video/VideoInfoDownloader.h
index 4479522a33..6e04186f36 100644
--- a/xbmc/video/VideoInfoDownloader.h
+++ b/xbmc/video/VideoInfoDownloader.h
@@ -59,7 +59,9 @@ public:
CVideoInfoTag& movieDetails,
CGUIDialogProgress* pProgress = NULL);
bool GetEpisodeDetails(const CScraperUrl& url, CVideoInfoTag &movieDetails, CGUIDialogProgress *pProgress = NULL);
- bool GetEpisodeList(const CScraperUrl& url, VIDEO::EPISODELIST& details, CGUIDialogProgress *pProgress = NULL);
+ bool GetEpisodeList(const CScraperUrl& url,
+ KODI::VIDEO::EPISODELIST& details,
+ CGUIDialogProgress* pProgress = NULL);
static void ShowErrorDialog(const ADDON::CScraperError &sce);
@@ -77,7 +79,7 @@ protected:
MOVIELIST m_movieList;
CVideoInfoTag m_movieDetails;
CScraperUrl m_url;
- VIDEO::EPISODELIST m_episode;
+ KODI::VIDEO::EPISODELIST m_episode;
LOOKUP_STATE m_state = DO_NOTHING;
int m_found = 0;
ADDON::ScraperPtr m_info;
diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp
index aca4162fd5..4e9eabbbc2 100644
--- a/xbmc/video/VideoInfoScanner.cpp
+++ b/xbmc/video/VideoInfoScanner.cpp
@@ -9,6 +9,7 @@
#include "VideoInfoScanner.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
@@ -42,6 +43,7 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoManagerTypes.h"
#include "video/VideoThumbLoader.h"
#include "video/dialogs/GUIDialogVideoManagerExtras.h"
@@ -54,11 +56,12 @@
using namespace XFILE;
using namespace ADDON;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
using KODI::MESSAGING::HELPERS::DialogResponse;
using KODI::UTILITY::CDigest;
-namespace VIDEO
+namespace KODI::VIDEO
{
CVideoInfoScanner::CVideoInfoScanner()
@@ -413,7 +416,7 @@ namespace VIDEO
break;
// add video extras to library
- if (foundSomething && !m_ignoreVideoExtras && pItem->IsVideoExtras())
+ if (foundSomething && !m_ignoreVideoExtras && IsVideoExtrasFolder(*pItem))
{
if (AddVideoExtras(items, content, pItem->GetPath()))
{
@@ -721,8 +724,8 @@ namespace VIDEO
CScraperUrl* pURL,
CGUIDialogProgress* pDlgProgress)
{
- if (pItem->m_bIsFolder || !pItem->IsVideo() || pItem->IsNFO() ||
- (pItem->IsPlayList() && !URIUtils::HasExtension(pItem->GetPath(), ".strm")))
+ if (pItem->m_bIsFolder || !IsVideo(*pItem) || pItem->IsNFO() ||
+ (pItem->IsPlayList() && !URIUtils::HasExtension(pItem->GetPath(), ".strm")))
return INFO_NOT_NEEDED;
if (ProgressCancelled(pDlgProgress, 198, pItem->GetLabel()))
@@ -826,8 +829,8 @@ namespace VIDEO
CScraperUrl* pURL,
CGUIDialogProgress* pDlgProgress)
{
- if (pItem->m_bIsFolder || !pItem->IsVideo() || pItem->IsNFO() ||
- (pItem->IsPlayList() && !URIUtils::HasExtension(pItem->GetPath(), ".strm")))
+ if (pItem->m_bIsFolder || !IsVideo(*pItem) || pItem->IsNFO() ||
+ (pItem->IsPlayList() && !URIUtils::HasExtension(pItem->GetPath(), ".strm")))
return INFO_NOT_NEEDED;
if (ProgressCancelled(pDlgProgress, 20394, pItem->GetLabel()))
@@ -2204,7 +2207,7 @@ namespace VIDEO
KODI::TIME::FileTime time = pItem->m_dateTime;
digest.Update(&time, sizeof(KODI::TIME::FileTime));
}
- if (pItem->IsVideo() && !pItem->IsPlayList() && !pItem->IsNFO())
+ if (IsVideo(*pItem) && !pItem->IsPlayList() && !pItem->IsNFO())
count++;
}
hash = digest.Finalize();
@@ -2484,8 +2487,9 @@ namespace VIDEO
const int idVideoVersion = m_database.AddVideoVersionType(
typeVideoVersion, VideoAssetTypeOwner::AUTO, VideoAssetType::EXTRA);
- m_database.AddExtrasVideoVersion(ContentToVideoDbType(content), dbId, idVideoVersion,
- *item.get());
+ m_database.AddVideoAsset(ContentToVideoDbType(content), dbId, idVideoVersion,
+ VideoAssetType::EXTRA, *item.get());
+
CLog::Log(LOGDEBUG, "VideoInfoScanner: Added video extras {}",
CURL::GetRedacted(item->GetPath()));
},
diff --git a/xbmc/video/VideoInfoScanner.h b/xbmc/video/VideoInfoScanner.h
index 9f49103be7..abfcbd52f4 100644
--- a/xbmc/video/VideoInfoScanner.h
+++ b/xbmc/video/VideoInfoScanner.h
@@ -21,7 +21,7 @@ class CRegExp;
class CFileItem;
class CFileItemList;
-namespace VIDEO
+namespace KODI::VIDEO
{
class IVideoInfoTagLoader;
@@ -264,5 +264,4 @@ namespace VIDEO
*/
static std::string GetArtTypeFromSize(unsigned int width, unsigned int height);
};
-}
-
+ } // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoItemArtworkHandler.cpp b/xbmc/video/VideoItemArtworkHandler.cpp
index 0401c832b3..c55a827a60 100644
--- a/xbmc/video/VideoItemArtworkHandler.cpp
+++ b/xbmc/video/VideoItemArtworkHandler.cpp
@@ -9,6 +9,7 @@
#include "VideoItemArtworkHandler.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "MediaSource.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
@@ -23,14 +24,17 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoScanner.h"
#include "video/VideoInfoTag.h"
#include "video/VideoThumbLoader.h"
#include "video/tags/VideoTagExtractionHelper.h"
-using namespace VIDEO;
using namespace XFILE;
+namespace KODI::VIDEO
+{
+
namespace
{
//-------------------------------------------------------------------------------------------------
@@ -118,7 +122,7 @@ void CVideoItemArtworkHandler::AddItemPathToFileBrowserSources(std::vector<CMedi
itemDir = m_item->GetVideoInfoTag()->GetPath();
const CFileItem itemTmp(itemDir, false);
- if (itemTmp.IsVideo())
+ if (IsVideo(itemTmp))
itemDir = URIUtils::GetParentPath(itemDir);
AddItemPathStringToFileBrowserSources(sources, itemDir,
@@ -552,3 +556,5 @@ std::unique_ptr<IVideoItemArtworkHandler> IVideoItemArtworkHandlerFactory::Creat
return artHandler;
}
+
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoItemArtworkHandler.h b/xbmc/video/VideoItemArtworkHandler.h
index 01613ef7d0..bab259e5ae 100644
--- a/xbmc/video/VideoItemArtworkHandler.h
+++ b/xbmc/video/VideoItemArtworkHandler.h
@@ -15,7 +15,7 @@
class CFileItem;
class CMediaSource;
-namespace VIDEO
+namespace KODI::VIDEO
{
class IVideoItemArtworkHandler
{
@@ -50,4 +50,4 @@ public:
const std::string& artType);
};
-} // namespace VIDEO
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/VideoThumbLoader.cpp b/xbmc/video/VideoThumbLoader.cpp
index 1cb634ac2e..cc14f55f2f 100644
--- a/xbmc/video/VideoThumbLoader.cpp
+++ b/xbmc/video/VideoThumbLoader.cpp
@@ -9,6 +9,7 @@
#include "VideoThumbLoader.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "URL.h"
@@ -21,6 +22,7 @@
#include "guilib/StereoscopicsManager.h"
#include "music/MusicDatabase.h"
#include "music/tags/MusicInfoTag.h"
+#include "network/NetworkFileItemClassify.h"
#include "settings/AdvancedSettings.h"
#include "settings/SettingUtils.h"
#include "settings/Settings.h"
@@ -29,6 +31,7 @@
#include "utils/URIUtils.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoManagerTypes.h"
#include "video/guilib/VideoVersionHelper.h"
@@ -37,8 +40,8 @@
#include <cstdlib>
#include <utility>
+using namespace KODI;
using namespace XFILE;
-using namespace VIDEO;
CVideoThumbLoader::CVideoThumbLoader() : CThumbLoader()
{
@@ -180,8 +183,11 @@ bool CVideoThumbLoader::LoadItemCached(CFileItem* pItem)
if (!pItem->HasVideoInfoTag() || !pItem->GetVideoInfoTag()->HasStreamDetails()) // no stream details
{
- if ((pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_iFileId >= 0) // file (or maybe folder) is in the database
- || (!pItem->m_bIsFolder && pItem->IsVideo())) // Some other video file for which we haven't yet got any database details
+ if ((pItem->HasVideoInfoTag() &&
+ pItem->GetVideoInfoTag()->m_iFileId >= 0) // file (or maybe folder) is in the database
+ || (!pItem->m_bIsFolder &&
+ VIDEO::IsVideo(
+ *pItem))) // Some other video file for which we haven't yet got any database details
{
if (m_videoDatabase->GetStreamDetails(*pItem))
pItem->SetInvalid();
@@ -286,7 +292,7 @@ bool CVideoThumbLoader::LoadItemLookup(CFileItem* pItem)
}
// We can only extract flags/thumbs for file-like items
- if (!pItem->m_bIsFolder && pItem->IsVideo())
+ if (!pItem->m_bIsFolder && VIDEO::IsVideo(*pItem))
{
const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
if (!pItem->HasArt("thumb"))
@@ -519,7 +525,7 @@ std::string CVideoThumbLoader::GetLocalArt(const CFileItem &item, const std::str
settings ? settings->GetInt(CSettings::SETTING_FILECACHE_BUFFERMODE) == CACHE_BUFFER_MODE_ALL
: false;
- if (item.m_bIsFolder && (item.IsStreamedFilesystem() || cacheAll))
+ if (item.m_bIsFolder && (NETWORK::IsStreamedFilesystem(item) || cacheAll))
{
CFileItemList items; // Dummy list
CDirectory::GetDirectory(item.GetPath(), items, "", DIR_FLAG_NO_FILE_DIRS | DIR_FLAG_READ_CACHE | DIR_FLAG_NO_FILE_INFO);
@@ -549,7 +555,7 @@ std::string CVideoThumbLoader::GetLocalArt(const CFileItem &item, const std::str
std::string CVideoThumbLoader::GetEmbeddedThumbURL(const CFileItem &item)
{
std::string path(item.GetPath());
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(item) && item.HasVideoInfoTag())
path = item.GetVideoInfoTag()->m_strFileNameAndPath;
if (URIUtils::IsStack(path))
path = CStackDirectory::GetFirstStackedFile(path);
@@ -595,7 +601,7 @@ void CVideoThumbLoader::DetectAndAddMissingItemData(CFileItem &item)
if (stereoMode.empty())
{
std::string path = item.GetPath();
- if (item.IsVideoDb() && item.HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(item) && item.HasVideoInfoTag())
path = item.GetVideoInfoTag()->GetPath();
// check for custom stereomode setting in video settings
diff --git a/xbmc/video/VideoUtils.cpp b/xbmc/video/VideoUtils.cpp
index fd730aeb89..a3258bbac8 100644
--- a/xbmc/video/VideoUtils.cpp
+++ b/xbmc/video/VideoUtils.cpp
@@ -9,6 +9,7 @@
#include "VideoUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
@@ -21,6 +22,7 @@
#include "utils/URIUtils.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include <algorithm>
@@ -28,9 +30,11 @@
#include <cstdint>
#include <vector>
+using namespace KODI::VIDEO;
+
namespace
{
-VIDEO_UTILS::ResumeInformation GetFolderItemResumeInformation(const CFileItem& item)
+KODI::VIDEO::UTILS::ResumeInformation GetFolderItemResumeInformation(const CFileItem& item)
{
if (!item.m_bIsFolder)
return {};
@@ -80,7 +84,7 @@ VIDEO_UTILS::ResumeInformation GetFolderItemResumeInformation(const CFileItem& i
if (folderItem.IsResumable())
{
- VIDEO_UTILS::ResumeInformation resumeInfo;
+ KODI::VIDEO::UTILS::ResumeInformation resumeInfo;
resumeInfo.isResumable = true;
return resumeInfo;
}
@@ -88,7 +92,7 @@ VIDEO_UTILS::ResumeInformation GetFolderItemResumeInformation(const CFileItem& i
return {};
}
-VIDEO_UTILS::ResumeInformation GetNonFolderItemResumeInformation(const CFileItem& item)
+KODI::VIDEO::UTILS::ResumeInformation GetNonFolderItemResumeInformation(const CFileItem& item)
{
// do not resume nfo files
if (item.IsNFO())
@@ -102,7 +106,7 @@ VIDEO_UTILS::ResumeInformation GetNonFolderItemResumeInformation(const CFileItem
if (item.IsLiveTV() || item.IsDeleted())
return {};
- VIDEO_UTILS::ResumeInformation resumeInfo;
+ KODI::VIDEO::UTILS::ResumeInformation resumeInfo;
if (item.GetCurrentResumeTimeAndPartNumber(resumeInfo.startOffset, resumeInfo.partNumber))
{
@@ -124,13 +128,13 @@ VIDEO_UTILS::ResumeInformation GetNonFolderItemResumeInformation(const CFileItem
}
std::string path = item.GetPath();
- if (item.IsVideoDb() || item.IsDVD())
+ if (IsVideoDb(item) || item.IsDVD())
{
if (item.HasVideoInfoTag())
{
path = item.GetVideoInfoTag()->m_strFileNameAndPath;
}
- else if (item.IsVideoDb())
+ else if (IsVideoDb(item))
{
// Obtain path+filename from video db
XFILE::VIDEODATABASEDIRECTORY::CQueryParams params;
@@ -178,7 +182,7 @@ VIDEO_UTILS::ResumeInformation GetNonFolderItemResumeInformation(const CFileItem
} // unnamed namespace
-namespace VIDEO_UTILS
+namespace KODI::VIDEO::UTILS
{
std::string GetOpticalMediaPath(const CFileItem& item)
{
@@ -277,4 +281,4 @@ ResumeInformation GetStackPartResumeInformation(const CFileItem& item, unsigned
return resumeInfo;
}
-} // namespace VIDEO_UTILS
+} // namespace KODI::VIDEO::UTILS
diff --git a/xbmc/video/VideoUtils.h b/xbmc/video/VideoUtils.h
index 200f650318..c344072ffe 100644
--- a/xbmc/video/VideoUtils.h
+++ b/xbmc/video/VideoUtils.h
@@ -12,7 +12,7 @@
class CFileItem;
-namespace VIDEO_UTILS
+namespace KODI::VIDEO::UTILS
{
/*!
\brief Check whether an item is an optical media folder or its parent.
@@ -57,4 +57,4 @@ ResumeInformation GetItemResumeInformation(const CFileItem& item);
*/
ResumeInformation GetStackPartResumeInformation(const CFileItem& item, unsigned int partNumber);
-} // namespace VIDEO_UTILS
+} // namespace KODI::VIDEO::UTILS
diff --git a/xbmc/video/dialogs/GUIDialogCMSSettings.cpp b/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
index 6299cacbc6..c7945523ee 100644
--- a/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
+++ b/xbmc/video/dialogs/GUIDialogCMSSettings.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogCMSSettings.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "addons/Skin.h"
diff --git a/xbmc/video/dialogs/GUIDialogSubtitles.cpp b/xbmc/video/dialogs/GUIDialogSubtitles.cpp
index e178a0002e..c22eda9717 100644
--- a/xbmc/video/dialogs/GUIDialogSubtitles.cpp
+++ b/xbmc/video/dialogs/GUIDialogSubtitles.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogSubtitles.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "LangInfo.h"
#include "ServiceBroker.h"
#include "URL.h"
diff --git a/xbmc/video/dialogs/GUIDialogTeletext.cpp b/xbmc/video/dialogs/GUIDialogTeletext.cpp
index 13c706b12f..26280c7126 100644
--- a/xbmc/video/dialogs/GUIDialogTeletext.cpp
+++ b/xbmc/video/dialogs/GUIDialogTeletext.cpp
@@ -85,6 +85,9 @@ void CGUIDialogTeletext::Process(unsigned int currentTime, CDirtyRegionList &dir
void CGUIDialogTeletext::Render()
{
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
+ RENDER_ORDER_FRONT_TO_BACK)
+ return;
// Do not render if we have no texture
if (!m_pTxtTexture)
{
@@ -124,7 +127,7 @@ void CGUIDialogTeletext::Render()
UTILS::COLOR::Color color =
(static_cast<UTILS::COLOR::Color>(teletextFadeAmount * 2.55f) & 0xff) << 24 | 0xFFFFFF;
- CGUITexture::DrawQuad(m_vertCoords, color, m_pTxtTexture.get());
+ CGUITexture::DrawQuad(m_vertCoords, color, m_pTxtTexture.get(), nullptr, -1.0f);
CGUIDialog::Render();
}
diff --git a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
index 10708a2f80..9c086dc109 100644
--- a/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoBookmarks.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogVideoBookmarks.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureCache.h"
#include "Util.h"
@@ -35,6 +36,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "view/ViewState.h"
#include <algorithm>
@@ -48,6 +50,8 @@
#define CONTROL_THUMBS 11
+using namespace KODI::VIDEO;
+
CGUIDialogVideoBookmarks::CGUIDialogVideoBookmarks()
: CGUIDialog(WINDOW_DIALOG_VIDEO_BOOKMARKS, "VideoOSDBookmarks.xml")
{
@@ -531,7 +535,7 @@ bool CGUIDialogVideoBookmarks::AddEpisodeBookmark()
bool CGUIDialogVideoBookmarks::OnAddBookmark()
{
- if (!g_application.CurrentFileItem().IsVideo())
+ if (!IsVideo(g_application.CurrentFileItem()))
return false;
if (CGUIDialogVideoBookmarks::AddBookmark())
diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
index 59daa631de..d5b7e68b28 100644
--- a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp
@@ -10,6 +10,7 @@
#include "ContextMenuManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
@@ -51,6 +52,7 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoScanner.h"
#include "video/VideoInfoTag.h"
#include "video/VideoItemArtworkHandler.h"
@@ -70,6 +72,7 @@
using namespace XFILE::VIDEODATABASEDIRECTORY;
using namespace XFILE;
+using namespace KODI;
using namespace KODI::MESSAGING;
#define CONTROL_IMAGE 3
@@ -766,7 +769,7 @@ private:
const ContentUtils::PlayMode mode{item->GetProperty("CheckAutoPlayNextItem").asBoolean()
? ContentUtils::PlayMode::CHECK_AUTO_PLAY_NEXT_ITEM
: ContentUtils::PlayMode::PLAY_ONLY_THIS};
- VIDEO_UTILS::PlayItem(item, "", mode);
+ VIDEO::UTILS::PlayItem(item, "", mode);
}
};
} // unnamed namespace
@@ -1067,7 +1070,8 @@ std::string CGUIDialogVideoInfo::GetThumbnail() const
int CGUIDialogVideoInfo::ManageVideoItem(const std::shared_ptr<CFileItem>& item)
{
- if (item == nullptr || !item->IsVideoDb() || !item->HasVideoInfoTag() || item->GetVideoInfoTag()->m_iDbId < 0)
+ if (item == nullptr || !VIDEO::IsVideoDb(*item) || !item->HasVideoInfoTag() ||
+ item->GetVideoInfoTag()->m_iDbId < 0)
return -1;
CVideoDatabase database;
diff --git a/xbmc/video/dialogs/GUIDialogVideoManager.cpp b/xbmc/video/dialogs/GUIDialogVideoManager.cpp
index d2d503c0fc..eedd73e0db 100644
--- a/xbmc/video/dialogs/GUIDialogVideoManager.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoManager.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogVideoManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "MediaSource.h"
#include "ServiceBroker.h"
@@ -36,6 +37,8 @@
#include <algorithm>
#include <string>
+using namespace KODI;
+
static constexpr unsigned int CONTROL_LABEL_TITLE = 2;
static constexpr unsigned int CONTROL_BUTTON_PLAY = 21;
@@ -51,9 +54,6 @@ CGUIDialogVideoManager::CGUIDialogVideoManager(int windowId)
m_selectedVideoAsset(std::make_shared<CFileItem>())
{
m_loadType = KEEP_IN_MEMORY;
-
- if (!m_database.Open())
- CLog::LogF(LOGERROR, "Failed to open video database!");
}
bool CGUIDialogVideoManager::OnMessage(CGUIMessage& message)
@@ -115,6 +115,9 @@ bool CGUIDialogVideoManager::OnAction(const CAction& action)
void CGUIDialogVideoManager::OnInitWindow()
{
+ if (!m_database.IsOpen() && !m_database.Open())
+ CLog::LogF(LOGERROR, "Failed to open video database!");
+
CGUIDialog::OnInitWindow();
SET_CONTROL_LABEL(CONTROL_LABEL_TITLE,
@@ -127,6 +130,12 @@ void CGUIDialogVideoManager::OnInitWindow()
UpdateControls();
}
+void CGUIDialogVideoManager::OnDeinitWindow(int nextWindowID)
+{
+ CGUIDialog::OnDeinitWindow(nextWindowID);
+ m_database.Close();
+}
+
void CGUIDialogVideoManager::Clear()
{
m_videoAssetsList->Clear();
@@ -198,6 +207,9 @@ void CGUIDialogVideoManager::UpdateControls()
void CGUIDialogVideoManager::Refresh()
{
+ if (!m_database.IsOpen() && !m_database.Open())
+ CLog::LogF(LOGERROR, "Failed to open video database!");
+
Clear();
const int dbId{m_videoAsset->GetVideoInfoTag()->m_iDbId};
@@ -277,7 +289,7 @@ private:
const ContentUtils::PlayMode mode{m_item->GetProperty("CheckAutoPlayNextItem").asBoolean()
? ContentUtils::PlayMode::CHECK_AUTO_PLAY_NEXT_ITEM
: ContentUtils::PlayMode::PLAY_ONLY_THIS};
- VIDEO_UTILS::PlayItem(m_item, "", mode);
+ VIDEO::UTILS::PlayItem(m_item, "", mode);
}
};
} // unnamed namespace
@@ -301,8 +313,7 @@ void CGUIDialogVideoManager::Remove()
return;
}
- //! @todo db refactor: should not be version, but asset
- m_database.RemoveVideoVersion(m_selectedVideoAsset->GetVideoInfoTag()->m_iDbId);
+ m_database.DeleteVideoAsset(m_selectedVideoAsset->GetVideoInfoTag()->m_iDbId);
// refresh data and controls
Refresh();
diff --git a/xbmc/video/dialogs/GUIDialogVideoManager.h b/xbmc/video/dialogs/GUIDialogVideoManager.h
index b4b043df0a..a76f724259 100644
--- a/xbmc/video/dialogs/GUIDialogVideoManager.h
+++ b/xbmc/video/dialogs/GUIDialogVideoManager.h
@@ -31,6 +31,7 @@ public:
protected:
void OnInitWindow() override;
+ void OnDeinitWindow(int nextWindowID) override;
bool OnMessage(CGUIMessage& message) override;
bool OnAction(const CAction& action) override;
diff --git a/xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp b/xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp
index 28bae13d04..b96bd85831 100644
--- a/xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoManagerExtras.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogVideoManagerExtras.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "URL.h"
@@ -214,12 +215,6 @@ bool CGUIDialogVideoManagerExtras::AddVideoExtra()
return m_database.ConvertVideoToVersion(itemType, newAsset.m_idMedia, dbId,
idNewVideoVersion, VideoAssetType::EXTRA);
}
- else
- {
- // @todo: should be in a database transaction with the addition as a new asset below
- if (!m_database.RemoveVideoVersion(newAsset.m_idFile))
- return false;
- }
}
CFileItem item{path, false};
@@ -238,7 +233,7 @@ bool CGUIDialogVideoManagerExtras::AddVideoExtra()
if (idNewVideoVersion == -1)
return false;
- m_database.AddExtrasVideoVersion(itemType, dbId, idNewVideoVersion, item);
+ m_database.AddVideoAsset(itemType, dbId, idNewVideoVersion, VideoAssetType::EXTRA, item);
return true;
}
diff --git a/xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp b/xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp
index f2dada7087..32ad392851 100644
--- a/xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp
+++ b/xbmc/video/dialogs/GUIDialogVideoManagerVersions.cpp
@@ -9,6 +9,7 @@
#include "GUIDialogVideoManagerVersions.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "ServiceBroker.h"
#include "URL.h"
@@ -583,12 +584,6 @@ bool CGUIDialogVideoManagerVersions::AddVideoVersionFilePicker()
return false;
}
}
- else
- {
- // @todo: should be in a database transaction with the addition as a new asset below
- if (!m_database.RemoveVideoVersion(newAsset.m_idFile))
- return false;
- }
}
CFileItem item{path, false};
@@ -605,7 +600,7 @@ bool CGUIDialogVideoManagerVersions::AddVideoVersionFilePicker()
if (idNewVideoVersion == -1)
return false;
- m_database.AddPrimaryVideoVersion(itemType, dbId, idNewVideoVersion, item);
+ m_database.AddVideoAsset(itemType, dbId, idNewVideoVersion, VideoAssetType::VERSION, item);
return true;
}
diff --git a/xbmc/video/guilib/VideoAction.h b/xbmc/video/guilib/VideoAction.h
index d2efd86d3c..d8d0ccb782 100644
--- a/xbmc/video/guilib/VideoAction.h
+++ b/xbmc/video/guilib/VideoAction.h
@@ -8,9 +8,7 @@
#pragma once
-namespace VIDEO
-{
-namespace GUILIB
+namespace KODI::VIDEO::GUILIB
{
// Note: Do not change the numerical values of the elements. Some of them are used as values for
// the integer settings SETTING_MYVIDEOS_SELECTACTION and SETTING_MYVIDEOS_PLAYACTION.
@@ -25,5 +23,4 @@ enum Action
ACTION_PLAYPART = 6,
ACTION_QUEUE = 7,
};
-} // namespace GUILIB
-} // namespace VIDEO
+} // namespace KODI::VIDEO::GUILIB
diff --git a/xbmc/video/guilib/VideoGUIUtils.cpp b/xbmc/video/guilib/VideoGUIUtils.cpp
index 5a30fa7ccd..8cadb0e755 100644
--- a/xbmc/video/guilib/VideoGUIUtils.cpp
+++ b/xbmc/video/guilib/VideoGUIUtils.cpp
@@ -9,6 +9,7 @@
#include "VideoGUIUtils.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
@@ -22,6 +23,8 @@
#include "guilib/GUIComponent.h"
#include "guilib/GUIWindowManager.h"
#include "guilib/LocalizeStrings.h"
+#include "music/MusicFileItemClassify.h"
+#include "network/NetworkFileItemClassify.h"
#include "playlists/PlayList.h"
#include "playlists/PlayListFactory.h"
#include "profiles/ProfileManager.h"
@@ -35,10 +38,14 @@
#include "utils/URIUtils.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoTag.h"
#include "video/VideoUtils.h"
#include "view/GUIViewState.h"
+namespace KODI
+{
+
namespace
{
class CAsyncGetItemsForPlaylist : public IRunnable
@@ -47,7 +54,7 @@ public:
CAsyncGetItemsForPlaylist(const std::shared_ptr<CFileItem>& item, CFileItemList& queuedItems)
: m_item(item),
m_resume((item->GetStartOffset() == STARTOFFSET_RESUME) &&
- VIDEO_UTILS::GetItemResumeInformation(*item).isResumable),
+ VIDEO::UTILS::GetItemResumeInformation(*item).isResumable),
m_queuedItems(queuedItems)
{
}
@@ -134,7 +141,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
if (item->m_bIsFolder)
{
// check if it's a folder with dvd or bluray files, then just add the relevant file
- const std::string mediapath = VIDEO_UTILS::GetOpticalMediaPath(*item);
+ const std::string mediapath = VIDEO::UTILS::GetOpticalMediaPath(*item);
if (!mediapath.empty())
{
m_queuedItems.Add(std::make_shared<CFileItem>(mediapath, false));
@@ -197,7 +204,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
items.Sort(sortDesc);
}
- if (items.GetContent().empty() && !items.IsVideoDb() && !items.IsVirtualDirectoryRoot() &&
+ if (items.GetContent().empty() && !VIDEO::IsVideoDb(items) && !items.IsVirtualDirectoryRoot() &&
!items.IsSourcesPath() && !items.IsLibraryFolder())
{
CVideoDatabase db;
@@ -289,7 +296,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
// just queue the playlist, it will be expanded on play
m_queuedItems.Add(item);
}
- else if (item->IsInternetStream())
+ else if (NETWORK::IsInternetStream(*item))
{
// just queue the internet stream, it will be expanded on play
m_queuedItems.Add(item);
@@ -299,7 +306,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
// a playable python files
m_queuedItems.Add(item);
}
- else if (item->IsVideoDb())
+ else if (VIDEO::IsVideoDb(*item))
{
// this case is needed unless we allow IsVideo() to return true for videodb items,
// but then we have issues with playlists of videodb items
@@ -307,7 +314,7 @@ void CAsyncGetItemsForPlaylist::GetItemsForPlaylist(const std::shared_ptr<CFileI
itemCopy->SetStartOffset(item->GetStartOffset());
m_queuedItems.Add(itemCopy);
}
- else if (!item->IsNFO() && item->IsVideo())
+ else if (!item->IsNFO() && VIDEO::IsVideo(*item))
{
m_queuedItems.Add(item);
}
@@ -331,7 +338,7 @@ void AddItemToPlayListAndPlay(const std::shared_ptr<CFileItem>& itemToQueue,
{
// recursively add items to list
CFileItemList queuedItems;
- VIDEO_UTILS::GetItemsForPlayList(itemToQueue, queuedItems);
+ VIDEO::UTILS::GetItemsForPlayList(itemToQueue, queuedItems);
auto& playlistPlayer = CServiceBroker::GetPlaylistPlayer();
playlistPlayer.ClearPlaylist(PLAYLIST::TYPE_VIDEO);
@@ -364,7 +371,9 @@ void AddItemToPlayListAndPlay(const std::shared_ptr<CFileItem>& itemToQueue,
} // unnamed namespace
-namespace VIDEO_UTILS
+} // namespace KODI
+
+namespace KODI::VIDEO::UTILS
{
void PlayItem(
const std::shared_ptr<CFileItem>& itemIn,
@@ -510,7 +519,7 @@ bool IsItemPlayable(const CFileItem& item)
return true;
// Exclude all music library items
- if (item.IsMusicDb() || StringUtils::StartsWithNoCase(item.GetPath(), "library://music/"))
+ if (MUSIC::IsMusicDb(item) || StringUtils::StartsWithNoCase(item.GetPath(), "library://music/"))
return false;
// Exclude other components
@@ -553,7 +562,7 @@ bool IsItemPlayable(const CFileItem& item)
return false;
if (item.m_bIsFolder &&
- (item.IsVideoDb() || StringUtils::StartsWithNoCase(item.GetPath(), "library://video/")))
+ (IsVideoDb(item) || StringUtils::StartsWithNoCase(item.GetPath(), "library://video/")))
{
// Exclude top level nodes - eg can't play 'genres' just a specific genre etc
const XFILE::VIDEODATABASEDIRECTORY::NODE_TYPE node =
@@ -571,7 +580,7 @@ bool IsItemPlayable(const CFileItem& item)
{
return true;
}
- else if ((!item.m_bIsFolder && item.IsVideo()) || item.IsDVD() || item.IsCDDA())
+ else if ((!item.m_bIsFolder && IsVideo(item)) || item.IsDVD() || MUSIC::IsCDDA(item))
{
return true;
}
@@ -614,4 +623,4 @@ std::string GetResumeString(const CFileItem& item)
return {};
}
-} // namespace VIDEO_UTILS
+} // namespace KODI::VIDEO::UTILS
diff --git a/xbmc/video/guilib/VideoGUIUtils.h b/xbmc/video/guilib/VideoGUIUtils.h
index 2de4e63cad..d2af15bfb1 100644
--- a/xbmc/video/guilib/VideoGUIUtils.h
+++ b/xbmc/video/guilib/VideoGUIUtils.h
@@ -15,7 +15,7 @@
class CFileItem;
class CFileItemList;
-namespace VIDEO_UTILS
+namespace KODI::VIDEO::UTILS
{
/*! \brief Start playback of the given item. If the item is a folder, build a playlist with
all items contained in the folder and start playback of the playlist. If item is a single video
@@ -65,4 +65,4 @@ bool IsItemPlayable(const CFileItem& item);
*/
std::string GetResumeString(const CFileItem& item);
-} // namespace VIDEO_UTILS
+} // namespace KODI::VIDEO::UTILS
diff --git a/xbmc/video/guilib/VideoPlayActionProcessor.cpp b/xbmc/video/guilib/VideoPlayActionProcessor.cpp
index 88e448df41..0d2c61897e 100644
--- a/xbmc/video/guilib/VideoPlayActionProcessor.cpp
+++ b/xbmc/video/guilib/VideoPlayActionProcessor.cpp
@@ -16,7 +16,8 @@
#include "video/guilib/VideoGUIUtils.h"
#include "video/guilib/VideoVersionHelper.h"
-using namespace VIDEO::GUILIB;
+namespace KODI::VIDEO::GUILIB
+{
Action CVideoPlayActionProcessorBase::GetDefaultAction()
{
@@ -77,7 +78,7 @@ Action CVideoPlayActionProcessorBase::ChoosePlayOrResume(const CFileItem& item)
{
Action action = ACTION_PLAY_FROM_BEGINNING;
- const std::string resumeString = VIDEO_UTILS::GetResumeString(item);
+ const std::string resumeString = VIDEO::UTILS::GetResumeString(item);
if (!resumeString.empty())
{
CContextButtons choices;
@@ -90,3 +91,5 @@ Action CVideoPlayActionProcessorBase::ChoosePlayOrResume(const CFileItem& item)
return action;
}
+
+} // namespace KODI::VIDEO::GUILIB
diff --git a/xbmc/video/guilib/VideoPlayActionProcessor.h b/xbmc/video/guilib/VideoPlayActionProcessor.h
index b943d4b259..5ae9c79aee 100644
--- a/xbmc/video/guilib/VideoPlayActionProcessor.h
+++ b/xbmc/video/guilib/VideoPlayActionProcessor.h
@@ -14,9 +14,7 @@
class CFileItem;
-namespace VIDEO
-{
-namespace GUILIB
+namespace KODI::VIDEO::GUILIB
{
class CVideoPlayActionProcessorBase
{
@@ -44,5 +42,4 @@ protected:
private:
CVideoPlayActionProcessorBase() = delete;
};
-} // namespace GUILIB
-} // namespace VIDEO
+} // namespace KODI::VIDEO::GUILIB
diff --git a/xbmc/video/guilib/VideoSelectActionProcessor.cpp b/xbmc/video/guilib/VideoSelectActionProcessor.cpp
index 665b55858d..50f7b21e81 100644
--- a/xbmc/video/guilib/VideoSelectActionProcessor.cpp
+++ b/xbmc/video/guilib/VideoSelectActionProcessor.cpp
@@ -9,6 +9,7 @@
#include "VideoSelectActionProcessor.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "dialogs/GUIDialogContextMenu.h"
#include "dialogs/GUIDialogSelect.h"
@@ -23,7 +24,8 @@
#include "video/VideoInfoTag.h"
#include "video/guilib/VideoGUIUtils.h"
-using namespace VIDEO::GUILIB;
+namespace KODI::VIDEO::GUILIB
+{
Action CVideoSelectActionProcessorBase::GetDefaultSelectAction()
{
@@ -106,7 +108,7 @@ Action CVideoSelectActionProcessorBase::ChooseVideoItemSelectAction() const
{
CContextButtons choices;
- const std::string resumeString = VIDEO_UTILS::GetResumeString(*m_item);
+ const std::string resumeString = UTILS::GetResumeString(*m_item);
if (!resumeString.empty())
{
choices.Add(ACTION_RESUME, resumeString);
@@ -123,3 +125,5 @@ Action CVideoSelectActionProcessorBase::ChooseVideoItemSelectAction() const
return static_cast<Action>(CGUIDialogContextMenu::ShowAndGetChoice(choices));
}
+
+} // namespace KODI::VIDEO::GUILIB
diff --git a/xbmc/video/guilib/VideoSelectActionProcessor.h b/xbmc/video/guilib/VideoSelectActionProcessor.h
index 8a4e6ee80e..30e2dc1049 100644
--- a/xbmc/video/guilib/VideoSelectActionProcessor.h
+++ b/xbmc/video/guilib/VideoSelectActionProcessor.h
@@ -14,9 +14,7 @@
class CFileItem;
-namespace VIDEO
-{
-namespace GUILIB
+namespace KODI::VIDEO::GUILIB
{
class CVideoSelectActionProcessorBase : public CVideoPlayActionProcessorBase
{
@@ -44,5 +42,4 @@ private:
Action ChooseVideoItemSelectAction() const;
unsigned int ChooseStackItemPartNumber() const;
};
-} // namespace GUILIB
-} // namespace VIDEO
+} // namespace KODI::VIDEO::GUILIB
diff --git a/xbmc/video/guilib/VideoVersionHelper.cpp b/xbmc/video/guilib/VideoVersionHelper.cpp
index e6ece8f03c..fbe9bdb202 100644
--- a/xbmc/video/guilib/VideoVersionHelper.cpp
+++ b/xbmc/video/guilib/VideoVersionHelper.cpp
@@ -9,6 +9,7 @@
#include "VideoVersionHelper.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "URL.h"
#include "dialogs/GUIDialogSelect.h"
@@ -21,10 +22,12 @@
#include "utils/StringUtils.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoManagerTypes.h"
#include "video/VideoThumbLoader.h"
-using namespace VIDEO::GUILIB;
+namespace KODI::VIDEO::GUILIB
+{
namespace
{
@@ -279,16 +282,4 @@ std::shared_ptr<CFileItem> CVideoVersionHelper::ChooseVideoFromAssets(
return item;
}
-bool VIDEO::IsVideoAssetFile(const CFileItem& item)
-{
- if (item.m_bIsFolder || !item.IsVideoDb())
- return false;
-
- // @todo maybe in the future look for prefix videodb://movies/videoversions in path instead
- // @todo better encoding of video assets as path, they won't always be tied with movies.
- const CURL itemUrl{item.GetPath()};
- if (itemUrl.HasOption("videoversionid"))
- return true;
-
- return false;
-}
+} // namespace KODI::VIDEO::GUILIB
diff --git a/xbmc/video/guilib/VideoVersionHelper.h b/xbmc/video/guilib/VideoVersionHelper.h
index 8d81ec1b65..0aea3ffb08 100644
--- a/xbmc/video/guilib/VideoVersionHelper.h
+++ b/xbmc/video/guilib/VideoVersionHelper.h
@@ -12,22 +12,13 @@
class CFileItem;
-namespace VIDEO
-{
-namespace GUILIB
+namespace KODI::VIDEO::GUILIB
{
+
class CVideoVersionHelper
{
public:
static std::shared_ptr<CFileItem> ChooseVideoFromAssets(const std::shared_ptr<CFileItem>& item);
};
-} // namespace GUILIB
-
-/*!
- * \brief Is the item a video asset, excluding folders
- * \param[in] item the item
- * \return true if it is, false otherwise
- */
-bool IsVideoAssetFile(const CFileItem& item);
-} // namespace VIDEO
+} // namespace KODI::VIDEO::GUILIB
diff --git a/xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp b/xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp
index 486bd7a727..ef2e9253ad 100644
--- a/xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp
+++ b/xbmc/video/jobs/VideoLibraryMarkWatchedJob.cpp
@@ -9,6 +9,7 @@
#include "VideoLibraryMarkWatchedJob.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/video/jobs/VideoLibraryRefreshingJob.cpp b/xbmc/video/jobs/VideoLibraryRefreshingJob.cpp
index 832bdd6b7f..958a6f970c 100644
--- a/xbmc/video/jobs/VideoLibraryRefreshingJob.cpp
+++ b/xbmc/video/jobs/VideoLibraryRefreshingJob.cpp
@@ -9,6 +9,7 @@
#include "VideoLibraryRefreshingJob.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "TextureDatabase.h"
#include "URL.h"
@@ -36,8 +37,8 @@
#include <memory>
#include <utility>
+using namespace KODI;
using namespace KODI::MESSAGING;
-using namespace VIDEO;
CVideoLibraryRefreshingJob::CVideoLibraryRefreshingJob(std::shared_ptr<CFileItem> item,
bool forceRefresh,
@@ -108,9 +109,9 @@ bool CVideoLibraryRefreshingJob::Work(CVideoDatabase &db)
if (!ignoreNfo)
{
- std::unique_ptr<IVideoInfoTagLoader> loader;
- loader.reset(CVideoInfoTagLoaderFactory::CreateLoader(*m_item, scraper,
- scanSettings.parent_name_root, m_forceRefresh));
+ std::unique_ptr<VIDEO::IVideoInfoTagLoader> loader;
+ loader.reset(VIDEO::CVideoInfoTagLoaderFactory::CreateLoader(
+ *m_item, scraper, scanSettings.parent_name_root, m_forceRefresh));
// check if there's an NFO for the item
CInfoScanner::INFO_TYPE nfoResult = CInfoScanner::NO_NFO;
if (loader)
@@ -181,7 +182,9 @@ bool CVideoLibraryRefreshingJob::Work(CVideoDatabase &db)
{
CFileItemList items;
items.Add(m_item);
- CVideoInfoScanner scanner;
+ items.SetPath(m_item->m_bIsFolder ? URIUtils::GetParentPath(m_item->GetPath())
+ : URIUtils::GetDirectory(m_item->GetPath()));
+ VIDEO::CVideoInfoScanner scanner;
if (scanner.RetrieveVideoInfo(items, scanSettings.parent_name, scraper->Content(),
!ignoreNfo, nullptr, m_refreshAll, GetProgressDialog()))
{
@@ -359,7 +362,7 @@ bool CVideoLibraryRefreshingJob::Work(CVideoDatabase &db)
}
// finally download the information for the item
- CVideoInfoScanner scanner;
+ VIDEO::CVideoInfoScanner scanner;
if (!scanner.RetrieveVideoInfo(items, scanSettings.parent_name,
scraper->Content(), !ignoreNfo,
scraperUrl.HasUrls() ? &scraperUrl : nullptr,
diff --git a/xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp b/xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp
index 15b71a2955..1c9d2c768d 100644
--- a/xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp
+++ b/xbmc/video/jobs/VideoLibraryResetResumePointJob.cpp
@@ -8,12 +8,13 @@
#include "VideoLibraryResetResumePointJob.h"
-#include <vector>
-
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "Util.h"
#include "filesystem/IDirectory.h"
+
+#include <vector>
#ifdef HAS_UPNP
#include "network/upnp/UPnP.h"
#endif
diff --git a/xbmc/video/jobs/VideoLibraryScanningJob.h b/xbmc/video/jobs/VideoLibraryScanningJob.h
index 3df98a753f..f7233799cd 100644
--- a/xbmc/video/jobs/VideoLibraryScanningJob.h
+++ b/xbmc/video/jobs/VideoLibraryScanningJob.h
@@ -45,7 +45,7 @@ protected:
bool Work(CVideoDatabase &db) override;
private:
- VIDEO::CVideoInfoScanner m_scanner;
+ KODI::VIDEO::CVideoInfoScanner m_scanner;
std::string m_directory;
bool m_showProgress;
bool m_scanAll;
diff --git a/xbmc/video/tags/IVideoInfoTagLoader.h b/xbmc/video/tags/IVideoInfoTagLoader.h
index 8afc31ec85..9f78b57a1c 100644
--- a/xbmc/video/tags/IVideoInfoTagLoader.h
+++ b/xbmc/video/tags/IVideoInfoTagLoader.h
@@ -18,7 +18,7 @@ class CFileItem;
class CVideoInfoTag;
class EmbeddedArt;
-namespace VIDEO
+namespace KODI::VIDEO
{
//! \brief Base class for video tag loaders.
diff --git a/xbmc/video/tags/VideoInfoTagLoaderFactory.cpp b/xbmc/video/tags/VideoInfoTagLoaderFactory.cpp
index 6f3c7fa009..f0fe697900 100644
--- a/xbmc/video/tags/VideoInfoTagLoaderFactory.cpp
+++ b/xbmc/video/tags/VideoInfoTagLoaderFactory.cpp
@@ -14,7 +14,8 @@
#include "VideoTagLoaderPlugin.h"
#include "video/tags/VideoTagExtractionHelper.h"
-using namespace VIDEO;
+namespace KODI::VIDEO
+{
IVideoInfoTagLoader* CVideoInfoTagLoaderFactory::CreateLoader(const CFileItem& item,
const ADDON::ScraperPtr& info,
@@ -45,3 +46,5 @@ IVideoInfoTagLoader* CVideoInfoTagLoaderFactory::CreateLoader(const CFileItem& i
return nullptr;
}
+
+} // namespace KODI::VIDEO
diff --git a/xbmc/video/tags/VideoInfoTagLoaderFactory.h b/xbmc/video/tags/VideoInfoTagLoaderFactory.h
index 9b8861f575..c6d41af749 100644
--- a/xbmc/video/tags/VideoInfoTagLoaderFactory.h
+++ b/xbmc/video/tags/VideoInfoTagLoaderFactory.h
@@ -13,7 +13,7 @@
class CFileItem; // forward
-namespace VIDEO
+namespace KODI::VIDEO
{
class CVideoInfoTagLoaderFactory
{
@@ -31,4 +31,4 @@ namespace VIDEO
CVideoInfoTagLoaderFactory(void) = delete;
virtual ~CVideoInfoTagLoaderFactory() = delete;
};
-}
+ } // namespace KODI::VIDEO
diff --git a/xbmc/video/tags/VideoTagExtractionHelper.cpp b/xbmc/video/tags/VideoTagExtractionHelper.cpp
index b331305fc4..53cd3340ef 100644
--- a/xbmc/video/tags/VideoTagExtractionHelper.cpp
+++ b/xbmc/video/tags/VideoTagExtractionHelper.cpp
@@ -17,7 +17,8 @@
#include "video/VideoInfoTag.h"
#include "video/tags/VideoTagLoaderFFmpeg.h"
-using namespace VIDEO::TAGS;
+namespace KODI::VIDEO::TAGS
+{
bool CVideoTagExtractionHelper::IsExtractionSupportedFor(const CFileItem& item)
{
@@ -39,3 +40,5 @@ std::string CVideoTagExtractionHelper::ExtractEmbeddedArtFor(const CFileItem& it
}
return {};
}
+
+} // namespace KODI::VIDEO::TAGS
diff --git a/xbmc/video/tags/VideoTagExtractionHelper.h b/xbmc/video/tags/VideoTagExtractionHelper.h
index 1e6823e1cf..963392e347 100644
--- a/xbmc/video/tags/VideoTagExtractionHelper.h
+++ b/xbmc/video/tags/VideoTagExtractionHelper.h
@@ -12,9 +12,7 @@
class CFileItem;
-namespace VIDEO
-{
-namespace TAGS
+namespace KODI::VIDEO::TAGS
{
class CVideoTagExtractionHelper
{
@@ -37,5 +35,4 @@ public:
*/
static std::string ExtractEmbeddedArtFor(const CFileItem& item, const std::string& artType);
};
-} // namespace TAGS
-} // namespace VIDEO
+} // namespace KODI::VIDEO::TAGS
diff --git a/xbmc/video/tags/VideoTagLoaderFFmpeg.h b/xbmc/video/tags/VideoTagLoaderFFmpeg.h
index f6b50df1a1..f61ec46e2b 100644
--- a/xbmc/video/tags/VideoTagLoaderFFmpeg.h
+++ b/xbmc/video/tags/VideoTagLoaderFFmpeg.h
@@ -21,7 +21,7 @@ namespace XFILE
}
//! \brief Video tag loader using FFMPEG.
-class CVideoTagLoaderFFmpeg : public VIDEO::IVideoInfoTagLoader
+class CVideoTagLoaderFFmpeg : public KODI::VIDEO::IVideoInfoTagLoader
{
public:
//! \brief Constructor.
diff --git a/xbmc/video/tags/VideoTagLoaderNFO.cpp b/xbmc/video/tags/VideoTagLoaderNFO.cpp
index f85ce39818..c5e3b84539 100644
--- a/xbmc/video/tags/VideoTagLoaderNFO.cpp
+++ b/xbmc/video/tags/VideoTagLoaderNFO.cpp
@@ -9,6 +9,7 @@
#include "VideoTagLoaderNFO.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "NfoFile.h"
#include "URL.h"
#include "filesystem/Directory.h"
diff --git a/xbmc/video/tags/VideoTagLoaderNFO.h b/xbmc/video/tags/VideoTagLoaderNFO.h
index e6124c8ad7..92a57d8973 100644
--- a/xbmc/video/tags/VideoTagLoaderNFO.h
+++ b/xbmc/video/tags/VideoTagLoaderNFO.h
@@ -14,7 +14,7 @@
#include <vector>
//! \brief Video tag loader using nfo files.
-class CVideoTagLoaderNFO : public VIDEO::IVideoInfoTagLoader
+class CVideoTagLoaderNFO : public KODI::VIDEO::IVideoInfoTagLoader
{
public:
CVideoTagLoaderNFO(const CFileItem& item,
diff --git a/xbmc/video/tags/VideoTagLoaderPlugin.cpp b/xbmc/video/tags/VideoTagLoaderPlugin.cpp
index f3b97ee608..6e7e8e0fbc 100644
--- a/xbmc/video/tags/VideoTagLoaderPlugin.cpp
+++ b/xbmc/video/tags/VideoTagLoaderPlugin.cpp
@@ -9,6 +9,7 @@
#include "VideoTagLoaderPlugin.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "URL.h"
#include "filesystem/PluginDirectory.h"
diff --git a/xbmc/video/tags/VideoTagLoaderPlugin.h b/xbmc/video/tags/VideoTagLoaderPlugin.h
index 7da92c14fe..d3efb3b7c0 100644
--- a/xbmc/video/tags/VideoTagLoaderPlugin.h
+++ b/xbmc/video/tags/VideoTagLoaderPlugin.h
@@ -17,7 +17,7 @@
#include <vector>
//! \brief Video tag loader from plugin source.
-class CVideoTagLoaderPlugin : public VIDEO::IVideoInfoTagLoader
+class CVideoTagLoaderPlugin : public KODI::VIDEO::IVideoInfoTagLoader
{
public:
CVideoTagLoaderPlugin(const CFileItem& item, bool forceRefresh);
diff --git a/xbmc/video/test/CMakeLists.txt b/xbmc/video/test/CMakeLists.txt
index 727641ea8b..1cf8a5d878 100644
--- a/xbmc/video/test/CMakeLists.txt
+++ b/xbmc/video/test/CMakeLists.txt
@@ -1,4 +1,5 @@
set(SOURCES TestStacks.cpp
+ TestVideoFileItemClassify.cpp
TestVideoInfoScanner.cpp
TestVideoUtils.cpp)
diff --git a/xbmc/video/test/TestStacks.cpp b/xbmc/video/test/TestStacks.cpp
index f5d92eabf8..12639a1a5f 100644
--- a/xbmc/video/test/TestStacks.cpp
+++ b/xbmc/video/test/TestStacks.cpp
@@ -7,6 +7,7 @@
*/
#include "FileItem.h"
+#include "FileItemList.h"
#include "filesystem/Directory.h"
#include "test/TestUtils.h"
diff --git a/xbmc/video/test/TestVideoFileItemClassify.cpp b/xbmc/video/test/TestVideoFileItemClassify.cpp
new file mode 100644
index 0000000000..128980f68d
--- /dev/null
+++ b/xbmc/video/test/TestVideoFileItemClassify.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "filesystem/Directory.h"
+#include "filesystem/File.h"
+#include "games/tags/GameInfoTag.h"
+#include "music/tags/MusicInfoTag.h"
+#include "pictures/PictureInfoTag.h"
+#include "test/TestUtils.h"
+#include "utils/FileExtensionProvider.h"
+#include "utils/FileUtils.h"
+#include "utils/URIUtils.h"
+#include "video/VideoFileItemClassify.h"
+#include "video/VideoInfoTag.h"
+
+#include <array>
+
+#include <gtest/gtest.h>
+
+using namespace KODI;
+
+struct StubDefinition
+{
+ StubDefinition(const std::string& path,
+ bool res = true,
+ const std::string& tagPath = "",
+ bool isFolder = false)
+ : item(path, isFolder), result(res)
+ {
+ if (!tagPath.empty())
+ {
+ if (isFolder)
+ item.GetVideoInfoTag()->m_strPath = tagPath;
+ else
+ item.GetVideoInfoTag()->m_strFileNameAndPath = tagPath;
+ }
+ }
+
+ CFileItem item;
+ bool result;
+};
+
+class DiscStubTest : public testing::WithParamInterface<StubDefinition>, public testing::Test
+{
+};
+
+TEST_P(DiscStubTest, IsDiscStub)
+{
+ EXPECT_EQ(VIDEO::IsDiscStub(GetParam().item), GetParam().result);
+}
+
+const auto discstub_tests = std::array{
+ StubDefinition{"/home/user/test.disc"},
+ StubDefinition{"videodb://foo/bar", true, "/home/user/test.disc"},
+ StubDefinition{"videodb://foo/bar", false, "/home/user/test.disc", true},
+ StubDefinition{"/home/user/test.avi", false},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestVideoFileItemClassify,
+ DiscStubTest,
+ testing::ValuesIn(discstub_tests));
+
+struct VideoClassifyTest
+{
+ VideoClassifyTest(const std::string& path,
+ bool res = true,
+ const std::string& mime = "",
+ int tag_type = 0)
+ : item(path, false), result(res)
+ {
+ if (!mime.empty())
+ item.SetMimeType(mime);
+ switch (tag_type)
+ {
+ case 1:
+ item.GetVideoInfoTag()->m_strFileNameAndPath = path;
+ break;
+ case 2:
+ item.GetGameInfoTag()->SetGameClient("some_client");
+ break;
+ case 3:
+ item.GetMusicInfoTag()->SetPlayCount(1);
+ break;
+ case 4:
+ item.GetPictureInfoTag()->SetInfo("foo", "bar");
+ ;
+ break;
+ default:
+ break;
+ }
+ }
+
+ CFileItem item;
+ bool result;
+};
+
+class VideoTest : public testing::WithParamInterface<VideoClassifyTest>, public testing::Test
+{
+};
+
+TEST_P(VideoTest, IsVideo)
+{
+ EXPECT_EQ(VIDEO::IsVideo(GetParam().item), GetParam().result);
+}
+
+const auto video_tests = std::array{
+ VideoClassifyTest{"/home/user/video.avi", true, "video/avi"},
+ VideoClassifyTest{"/home/user/video.avi", true, "", 1},
+ VideoClassifyTest{"/home/user/video.avi", false, "", 2},
+ VideoClassifyTest{"/home/user/video.avi", false, "", 3},
+ VideoClassifyTest{"/home/user/video.avi", false, "", 4},
+ VideoClassifyTest{"pvr://recordings/tv/1", true},
+ VideoClassifyTest{"pvr://123", false},
+ VideoClassifyTest{"dvd://VIDEO_TS/video_ts.ifo", true},
+ VideoClassifyTest{"dvd://1", true},
+ VideoClassifyTest{"/home/user/video.not", true, "application/ogg"},
+ VideoClassifyTest{"/home/user/video.not", true, "application/mp4"},
+ VideoClassifyTest{"/home/user/video.not", true, "application/mxf"},
+};
+
+INSTANTIATE_TEST_SUITE_P(TestVideoFileItemClassify, VideoTest, testing::ValuesIn(video_tests));
+
+TEST(TestVideoFileItemClassify, VideoExtensions)
+{
+ const auto& exts = CServiceBroker::GetFileExtensionProvider().GetVideoExtensions();
+ for (const auto& ext : StringUtils::Split(exts, "|"))
+ {
+ if (!ext.empty())
+ {
+ EXPECT_TRUE(VIDEO::IsVideo(CFileItem(ext, false)));
+ }
+ }
+}
+
+TEST(TestVideoFileItemClassify, IsBDFile)
+{
+ EXPECT_TRUE(VIDEO::IsBDFile(CFileItem("/home/foo/index.BDMV", false)));
+ EXPECT_TRUE(VIDEO::IsBDFile(CFileItem("smb://foo/bar/index.bdm", false)));
+ EXPECT_TRUE(VIDEO::IsBDFile(CFileItem("ftp://foo:bar@foobar.com/movieobject.BDMV", false)));
+ EXPECT_TRUE(VIDEO::IsBDFile(CFileItem("https://foobar.com/movieobj.bdm", false)));
+ EXPECT_FALSE(VIDEO::IsBDFile(CFileItem("https://foobar.com/movieobject.not", false)));
+}
+
+TEST(TestVideoFileItemClassify, IsDVDFile)
+{
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.vob", false), true, false));
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.VOB", false), true, true));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_TS.vob", false), false, false));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.VOb", false), false, true));
+
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/vts_yo_0.vob", false), true, false));
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/vts_0_ifo.vob", false), true, true));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/VTS_123456_0.vob", false), false, false));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/VTS_qwerty_0.VOB", false), false, true));
+
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.IFO", false), false, true));
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.IFO", false), true, true));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.IFO", false), false, false));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/video_ts.IFO", false), true, false));
+
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/vts_ab_0.ifo", false), false, true));
+ EXPECT_TRUE(VIDEO::IsDVDFile(CFileItem("/home/foo/vts_ab_0.ifo", false), false, true));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/VTS_ab_0.ifo", false), false, false));
+ EXPECT_FALSE(VIDEO::IsDVDFile(CFileItem("/home/foo/VTS_ab_0.ifo", false), false, false));
+}
+
+TEST(TestVideoFileItemClassify, IsProtectedBlurayDisc)
+{
+ const auto temp_file = CXBMCTestUtils::Instance().CreateTempFile("bluraytest");
+ const std::string dir = CXBMCTestUtils::Instance().TempFileDirectory(temp_file);
+ CFileUtils::DeleteItem(URIUtils::AddFileToFolder(dir, "AACS", "Unit_Key_RO.inf"));
+ EXPECT_FALSE(VIDEO::IsProtectedBlurayDisc(CFileItem(dir, true)));
+ XFILE::CDirectory::Create(URIUtils::AddFileToFolder(dir, "AACS"));
+ XFILE::CFile inf_file;
+ inf_file.OpenForWrite(URIUtils::AddFileToFolder(dir, "AACS", "Unit_Key_RO.inf"));
+ inf_file.Close();
+ EXPECT_TRUE(VIDEO::IsProtectedBlurayDisc(CFileItem(dir, true)));
+ CFileUtils::DeleteItem(URIUtils::AddFileToFolder(dir, "AACS", "Unit_Key_RO.inf"));
+ CXBMCTestUtils::Instance().DeleteTempFile(temp_file);
+}
+
+TEST(TestVideoFileItemClassify, IsSubtitle)
+{
+ const auto& exts = CServiceBroker::GetFileExtensionProvider().GetSubtitleExtensions();
+ for (const auto& ext : StringUtils::Split(exts, "|"))
+ {
+ if (!ext.empty())
+ {
+ EXPECT_TRUE(VIDEO::IsSubtitle(CFileItem("random" + ext, false)));
+ }
+ }
+
+ EXPECT_FALSE(VIDEO::IsSubtitle(CFileItem("random.notasub", false)));
+}
+
+TEST(TestVideoFileItemClassify, IsVideoAssetsFile)
+{
+ EXPECT_TRUE(VIDEO::IsVideoAssetFile(CFileItem("videodb://foo/bar?videoversionid=1", false)));
+ EXPECT_FALSE(VIDEO::IsVideoAssetFile(CFileItem("videodb://foo/bar?videoversionid=1", true)));
+ EXPECT_FALSE(VIDEO::IsVideoAssetFile(CFileItem("videodb://foo/bar", false)));
+}
+
+TEST(TestVideoFileItemClassify, IsVideoDb)
+{
+ EXPECT_TRUE(VIDEO::IsVideoDb(CFileItem("videodb://1/2/3", false)));
+ EXPECT_TRUE(VIDEO::IsVideoDb(CFileItem("videodb://1/2/", true)));
+ EXPECT_FALSE(VIDEO::IsVideoDb(CFileItem("/videodb/home/foo/Extraordinary/", true)));
+}
+
+TEST(TestVideoFileItemClassify, IsVideoExtrasFolder)
+{
+ EXPECT_TRUE(VIDEO::IsVideoExtrasFolder(CFileItem("/home/foo/Extras/", true)));
+ EXPECT_TRUE(VIDEO::IsVideoExtrasFolder(CFileItem("/home/foo/extras/", true)));
+ EXPECT_FALSE(VIDEO::IsVideoExtrasFolder(CFileItem("/home/foo/Extraordinary/", true)));
+ EXPECT_FALSE(VIDEO::IsVideoExtrasFolder(CFileItem("/home/foo/Extras/abc.mkv", false)));
+}
diff --git a/xbmc/video/test/TestVideoInfoScanner.cpp b/xbmc/video/test/TestVideoInfoScanner.cpp
index f44ead0ae6..a46b0523bb 100644
--- a/xbmc/video/test/TestVideoInfoScanner.cpp
+++ b/xbmc/video/test/TestVideoInfoScanner.cpp
@@ -11,7 +11,7 @@
#include <gtest/gtest.h>
-using namespace VIDEO;
+using namespace KODI;
using ::testing::Test;
using ::testing::WithParamInterface;
using ::testing::ValuesIn;
@@ -48,13 +48,13 @@ class TestVideoInfoScanner : public Test,
TEST_P(TestVideoInfoScanner, EnumerateEpisodeItem)
{
const TestEntry& entry = GetParam();
- CVideoInfoScanner scanner;
+ VIDEO::CVideoInfoScanner scanner;
CFileItem item(entry.path, false);
- EPISODELIST expected;
+ VIDEO::EPISODELIST expected;
for (int i = 0; i < 3 && entry.episode[i]; i++)
expected.emplace_back(entry.season, entry.episode[i], 0, false);
- EPISODELIST result;
+ VIDEO::EPISODELIST result;
ASSERT_TRUE(scanner.EnumerateEpisodeItem(&item, result));
EXPECT_EQ(expected.size(), result.size());
for (size_t i = 0; i < expected.size(); i++)
@@ -65,9 +65,9 @@ INSTANTIATE_TEST_SUITE_P(VideoInfoScanner, TestVideoInfoScanner, ValuesIn(TestDa
TEST(TestVideoInfoScanner, EnumerateEpisodeItemByTitle)
{
- CVideoInfoScanner scanner;
+ VIDEO::CVideoInfoScanner scanner;
CFileItem item("/foo.special.mp4", false);
- EPISODELIST result;
+ VIDEO::EPISODELIST result;
ASSERT_TRUE(scanner.EnumerateEpisodeItem(&item, result));
ASSERT_EQ(result.size(), 1);
ASSERT_EQ(result[0].strTitle, "foo");
diff --git a/xbmc/video/test/TestVideoUtils.cpp b/xbmc/video/test/TestVideoUtils.cpp
index 5c77d9bd50..579fff0180 100644
--- a/xbmc/video/test/TestVideoUtils.cpp
+++ b/xbmc/video/test/TestVideoUtils.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
+using namespace KODI;
namespace fs = KODI::PLATFORM::FILESYSTEM;
using OptDef = std::pair<std::string, bool>;
@@ -39,9 +40,9 @@ TEST_P(OpticalMediaPathTest, GetOpticalMediaPath)
}
CFileItem item(temp_path, true);
if (GetParam().second)
- EXPECT_EQ(VIDEO_UTILS::GetOpticalMediaPath(item), file_path);
+ EXPECT_EQ(VIDEO::UTILS::GetOpticalMediaPath(item), file_path);
else
- EXPECT_EQ(VIDEO_UTILS::GetOpticalMediaPath(item), "");
+ EXPECT_EQ(VIDEO::UTILS::GetOpticalMediaPath(item), "");
XFILE::CDirectory::RemoveRecursive(temp_path);
}
diff --git a/xbmc/video/windows/GUIWindowFullScreen.cpp b/xbmc/video/windows/GUIWindowFullScreen.cpp
index 1fccba980a..28974e405a 100644
--- a/xbmc/video/windows/GUIWindowFullScreen.cpp
+++ b/xbmc/video/windows/GUIWindowFullScreen.cpp
@@ -22,6 +22,7 @@
#include "input/actions/Action.h"
#include "input/actions/ActionIDs.h"
#include "input/mouse/MouseEvent.h"
+#include "settings/AdvancedSettings.h"
#include "settings/DisplaySettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -182,6 +183,10 @@ void CGUIWindowFullScreen::ClearBackground()
const auto appPlayer = components.GetComponent<CApplicationPlayer>();
if (appPlayer->IsRenderingVideoLayer())
CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0);
+ else if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiGeometryClear)
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear(0xff000000);
+ else
+ CServiceBroker::GetWinSystem()->GetGfxContext().Clear();
}
void CGUIWindowFullScreen::OnWindowLoaded()
@@ -377,11 +382,19 @@ void CGUIWindowFullScreen::Process(unsigned int currentTime, CDirtyRegionList &d
void CGUIWindowFullScreen::Render()
{
- CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(CServiceBroker::GetWinSystem()->GetGfxContext().GetVideoResolution(), false);
- auto& components = CServiceBroker::GetAppComponents();
- const auto appPlayer = components.GetComponent<CApplicationPlayer>();
- appPlayer->Render(true, 255);
- CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(m_coordsRes, m_needsScaling);
+ if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() !=
+ RENDER_ORDER_FRONT_TO_BACK)
+ {
+ CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(
+ CServiceBroker::GetWinSystem()->GetGfxContext().GetVideoResolution(), false);
+ auto& components = CServiceBroker::GetAppComponents();
+ const auto appPlayer = components.GetComponent<CApplicationPlayer>();
+ // FIXME: remove clearing pass from renderer, it should be its own, dedicated function.
+ bool clear = CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiGeometryClear;
+ appPlayer->Render(clear, 255);
+ CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(m_coordsRes,
+ m_needsScaling);
+ }
CGUIWindow::Render();
}
diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp
index a202928252..50da6ba3b8 100644
--- a/xbmc/video/windows/GUIWindowVideoBase.cpp
+++ b/xbmc/video/windows/GUIWindowVideoBase.cpp
@@ -10,6 +10,7 @@
#include "Autorun.h"
#include "ContextMenuManager.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
@@ -36,6 +37,7 @@
#include "input/actions/ActionIDs.h"
#include "messaging/helpers/DialogOKHelper.h"
#include "music/dialogs/GUIDialogMusicInfo.h"
+#include "network/NetworkFileItemClassify.h"
#include "playlists/PlayList.h"
#include "playlists/PlayListFactory.h"
#include "profiles/ProfileManager.h"
@@ -53,6 +55,7 @@
#include "utils/log.h"
#include "video/VideoDatabase.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoScanner.h"
#include "video/VideoLibraryQueue.h"
#include "video/VideoManagerTypes.h"
@@ -68,9 +71,8 @@
using namespace XFILE;
using namespace VIDEODATABASEDIRECTORY;
-using namespace VIDEO;
-using namespace VIDEO::GUILIB;
using namespace ADDON;
+using namespace KODI;
using namespace PVR;
using namespace KODI::MESSAGING;
@@ -223,13 +225,13 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
return false;
// Movie set
- if (fileItem.m_bIsFolder && fileItem.IsVideoDb() &&
+ if (fileItem.m_bIsFolder && VIDEO::IsVideoDb(fileItem) &&
fileItem.GetPath() != "videodb://movies/sets/" &&
StringUtils::StartsWith(fileItem.GetPath(), "videodb://movies/sets/"))
return ShowInfoAndRefresh(std::make_shared<CFileItem>(fileItem), nullptr);
// Music video. Match visibility test of CMusicInfo::IsVisible
- if (fileItem.IsVideoDb() && fileItem.HasVideoInfoTag() &&
+ if (VIDEO::IsVideoDb(fileItem) && fileItem.HasVideoInfoTag() &&
(fileItem.HasProperty("artist_musicid") || fileItem.HasProperty("album_musicid")))
{
CGUIDialogMusicInfo::ShowFor(std::make_shared<CFileItem>(fileItem).get());
@@ -237,7 +239,7 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
}
std::string strDir;
- if (fileItem.IsVideoDb() && fileItem.HasVideoInfoTag() &&
+ if (VIDEO::IsVideoDb(fileItem) && fileItem.HasVideoInfoTag() &&
!fileItem.GetVideoInfoTag()->m_strPath.empty())
strDir = fileItem.GetVideoInfoTag()->m_strPath;
else
@@ -245,7 +247,7 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
m_database.Open();
- SScanSettings settings;
+ VIDEO::SScanSettings settings;
bool foundDirectly = false;
const ADDON::ScraperPtr scraper = m_database.GetScraperForPath(strDir, settings, foundDirectly);
@@ -268,7 +270,7 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
return true;
CFileItem item(fileItem);
- if ((item.IsVideoDb() && item.HasVideoInfoTag()) ||
+ if ((VIDEO::IsVideoDb(item) && item.HasVideoInfoTag()) ||
(item.HasVideoInfoTag() && item.GetVideoInfoTag()->m_iDbId != -1))
{
if (item.GetVideoInfoTag()->m_type == MediaTypeSeason)
@@ -287,7 +289,7 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
// Check for cases 1_dir/1_dir/.../file (e.g. by packages where have a extra folder)
while (items.Size() == 1 && items[0]->m_bIsFolder &&
- VIDEO_UTILS::GetOpticalMediaPath(*items[0]).empty())
+ VIDEO::UTILS::GetOpticalMediaPath(*items[0]).empty())
{
const std::string path = items[0]->GetPath();
items.Clear();
@@ -303,7 +305,7 @@ bool CGUIWindowVideoBase::OnItemInfo(const CFileItem& fileItem)
->m_moviesExcludeFromScanRegExps;
for (const auto& i : items)
{
- if (i->IsVideo() && !i->IsPlayList() &&
+ if (VIDEO::IsVideo(*i) && !i->IsPlayList() &&
!CUtil::ExcludeFileOrFolder(i->GetPath(), excludeFromScan))
{
item.SetPath(i->GetPath());
@@ -441,8 +443,14 @@ bool CGUIWindowVideoBase::ShowInfo(const CFileItemPtr& item2, const ScraperPtr&
{
item = pDlgInfo->GetCurrentListItem();
- if (item->IsVideoDb() && item->HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(*item) && item->HasVideoInfoTag())
item->SetPath(item->GetVideoInfoTag()->GetPath());
+ else if (!VIDEO::IsVideoDb(*item) && item->m_bIsFolder)
+ {
+ // Info on folder containing a movie needs dyn path as path for refresh with correct name
+ //! @todo get rid of "videos with versions as folder" hack to be able to fix in CFileItem::GetBaseMoviePath()
+ item->SetPath(item->GetVideoInfoTag()->GetPath());
+ }
}
}
@@ -486,7 +494,7 @@ bool CGUIWindowVideoBase::ShowInfo(const CFileItemPtr& item2, const ScraperPtr&
{
item = pDlgInfo->GetCurrentListItem();
- if (item->IsVideoDb() && item->HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(*item) && item->HasVideoInfoTag())
item->SetPath(item->GetVideoInfoTag()->GetPath());
}
listNeedsUpdating = true;
@@ -527,8 +535,8 @@ void CGUIWindowVideoBase::OnQueueItem(const std::shared_ptr<CFileItem>& item, in
if (item->IsRAR() || item->IsZIP())
return;
- VIDEO_UTILS::QueueItem(item, first ? VIDEO_UTILS::QueuePosition::POSITION_BEGIN
- : VIDEO_UTILS::QueuePosition::POSITION_END);
+ VIDEO::UTILS::QueueItem(item, first ? VIDEO::UTILS::QueuePosition::POSITION_BEGIN
+ : VIDEO::UTILS::QueuePosition::POSITION_END);
// select next item
m_viewControl.SetSelectedItem(iItem + 1);
@@ -550,14 +558,15 @@ bool CGUIWindowVideoBase::OnSelect(int iItem)
!StringUtils::StartsWith(path, "plugin://")) ||
(StringUtils::StartsWith(path, "plugin://") &&
item->GetProperty("IsPlayable").asBoolean(false))))
- return OnFileAction(iItem, CVideoSelectActionProcessorBase::GetDefaultSelectAction(), "");
+ return OnFileAction(
+ iItem, VIDEO::GUILIB::CVideoSelectActionProcessorBase::GetDefaultSelectAction(), "");
return CGUIMediaWindow::OnSelect(iItem);
}
namespace
{
-class CVideoSelectActionProcessor : public CVideoSelectActionProcessorBase
+class CVideoSelectActionProcessor : public VIDEO::GUILIB::CVideoSelectActionProcessorBase
{
public:
CVideoSelectActionProcessor(CGUIWindowVideoBase& window,
@@ -614,7 +623,9 @@ private:
};
} // namespace
-bool CGUIWindowVideoBase::OnFileAction(int iItem, Action action, const std::string& player)
+bool CGUIWindowVideoBase::OnFileAction(int iItem,
+ VIDEO::GUILIB::Action action,
+ const std::string& player)
{
const std::shared_ptr<CFileItem> item = m_vecItems->Get(iItem);
if (!item)
@@ -733,7 +744,7 @@ void CGUIWindowVideoBase::LoadVideoInfo(CFileItemList& items,
}
// set the watched overlay
- if (pItem->IsVideo())
+ if (VIDEO::IsVideo(*pItem))
pItem->SetOverlayImage(pItem->HasVideoInfoTag() &&
pItem->GetVideoInfoTag()->GetPlayCount() > 0
? CGUIListItem::ICON_OVERLAY_WATCHED
@@ -744,7 +755,7 @@ void CGUIWindowVideoBase::LoadVideoInfo(CFileItemList& items,
namespace
{
-class CVideoPlayActionProcessor : public CVideoPlayActionProcessorBase
+class CVideoPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase
{
public:
CVideoPlayActionProcessor(CGUIWindowVideoBase& window,
@@ -794,7 +805,7 @@ void CGUIWindowVideoBase::GetContextButtons(int itemNumber, CContextButtons &but
if (!item->IsParentFolder())
{
std::string path(item->GetPath());
- if (item->IsVideoDb() && item->HasVideoInfoTag())
+ if (VIDEO::IsVideoDb(*item) && item->HasVideoInfoTag())
path = item->GetVideoInfoTag()->m_strFileNameAndPath;
if (!item->IsPath("add") && !item->IsPlugin() &&
@@ -820,13 +831,15 @@ void CGUIWindowVideoBase::GetContextButtons(int itemNumber, CContextButtons &but
(!item->HasProperty("IsPlayable") || item->GetProperty("IsPlayable").asBoolean()) &&
m_vecItems->Size() > 1 && itemNumber < m_vecItems->Size() - 1)
{
- if (VIDEO_UTILS::IsAutoPlayNextItem(*item))
+ if (VIDEO::UTILS::IsAutoPlayNextItem(*item))
buttons.Add(CONTEXT_BUTTON_PLAY_ONLY_THIS, 13434);
else
buttons.Add(CONTEXT_BUTTON_PLAY_AND_QUEUE, 13412);
}
if (item->IsSmartPlayList() || m_vecItems->IsSmartPlayList())
buttons.Add(CONTEXT_BUTTON_EDIT_SMART_PLAYLIST, 586);
+ if (VIDEO::IsBlurayPlaylist(*item))
+ buttons.Add(CONTEXT_BUTTON_CHOOSE_PLAYLIST, 13424);
}
}
CGUIMediaWindow::GetContextButtons(itemNumber, buttons);
@@ -853,8 +866,8 @@ bool CGUIWindowVideoBase::OnPlayStackPart(const std::shared_ptr<CFileItem>& item
const int value = CVideoSelectActionProcessor::ChoosePlayOrResume(*parts[partNumber - 1]);
if (value == VIDEO::GUILIB::ACTION_RESUME)
{
- const VIDEO_UTILS::ResumeInformation resumeInfo =
- VIDEO_UTILS::GetItemResumeInformation(*parts[partNumber - 1]);
+ const VIDEO::UTILS::ResumeInformation resumeInfo =
+ VIDEO::UTILS::GetItemResumeInformation(*parts[partNumber - 1]);
item->SetStartOffset(resumeInfo.startOffset);
}
else if (value != VIDEO::GUILIB::ACTION_PLAY_FROM_BEGINNING)
@@ -883,6 +896,7 @@ bool CGUIWindowVideoBase::OnPlayStackPart(const std::shared_ptr<CFileItem>& item
bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
{
CFileItemPtr item;
+ m_forceSelection = false;
if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
item = m_vecItems->Get(itemNumber);
switch (button)
@@ -905,13 +919,14 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
if (!item)
return false;
- if (item->IsVideoDb() && (!item->m_bIsFolder || item->GetVideoInfoTag()->m_strPath.empty()))
+ if (VIDEO::IsVideoDb(*item) &&
+ (!item->m_bIsFolder || item->GetVideoInfoTag()->m_strPath.empty()))
return false;
if (item->m_bIsFolder)
{
const std::string strPath =
- item->IsVideoDb() ? item->GetVideoInfoTag()->m_strPath : item->GetPath();
+ VIDEO::IsVideoDb(*item) ? item->GetVideoInfoTag()->m_strPath : item->GetPath();
OnScan(strPath, true);
}
else
@@ -936,6 +951,11 @@ bool CGUIWindowVideoBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
return OnPlayAndQueueMedia(item);
case CONTEXT_BUTTON_PLAY_ONLY_THIS:
return OnPlayMedia(itemNumber);
+ case CONTEXT_BUTTON_CHOOSE_PLAYLIST:
+ {
+ m_forceSelection = true;
+ return OnPlayMedia(itemNumber);
+ }
default:
break;
}
@@ -961,7 +981,7 @@ bool CGUIWindowVideoBase::OnPlayMedia(const std::shared_ptr<CFileItem>& pItem,
auto itemCopy = std::make_shared<CFileItem>(*pItem);
- if (pItem->IsVideoDb())
+ if (VIDEO::IsVideoDb(*pItem))
{
itemCopy->SetPath(pItem->GetVideoInfoTag()->m_strFileNameAndPath);
itemCopy->SetProperty("original_listitem_url", pItem->GetPath());
@@ -973,7 +993,7 @@ bool CGUIWindowVideoBase::OnPlayMedia(const std::shared_ptr<CFileItem>& pItem,
if (m_thumbLoader.IsLoading())
m_thumbLoader.StopAsync();
- CServiceBroker::GetPlaylistPlayer().Play(itemCopy, player);
+ CServiceBroker::GetPlaylistPlayer().Play(itemCopy, player, m_forceSelection);
const auto& components = CServiceBroker::GetAppComponents();
const auto appPlayer = components.GetComponent<CApplicationPlayer>();
@@ -1074,7 +1094,7 @@ void CGUIWindowVideoBase::LoadPlayList(const std::string& strPlayList,
bool CGUIWindowVideoBase::PlayItem(const std::shared_ptr<CFileItem>& pItem,
const std::string& player)
{
- if (!pItem->m_bIsFolder && pItem->IsVideoDb() && !pItem->Exists())
+ if (!pItem->m_bIsFolder && VIDEO::IsVideoDb(*pItem) && !pItem->Exists())
{
CLog::LogF(LOGDEBUG, "File '{}' for library item '{}' doesn't exist.", pItem->GetDynPath(),
pItem->GetPath());
@@ -1109,6 +1129,8 @@ bool CGUIWindowVideoBase::PlayItem(const std::shared_ptr<CFileItem>& pItem,
return true;
}
+ m_forceSelection = false;
+
//! @todo get rid of "videos with versions as folder" hack!
if (pItem->m_bIsFolder && !pItem->IsPlugin() &&
!(pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->IsDefaultVideoVersion()))
@@ -1123,7 +1145,7 @@ bool CGUIWindowVideoBase::PlayItem(const std::shared_ptr<CFileItem>& pItem,
// recursively add items to list
CFileItemList queuedItems;
- VIDEO_UTILS::GetItemsForPlayList(item, queuedItems);
+ VIDEO::UTILS::GetItemsForPlayList(item, queuedItems);
CServiceBroker::GetPlaylistPlayer().ClearPlaylist(PLAYLIST::TYPE_VIDEO);
CServiceBroker::GetPlaylistPlayer().Reset();
@@ -1210,9 +1232,9 @@ bool CGUIWindowVideoBase::GetDirectory(const std::string &strDirectory, CFileIte
bool CGUIWindowVideoBase::StackingAvailable(const CFileItemList &items)
{
CURL url(items.GetPath());
- return !(items.IsPlugin() || items.IsAddonsPath() ||
- items.IsRSS() || items.IsInternetStream() ||
- items.IsVideoDb() || url.IsProtocol("playlistvideo"));
+ return !(items.IsPlugin() || items.IsAddonsPath() || items.IsRSS() ||
+ NETWORK::IsInternetStream(items) || VIDEO::IsVideoDb(items) ||
+ url.IsProtocol("playlistvideo"));
}
void CGUIWindowVideoBase::GetGroupedItems(CFileItemList &items)
@@ -1259,9 +1281,9 @@ void CGUIWindowVideoBase::GetGroupedItems(CFileItemList &items)
bool CGUIWindowVideoBase::CheckFilterAdvanced(CFileItemList &items) const
{
const std::string& content = items.GetContent();
- if ((items.IsVideoDb() || CanContainFilter(m_strFilterPath)) &&
- (StringUtils::EqualsNoCase(content, "movies") ||
- StringUtils::EqualsNoCase(content, "tvshows") ||
+ if ((VIDEO::IsVideoDb(items) || CanContainFilter(m_strFilterPath)) &&
+ (StringUtils::EqualsNoCase(content, "movies") ||
+ StringUtils::EqualsNoCase(content, "tvshows") ||
StringUtils::EqualsNoCase(content, "episodes") ||
StringUtils::EqualsNoCase(content, "musicvideos")))
return true;
@@ -1335,7 +1357,9 @@ void CGUIWindowVideoBase::OnSearchItemFound(const CFileItem* pSelItem)
Update(strParentPath);
- if (pSelItem->IsVideoDb() && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MYVIDEOS_FLATTEN))
+ if (VIDEO::IsVideoDb(*pSelItem) &&
+ CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_MYVIDEOS_FLATTEN))
SetHistoryForPath("");
else
SetHistoryForPath(strParentPath);
@@ -1361,7 +1385,9 @@ void CGUIWindowVideoBase::OnSearchItemFound(const CFileItem* pSelItem)
Update(strPath);
- if (pSelItem->IsVideoDb() && CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_MYVIDEOS_FLATTEN))
+ if (VIDEO::IsVideoDb(*pSelItem) &&
+ CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(
+ CSettings::SETTING_MYVIDEOS_FLATTEN))
SetHistoryForPath("");
else
SetHistoryForPath(strPath);
@@ -1370,7 +1396,7 @@ void CGUIWindowVideoBase::OnSearchItemFound(const CFileItem* pSelItem)
{
CFileItemPtr pItem = m_vecItems->Get(i);
CURL url(pItem->GetPath());
- if (pSelItem->IsVideoDb())
+ if (VIDEO::IsVideoDb(*pSelItem))
url.SetOptions("");
if (url.Get() == pSelItem->GetPath())
{
@@ -1382,7 +1408,9 @@ void CGUIWindowVideoBase::OnSearchItemFound(const CFileItem* pSelItem)
m_viewControl.SetFocused();
}
-int CGUIWindowVideoBase::GetScraperForItem(CFileItem *item, ADDON::ScraperPtr &info, SScanSettings& settings)
+int CGUIWindowVideoBase::GetScraperForItem(CFileItem* item,
+ ADDON::ScraperPtr& info,
+ VIDEO::SScanSettings& settings)
{
if (!item)
return 0;
@@ -1449,7 +1477,7 @@ bool CGUIWindowVideoBase::OnUnAssignContent(const std::string &path, int header,
if (!bCanceled)
{
ADDON::ScraperPtr info;
- SScanSettings settings;
+ VIDEO::SScanSettings settings;
settings.exclude = true;
db.SetScraperForPath(path,info,settings);
}
@@ -1465,7 +1493,7 @@ void CGUIWindowVideoBase::OnAssignContent(const std::string &path)
CVideoDatabase db;
db.Open();
- SScanSettings settings;
+ VIDEO::SScanSettings settings;
ADDON::ScraperPtr info = db.GetScraperForPath(path, settings);
ADDON::ScraperPtr info2(info);
@@ -1512,7 +1540,7 @@ void CGUIWindowVideoBase::UpdateVideoVersionItems()
//! not for example for home screen widgets!
int videoVersionId{-1};
- if (item->IsVideoDb() && item->GetVideoInfoTag()->HasVideoVersions())
+ if (VIDEO::IsVideoDb(*item) && item->GetVideoInfoTag()->HasVideoVersions())
{
if (item->GetProperty("has_resolved_video_asset").asBoolean(false))
{
diff --git a/xbmc/video/windows/GUIWindowVideoBase.h b/xbmc/video/windows/GUIWindowVideoBase.h
index 943db2bad4..d71b7628fe 100644
--- a/xbmc/video/windows/GUIWindowVideoBase.h
+++ b/xbmc/video/windows/GUIWindowVideoBase.h
@@ -96,7 +96,7 @@ protected:
\param action the action to perform
\return true if the action is performed, false otherwise
*/
- bool OnFileAction(int item, VIDEO::GUILIB::Action action, const std::string& player);
+ bool OnFileAction(int item, KODI::VIDEO::GUILIB::Action action, const std::string& player);
void OnRestartItem(int iItem, const std::string &player = "");
bool OnPlayOrResumeItem(int iItem, const std::string& player = "");
@@ -118,7 +118,9 @@ protected:
void OnSearch();
void OnSearchItemFound(const CFileItem* pSelItem);
- int GetScraperForItem(CFileItem *item, ADDON::ScraperPtr &info, VIDEO::SScanSettings& settings);
+ int GetScraperForItem(CFileItem* item,
+ ADDON::ScraperPtr& info,
+ KODI::VIDEO::SScanSettings& settings);
static bool OnUnAssignContent(const std::string &path, int header, int text);
@@ -143,4 +145,6 @@ private:
\return true: the information of the item was modified. false: no change.
*/
bool ShowInfo(const CFileItemPtr& item, const ADDON::ScraperPtr& content);
+
+ bool m_forceSelection;
};
diff --git a/xbmc/video/windows/GUIWindowVideoNav.cpp b/xbmc/video/windows/GUIWindowVideoNav.cpp
index 86ab1d96eb..a53d72443b 100644
--- a/xbmc/video/windows/GUIWindowVideoNav.cpp
+++ b/xbmc/video/windows/GUIWindowVideoNav.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowVideoNav.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "PartyModeManager.h"
#include "ServiceBroker.h"
@@ -39,6 +40,7 @@
#include "utils/Variant.h"
#include "utils/log.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include "video/VideoInfoScanner.h"
#include "video/VideoLibraryQueue.h"
#include "video/dialogs/GUIDialogVideoInfo.h"
@@ -48,6 +50,7 @@
using namespace XFILE;
using namespace VIDEODATABASEDIRECTORY;
+using namespace KODI;
using namespace KODI::MESSAGING;
#define CONTROL_BTNVIEWASICONS 2
@@ -152,7 +155,7 @@ bool CGUIWindowVideoNav::OnMessage(CGUIMessage& message)
// We are here if the item is filtered out in the nav window
const std::string& path = message.GetStringParam(0);
CFileItem item(path, URIUtils::HasSlashAtEnd(path));
- if (item.IsVideoDb())
+ if (VIDEO::IsVideoDb(item))
{
*(item.GetVideoInfoTag()) = XFILE::CVideoDatabaseFile::GetVideoTag(CURL(item.GetPath()));
if (!item.GetVideoInfoTag()->IsEmpty())
@@ -242,7 +245,7 @@ bool CGUIWindowVideoNav::OnMessage(CGUIMessage& message)
SelectFirstUnwatchedItem CGUIWindowVideoNav::GetSettingSelectFirstUnwatchedItem()
{
- if (m_vecItems->IsVideoDb())
+ if (VIDEO::IsVideoDb(*m_vecItems))
{
NODE_TYPE nodeType = CVideoDatabaseDirectory::GetDirectoryChildType(m_vecItems->GetPath());
@@ -358,7 +361,7 @@ bool CGUIWindowVideoNav::GetDirectory(const std::string &strDirectory, CFileItem
bool bResult = CGUIWindowVideoBase::GetDirectory(strDirectory, items);
if (bResult)
{
- if (items.IsVideoDb())
+ if (VIDEO::IsVideoDb(items))
{
XFILE::CVideoDatabaseDirectory dir;
CQueryParams params;
@@ -546,7 +549,7 @@ void CGUIWindowVideoNav::UpdateButtons()
else if (m_vecItems->IsPath("sources://video/"))
strLabel = g_localizeStrings.Get(744);
// everything else is from a videodb:// path
- else if (m_vecItems->IsVideoDb())
+ else if (VIDEO::IsVideoDb(*m_vecItems))
{
CVideoDatabaseDirectory dir;
dir.GetLabel(m_vecItems->GetPath(), strLabel);
@@ -671,7 +674,7 @@ void CGUIWindowVideoNav::OnDeleteItem(const CFileItemPtr& pItem)
if (m_vecItems->IsParentFolder())
return;
- if (!m_vecItems->IsVideoDb() && !pItem->IsVideoDb())
+ if (!VIDEO::IsVideoDb(*m_vecItems) && !VIDEO::IsVideoDb(*pItem))
{
if (!pItem->IsPath("newsmartplaylist://video") && !pItem->IsPath("special://videoplaylists/") &&
!pItem->IsPath("sources://video/") && !URIUtils::IsProtocol(pItem->GetPath(), "newtag"))
@@ -798,7 +801,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
// can we update the database?
if (profileManager->GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
{
- if (!CVideoLibraryQueue::GetInstance().IsScanningLibrary() && item->IsVideoDb() &&
+ if (!CVideoLibraryQueue::GetInstance().IsScanningLibrary() && VIDEO::IsVideoDb(*item) &&
item->HasVideoInfoTag() &&
(item->GetVideoInfoTag()->m_type == MediaTypeMovie || // movies
item->GetVideoInfoTag()->m_type == MediaTypeTvShow || // tvshows
@@ -824,7 +827,7 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
}
}
- if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
+ if (!VIDEO::IsVideoDb(*m_vecItems) && !m_vecItems->IsVirtualDirectoryRoot())
{ // non-video db items, file operations are allowed
if ((CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_FILELISTS_ALLOWFILEDELETION) &&
CUtil::SupportsWriteFileOperations(item->GetPath())) ||
@@ -835,7 +838,9 @@ void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &butt
buttons.Add(CONTEXT_BUTTON_RENAME, 118);
}
// add "Set/Change content" to folders
- if (item->m_bIsFolder && !item->IsVideoDb() && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLibraryFolder() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath()))
+ if (item->m_bIsFolder && !VIDEO::IsVideoDb(*item) && !item->IsPlayList() &&
+ !item->IsSmartPlayList() && !item->IsLibraryFolder() && !item->IsLiveTV() &&
+ !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath()))
{
if (info && info->Content() != CONTENT_NONE)
buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
@@ -1079,7 +1084,7 @@ bool CGUIWindowVideoNav::ApplyWatchedFilter(CFileItemList &items)
|| node == NODE_TYPE_RECENTLY_ADDED_MOVIES
|| node == NODE_TYPE_RECENTLY_ADDED_MUSICVIDEOS)
filterWatched = true;
- if (!items.IsVideoDb())
+ if (!VIDEO::IsVideoDb(items))
filterWatched = true;
if (items.GetContent() == "tvshows" &&
(items.IsSmartPlayList() || items.IsLibraryFolder()))
diff --git a/xbmc/video/windows/GUIWindowVideoPlaylist.cpp b/xbmc/video/windows/GUIWindowVideoPlaylist.cpp
index 3569a0c5ea..03619d1eb9 100644
--- a/xbmc/video/windows/GUIWindowVideoPlaylist.cpp
+++ b/xbmc/video/windows/GUIWindowVideoPlaylist.cpp
@@ -8,6 +8,7 @@
#include "GUIWindowVideoPlaylist.h"
+#include "FileItemList.h"
#include "GUIUserMessages.h"
#include "PartyModeManager.h"
#include "PlayListPlayer.h"
@@ -30,6 +31,7 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
#include "video/guilib/VideoPlayActionProcessor.h"
#define CONTROL_BTNVIEWASICONS 2
@@ -46,7 +48,7 @@
#define CONTROL_BTNPREVIOUS 25
#define CONTROL_BTNREPEAT 26
-using namespace VIDEO::GUILIB;
+using namespace KODI;
CGUIWindowVideoPlaylist::CGUIWindowVideoPlaylist()
: CGUIWindowVideoBase(WINDOW_VIDEO_PLAYLIST, "MyPlaylist.xml")
@@ -63,7 +65,7 @@ void CGUIWindowVideoPlaylist::OnPrepareFileItems(CFileItemList& items)
if (items.IsEmpty())
return;
- if (!items.IsVideoDb() && !items.IsVirtualDirectoryRoot())
+ if (!VIDEO::IsVideoDb(items) && !items.IsVirtualDirectoryRoot())
{ // load info from the database
std::string label;
if (items.GetLabel().empty() &&
@@ -376,7 +378,7 @@ void CGUIWindowVideoPlaylist::UpdateButtons()
namespace
{
-class CVideoPlayActionProcessor : public CVideoPlayActionProcessorBase
+class CVideoPlayActionProcessor : public VIDEO::GUILIB::CVideoPlayActionProcessorBase
{
public:
CVideoPlayActionProcessor(const std::shared_ptr<CFileItem>& item,
diff --git a/xbmc/video/windows/VideoFileItemListModifier.cpp b/xbmc/video/windows/VideoFileItemListModifier.cpp
index b17a71db87..2f5c222c62 100644
--- a/xbmc/video/windows/VideoFileItemListModifier.cpp
+++ b/xbmc/video/windows/VideoFileItemListModifier.cpp
@@ -9,6 +9,7 @@
#include "VideoFileItemListModifier.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "ServiceBroker.h"
#include "filesystem/VideoDatabaseDirectory/DirectoryNode.h"
#include "guilib/LocalizeStrings.h"
@@ -17,14 +18,16 @@
#include "settings/SettingsComponent.h"
#include "video/VideoDatabase.h"
#include "video/VideoDbUrl.h"
+#include "video/VideoFileItemClassify.h"
#include <memory>
+using namespace KODI::VIDEO;
using namespace XFILE::VIDEODATABASEDIRECTORY;
bool CVideoFileItemListModifier::CanModify(const CFileItemList &items) const
{
- if (items.IsVideoDb())
+ if (IsVideoDb(items))
return true;
return false;
@@ -40,7 +43,7 @@ bool CVideoFileItemListModifier::Modify(CFileItemList &items) const
// depending on the child node
void CVideoFileItemListModifier::AddQueuingFolder(CFileItemList& items)
{
- if (!items.IsVideoDb())
+ if (!IsVideoDb(items))
return;
auto directoryNode = CDirectoryNode::ParseURL(items.GetPath());
diff --git a/xbmc/view/GUIViewControl.cpp b/xbmc/view/GUIViewControl.cpp
index 3d4801b693..6ce4516b52 100644
--- a/xbmc/view/GUIViewControl.cpp
+++ b/xbmc/view/GUIViewControl.cpp
@@ -9,6 +9,7 @@
#include "GUIViewControl.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIInfoManager.h"
#include "ServiceBroker.h"
#include "guilib/GUIComponent.h"
diff --git a/xbmc/view/GUIViewState.cpp b/xbmc/view/GUIViewState.cpp
index e0cf9d2aca..3457aa24cb 100644
--- a/xbmc/view/GUIViewState.cpp
+++ b/xbmc/view/GUIViewState.cpp
@@ -10,6 +10,7 @@
#include "AutoSwitch.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "PlayListPlayer.h"
#include "ServiceBroker.h"
@@ -494,7 +495,7 @@ bool CGUIViewState::AutoPlayNextVideoItem() const
if (GetPlaylist() != PLAYLIST::TYPE_VIDEO)
return false;
- return VIDEO_UTILS::IsAutoPlayNextItem(m_items.GetContent());
+ return VIDEO::UTILS::IsAutoPlayNextItem(m_items.GetContent());
}
void CGUIViewState::LoadViewState(const std::string &path, int windowID)
diff --git a/xbmc/windowing/GraphicContext.cpp b/xbmc/windowing/GraphicContext.cpp
index e3300e925c..ebaec5b715 100644
--- a/xbmc/windowing/GraphicContext.cpp
+++ b/xbmc/windowing/GraphicContext.cpp
@@ -580,6 +580,11 @@ void CGraphicContext::ResetScreenParameters(RESOLUTION res)
ResetOverscan(res, info.Overscan);
}
+void CGraphicContext::Clear()
+{
+ CServiceBroker::GetRenderSystem()->InvalidateColorBuffer();
+}
+
void CGraphicContext::Clear(UTILS::COLOR::Color color)
{
CServiceBroker::GetRenderSystem()->ClearBuffers(color);
@@ -822,6 +827,22 @@ void CGraphicContext::RestoreStereoFactor()
UpdateCameraPosition(m_cameras.top(), m_stereoFactors.top());
}
+float CGraphicContext::GetNormalizedDepth(uint32_t depth)
+{
+ float normalizedDepth = static_cast<float>(depth);
+ normalizedDepth /= m_layer;
+ normalizedDepth = normalizedDepth * 2 - 1;
+ return normalizedDepth;
+}
+
+float CGraphicContext::GetTransformDepth(int32_t depthOffset)
+{
+ float depth = static_cast<float>(m_finalTransform.matrix.depth + depthOffset);
+ depth /= m_layer;
+ depth = depth * 2 - 1;
+ return depth;
+}
+
CRect CGraphicContext::GenerateAABB(const CRect &rect) const
{
// ------------------------
@@ -1006,6 +1027,24 @@ void CGraphicContext::GetAllowedResolutions(std::vector<RESOLUTION> &res)
}
}
+void CGraphicContext::SetRenderOrder(RENDER_ORDER renderOrder)
+{
+ m_renderOrder = renderOrder;
+ if (renderOrder == RENDER_ORDER_ALL_BACK_TO_FRONT)
+ CServiceBroker::GetRenderSystem()->SetDepthCulling(DEPTH_CULLING_OFF);
+ else if (renderOrder == RENDER_ORDER_BACK_TO_FRONT)
+ CServiceBroker::GetRenderSystem()->SetDepthCulling(DEPTH_CULLING_BACK_TO_FRONT);
+ else if (renderOrder == RENDER_ORDER_FRONT_TO_BACK)
+ CServiceBroker::GetRenderSystem()->SetDepthCulling(DEPTH_CULLING_FRONT_TO_BACK);
+}
+
+uint32_t CGraphicContext::GetDepth(uint32_t addLayers)
+{
+ uint32_t layer = m_layer;
+ m_layer += addLayers;
+ return layer;
+}
+
void CGraphicContext::SetFPS(float fps)
{
m_fFPSOverride = fps;
diff --git a/xbmc/windowing/GraphicContext.h b/xbmc/windowing/GraphicContext.h
index 0c5201f1e7..36aff34608 100644
--- a/xbmc/windowing/GraphicContext.h
+++ b/xbmc/windowing/GraphicContext.h
@@ -57,6 +57,13 @@ enum AdjustRefreshRate
ADJUST_REFRESHRATE_ON_START,
};
+enum RENDER_ORDER
+{
+ RENDER_ORDER_ALL_BACK_TO_FRONT = 0,
+ RENDER_ORDER_BACK_TO_FRONT,
+ RENDER_ORDER_FRONT_TO_BACK,
+};
+
class CGraphicContext : public CCriticalSection
{
public:
@@ -99,8 +106,33 @@ public:
void ResetScreenParameters(RESOLUTION res);
void CaptureStateBlock();
void ApplyStateBlock();
- void Clear(UTILS::COLOR::Color color = 0);
+ /*! \brief Invalidates color buffer, clears the depth buffer (if used).
+ Will result in undefined color buffer values which will have to be
+ repainted. Has to be called at the beginning of a frame.
+ */
+ void Clear();
+ /*! \brief Clears the depth buffer (if used) and the color buffer. Guaranties
+ a defined color buffer value. Has to be called at the beginning of a frame.
+ \param color the specified color.
+ */
+ void Clear(UTILS::COLOR::Color color);
void GetAllowedResolutions(std::vector<RESOLUTION> &res);
+ /*! \brief Sets the direction of the current rendering pass.
+ \param renderOrder direction of the pass
+ */
+ void SetRenderOrder(RENDER_ORDER renderOrder);
+ /*! \brief Returns the current render order mode
+ \returns RENDER_ORDER returns the mode
+ */
+ RENDER_ORDER GetRenderOrder() { return m_renderOrder; }
+ /*! \brief Resets the z-depth. Layer 0 and 1 are reserved as presentation (video) layer.
+ */
+ void ResetDepth() { m_layer = 2; }
+ /*! \brief Reserve layers for the caller to use
+ \param addLayers number of layers needed
+ \returns uint32_t returns the absolute layer hight
+ */
+ uint32_t GetDepth(uint32_t addLayers = 2);
/* \brief Get UI scaling information from a given resolution to the screen resolution.
Takes account of overscan and UI zooming.
@@ -134,6 +166,16 @@ public:
void RestoreCameraPosition();
void SetStereoFactor(float factor);
void RestoreStereoFactor();
+ /*! \brief Gets the depth information of the current transform matrix
+ \param depthOffset adds an offset to the current depth
+ \returns float normalized -1 to 1
+ */
+ float GetTransformDepth(int32_t depthOffset = 0);
+ /*! \brief Gets the (normalized) depth information
+ \param depth to be normalized
+ \returns float normalized -1 to 1
+ */
+ float GetNormalizedDepth(uint32_t depth);
/*! \brief Set a region in which to clip all rendering
Anything that is rendered after setting a clip region will be clipped so that no part renders
outside of the clip region. Successive calls to SetClipRegion intersect the clip region, which
@@ -234,4 +276,6 @@ protected:
RENDER_STEREO_MODE m_nextStereoMode = RENDER_STEREO_MODE_OFF;
bool m_isTransferPQ{false};
+ RENDER_ORDER m_renderOrder{RENDER_ORDER_ALL_BACK_TO_FRONT};
+ uint32_t m_layer{2};
};
diff --git a/xbmc/windowing/X11/GLContextEGL.cpp b/xbmc/windowing/X11/GLContextEGL.cpp
index 7999e76b98..a7c4c3ea00 100644
--- a/xbmc/windowing/X11/GLContextEGL.cpp
+++ b/xbmc/windowing/X11/GLContextEGL.cpp
@@ -341,7 +341,7 @@ bool CGLContextEGL::SuitableCheck(EGLDisplay eglDisplay, EGLConfig config)
return false;
if (!eglGetConfigAttrib(eglDisplay, config, EGL_BLUE_SIZE, &value) || value < 8)
return false;
- if (!eglGetConfigAttrib(eglDisplay, config, EGL_DEPTH_SIZE, &value) || value < 24)
+ if (!eglGetConfigAttrib(eglDisplay, config, EGL_DEPTH_SIZE, &value) || value < 16)
return false;
return true;
diff --git a/xbmc/windowing/android/AndroidUtils.cpp b/xbmc/windowing/android/AndroidUtils.cpp
index 27c7536c19..35ee48b4b2 100644
--- a/xbmc/windowing/android/AndroidUtils.cpp
+++ b/xbmc/windowing/android/AndroidUtils.cpp
@@ -20,52 +20,14 @@
#include <androidjni/MediaCodecInfo.h>
#include <androidjni/MediaCodecList.h>
-#include <androidjni/System.h>
-#include <androidjni/SystemProperties.h>
#include <androidjni/View.h>
#include <androidjni/Window.h>
-#include <androidjni/WindowManager.h>
-static bool s_hasModeApi = false;
static std::vector<RESOLUTION_INFO> s_res_displayModes;
static RESOLUTION_INFO s_res_cur_displayMode;
-static float currentRefreshRate()
-{
- if (s_hasModeApi)
- return s_res_cur_displayMode.fRefreshRate;
-
- CJNIWindow window = CXBMCApp::getWindow();
- if (window)
- {
- float preferredRate = window.getAttributes().getpreferredRefreshRate();
- if (preferredRate > 20.0f)
- {
- CLog::Log(LOGINFO, "CAndroidUtils: Preferred refresh rate: {:f}", preferredRate);
- return preferredRate;
- }
- CJNIView view(window.getDecorView());
- if (view)
- {
- CJNIDisplay display(view.getDisplay());
- if (display)
- {
- float reportedRate = display.getRefreshRate();
- if (reportedRate > 20.0f)
- {
- CLog::Log(LOGINFO, "CAndroidUtils: Current display refresh rate: {:f}", reportedRate);
- return reportedRate;
- }
- }
- }
- }
- CLog::Log(LOGDEBUG, "found no refresh rate");
- return 60.0;
-}
-
static void fetchDisplayModes()
{
- s_hasModeApi = false;
s_res_displayModes.clear();
CJNIDisplay display = CXBMCApp::getWindow().getDecorView().getDisplay();
@@ -75,46 +37,44 @@ static void fetchDisplayModes()
CJNIDisplayMode m = display.getMode();
if (m)
{
- if (m.getPhysicalWidth() > m.getPhysicalHeight()) // Assume unusable if portrait is returned
+ const bool landscape = m.getPhysicalWidth() > m.getPhysicalHeight();
+ CLog::Log(LOGDEBUG, "CAndroidUtils: current mode: {}: {}x{}@{:f}", m.getModeId(),
+ m.getPhysicalWidth(), m.getPhysicalHeight(), m.getRefreshRate());
+ s_res_cur_displayMode.strId = std::to_string(m.getModeId());
+ s_res_cur_displayMode.iWidth = s_res_cur_displayMode.iScreenWidth =
+ landscape ? m.getPhysicalWidth() : m.getPhysicalHeight();
+ s_res_cur_displayMode.iHeight = s_res_cur_displayMode.iScreenHeight =
+ landscape ? m.getPhysicalHeight() : m.getPhysicalWidth();
+ s_res_cur_displayMode.fRefreshRate = m.getRefreshRate();
+ s_res_cur_displayMode.dwFlags = D3DPRESENTFLAG_PROGRESSIVE;
+ s_res_cur_displayMode.bFullScreen = true;
+ s_res_cur_displayMode.iSubtitles = s_res_cur_displayMode.iHeight;
+ s_res_cur_displayMode.fPixelRatio = 1.0f;
+ s_res_cur_displayMode.strMode = StringUtils::Format(
+ "{}x{} @ {:.6f}{} - Full Screen", s_res_cur_displayMode.iScreenWidth,
+ s_res_cur_displayMode.iScreenHeight, s_res_cur_displayMode.fRefreshRate,
+ s_res_cur_displayMode.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
+
+ std::vector<CJNIDisplayMode> modes = display.getSupportedModes();
+ for (CJNIDisplayMode& m : modes)
{
- s_hasModeApi = true;
-
- CLog::Log(LOGDEBUG, "CAndroidUtils: current mode: {}: {}x{}@{:f}", m.getModeId(),
+ CLog::Log(LOGDEBUG, "CAndroidUtils: available mode: {}: {}x{}@{:f}", m.getModeId(),
m.getPhysicalWidth(), m.getPhysicalHeight(), m.getRefreshRate());
- s_res_cur_displayMode.strId = std::to_string(m.getModeId());
- s_res_cur_displayMode.iWidth = s_res_cur_displayMode.iScreenWidth = m.getPhysicalWidth();
- s_res_cur_displayMode.iHeight = s_res_cur_displayMode.iScreenHeight = m.getPhysicalHeight();
- s_res_cur_displayMode.fRefreshRate = m.getRefreshRate();
- s_res_cur_displayMode.dwFlags = D3DPRESENTFLAG_PROGRESSIVE;
- s_res_cur_displayMode.bFullScreen = true;
- s_res_cur_displayMode.iSubtitles = s_res_cur_displayMode.iHeight;
- s_res_cur_displayMode.fPixelRatio = 1.0f;
- s_res_cur_displayMode.strMode = StringUtils::Format(
- "{}x{} @ {:.6f}{} - Full Screen", s_res_cur_displayMode.iScreenWidth,
- s_res_cur_displayMode.iScreenHeight, s_res_cur_displayMode.fRefreshRate,
- s_res_cur_displayMode.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
-
- std::vector<CJNIDisplayMode> modes = display.getSupportedModes();
- for (CJNIDisplayMode& m : modes)
- {
- CLog::Log(LOGDEBUG, "CAndroidUtils: available mode: {}: {}x{}@{:f}", m.getModeId(),
- m.getPhysicalWidth(), m.getPhysicalHeight(), m.getRefreshRate());
-
- RESOLUTION_INFO res;
- res.strId = std::to_string(m.getModeId());
- res.iWidth = res.iScreenWidth = m.getPhysicalWidth();
- res.iHeight = res.iScreenHeight = m.getPhysicalHeight();
- res.fRefreshRate = m.getRefreshRate();
- res.dwFlags = D3DPRESENTFLAG_PROGRESSIVE;
- res.bFullScreen = true;
- res.iSubtitles = res.iHeight;
- res.fPixelRatio = 1.0f;
- res.strMode = StringUtils::Format("{}x{} @ {:.6f}{} - Full Screen", res.iScreenWidth,
- res.iScreenHeight, res.fRefreshRate,
- res.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
-
- s_res_displayModes.push_back(res);
- }
+
+ RESOLUTION_INFO res;
+ res.strId = std::to_string(m.getModeId());
+ res.iWidth = res.iScreenWidth = landscape ? m.getPhysicalWidth() : m.getPhysicalHeight();
+ res.iHeight = res.iScreenHeight = landscape ? m.getPhysicalHeight() : m.getPhysicalWidth();
+ res.fRefreshRate = m.getRefreshRate();
+ res.dwFlags = D3DPRESENTFLAG_PROGRESSIVE;
+ res.bFullScreen = true;
+ res.iSubtitles = res.iHeight;
+ res.fPixelRatio = 1.0f;
+ res.strMode = StringUtils::Format("{}x{} @ {:.6f}{} - Full Screen", res.iScreenWidth,
+ res.iScreenHeight, res.fRefreshRate,
+ res.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
+
+ s_res_displayModes.push_back(res);
}
}
}
@@ -142,7 +102,6 @@ const std::string CAndroidUtils::SETTING_LIMITGUI = "videoscreen.limitgui";
CAndroidUtils::CAndroidUtils()
{
- std::string displaySize;
m_width = m_height = 0;
fetchDisplayModes();
@@ -155,22 +114,6 @@ CAndroidUtils::CAndroidUtils()
}
}
- if (!m_width || !m_height)
- {
- // Property available on some devices
- displaySize = CJNISystemProperties::get("sys.display-size", "");
- if (!displaySize.empty())
- {
- std::vector<std::string> aSize = StringUtils::Split(displaySize, "x");
- if (aSize.size() == 2)
- {
- m_width = StringUtils::IsInteger(aSize[0]) ? atoi(aSize[0].c_str()) : 0;
- m_height = StringUtils::IsInteger(aSize[1]) ? atoi(aSize[1].c_str()) : 0;
- }
- CLog::Log(LOGDEBUG, "CAndroidUtils: display-size: {}({}x{})", displaySize, m_width, m_height);
- }
- }
-
CLog::Log(LOGDEBUG, "CAndroidUtils: maximum/current resolution: {}x{}", m_width, m_height);
int limit = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
CAndroidUtils::SETTING_LIMITGUI);
@@ -221,24 +164,9 @@ bool CAndroidUtils::GetNativeResolution(RESOLUTION_INFO* res) const
CLog::Log(LOGINFO, "CAndroidUtils: window resolution: {}x{}", m_width, m_height);
}
- if (s_hasModeApi)
- {
- *res = s_res_cur_displayMode;
- res->iWidth = m_width;
- res->iHeight = m_height;
- }
- else
- {
- res->strId = "-1";
- res->fRefreshRate = currentRefreshRate();
- res->dwFlags = D3DPRESENTFLAG_PROGRESSIVE;
- res->bFullScreen = true;
- res->iWidth = m_width;
- res->iHeight = m_height;
- res->fPixelRatio = 1.0f;
- res->iScreenWidth = res->iWidth;
- res->iScreenHeight = res->iHeight;
- }
+ *res = s_res_cur_displayMode;
+ res->iWidth = m_width;
+ res->iHeight = m_height;
res->iSubtitles = res->iHeight;
res->strMode =
StringUtils::Format("{}x{} @ {:.6f}{} - Full Screen", res->iScreenWidth, res->iScreenHeight,
@@ -253,14 +181,8 @@ bool CAndroidUtils::SetNativeResolution(const RESOLUTION_INFO& res)
CLog::Log(LOGINFO, "CAndroidUtils: SetNativeResolution: {}: {}x{} {}x{}@{:f}", res.strId,
res.iWidth, res.iHeight, res.iScreenWidth, res.iScreenHeight, res.fRefreshRate);
- if (s_hasModeApi)
- {
- CXBMCApp::Get().SetDisplayMode(std::atoi(res.strId.c_str()), res.fRefreshRate);
- s_res_cur_displayMode = res;
- }
- else
- CXBMCApp::Get().SetRefreshRate(res.fRefreshRate);
-
+ CXBMCApp::Get().SetDisplayMode(std::atoi(res.strId.c_str()), res.fRefreshRate);
+ s_res_cur_displayMode = res;
CXBMCApp::Get().SetBuffersGeometry(res.iWidth, res.iHeight, 0);
return true;
@@ -269,63 +191,21 @@ bool CAndroidUtils::SetNativeResolution(const RESOLUTION_INFO& res)
bool CAndroidUtils::ProbeResolutions(std::vector<RESOLUTION_INFO>& resolutions)
{
RESOLUTION_INFO cur_res;
- bool ret = GetNativeResolution(&cur_res);
+ GetNativeResolution(&cur_res);
CLog::Log(LOGDEBUG, "CAndroidUtils: ProbeResolutions: {}x{}", m_width, m_height);
- if (s_hasModeApi)
- {
- for (RESOLUTION_INFO res : s_res_displayModes)
- {
- if (m_width && m_height)
- {
- res.iWidth = std::min(res.iWidth, m_width);
- res.iHeight = std::min(res.iHeight, m_height);
- res.iSubtitles = res.iHeight;
- }
- resolutions.push_back(res);
- }
- return true;
- }
-
- if (ret && cur_res.iWidth > 1 && cur_res.iHeight > 1)
+ for (RESOLUTION_INFO res : s_res_displayModes)
{
- std::vector<float> refreshRates;
- CJNIWindow window = CXBMCApp::getWindow();
- if (window)
+ if (m_width && m_height)
{
- CJNIView view = window.getDecorView();
- if (view)
- {
- CJNIDisplay display = view.getDisplay();
- if (display)
- {
- refreshRates = display.getSupportedRefreshRates();
- }
- }
-
- if (!refreshRates.empty())
- {
- for (unsigned int i = 0; i < refreshRates.size(); i++)
- {
- if (refreshRates[i] < 20.0f)
- continue;
- cur_res.fRefreshRate = refreshRates[i];
- cur_res.strMode = StringUtils::Format(
- "{}x{} @ {:.6f}{} - Full Screen", cur_res.iScreenWidth, cur_res.iScreenHeight,
- cur_res.fRefreshRate, cur_res.dwFlags & D3DPRESENTFLAG_INTERLACED ? "i" : "");
- resolutions.push_back(cur_res);
- }
- }
- }
- if (resolutions.empty())
- {
- /* No valid refresh rates available, just provide the current one */
- resolutions.push_back(cur_res);
+ res.iWidth = std::min(res.iWidth, m_width);
+ res.iHeight = std::min(res.iHeight, m_height);
+ res.iSubtitles = res.iHeight;
}
- return true;
+ resolutions.push_back(res);
}
- return false;
+ return true;
}
bool CAndroidUtils::UpdateDisplayModes()
diff --git a/xbmc/windowing/osx/OpenGL/OSXGLView.h b/xbmc/windowing/osx/OpenGL/OSXGLView.h
index 54a85a232f..016e102e78 100644
--- a/xbmc/windowing/osx/OpenGL/OSXGLView.h
+++ b/xbmc/windowing/osx/OpenGL/OSXGLView.h
@@ -16,12 +16,6 @@
- (CGLContextObj)getGLContextObj;
/**
- * @brief Application renders out of the NSOpenGLView drawRect (on a different thread). Hence the current
- * NSOpenGLContext needs to be make current so that the view on the context is valid for rendering.
- * This should be done whenever gl calls are about to be done.
- */
-- (void)NotifyContext;
-/**
* @brief Update the current OpenGL context (view is set before updating)
*/
- (void)Update;
@@ -30,9 +24,4 @@
*/
- (void)FlushBuffer;
-/**
- * @brief Specifies if the glContext is currently owned by the view
- */
-@property(atomic, assign) BOOL glContextOwned;
-
@end
diff --git a/xbmc/windowing/osx/OpenGL/OSXGLView.mm b/xbmc/windowing/osx/OpenGL/OSXGLView.mm
index 195ea0d889..857174838a 100644
--- a/xbmc/windowing/osx/OpenGL/OSXGLView.mm
+++ b/xbmc/windowing/osx/OpenGL/OSXGLView.mm
@@ -20,8 +20,6 @@
NSTrackingArea* m_trackingArea;
}
-@synthesize glContextOwned;
-
- (void)SendInputEvent:(NSEvent*)nsEvent
{
CWinSystemOSX* winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
@@ -88,14 +86,6 @@
- (void)drawRect:(NSRect)rect
{
- // whenever the view/window is resized the glContext is made current to the main (rendering) thread.
- // Since kodi does its rendering on the application main thread (not the macOS rendering thread), we
- // need to store this so that on a subsquent frame render we get the ownership of the gl context again.
- // doing this blindly without any sort of control may stall the main thread and lead to low GUI fps
- // since the glContext ownership needs to be obtained from the rendering thread (diverged from the actual
- // thread doing the rendering calls).
- [self setGlContextOwned:TRUE];
-
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self setOpenGLContext:m_glcontext];
@@ -215,17 +205,8 @@
- (void)Update
{
assert(m_glcontext);
- [self NotifyContext];
- [m_glcontext update];
-}
-
-- (void)NotifyContext
-{
- assert(m_glcontext);
- // signals/notifies the context that this view is current (required if we render out of DrawRect)
- // ownership of the context is transferred to the callee thread
[m_glcontext makeCurrentContext];
- [self setGlContextOwned:FALSE];
+ [m_glcontext update];
}
- (void)FlushBuffer
diff --git a/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm b/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
index 5bfb6b0d22..c3eaa113c2 100644
--- a/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
+++ b/xbmc/windowing/osx/OpenGL/WindowControllerMacOS.mm
@@ -77,6 +77,24 @@
}
}
+- (void)windowWillStartLiveResize:(NSNotification*)notification
+{
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ {
+ appPort->SetRenderGUI(false);
+ }
+}
+
+- (void)windowDidEndLiveResize:(NSNotification*)notification
+{
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
+ {
+ appPort->SetRenderGUI(true);
+ }
+}
+
- (void)windowDidMiniaturize:(NSNotification*)aNotification
{
g_application.m_AppFocused = false;
diff --git a/xbmc/windowing/osx/WinSystemOSX.h b/xbmc/windowing/osx/WinSystemOSX.h
index c431d70cd9..899e52486b 100644
--- a/xbmc/windowing/osx/WinSystemOSX.h
+++ b/xbmc/windowing/osx/WinSystemOSX.h
@@ -71,7 +71,6 @@ public:
void MoveToScreen(unsigned int screenIdx) override;
void OnMove(int x, int y) override;
void OnChangeScreen(unsigned int screenIdx) override;
- CGraphicContext& GetGfxContext() const override;
bool HasValidResolution() const;
std::string GetClipboardText() override;
diff --git a/xbmc/windowing/osx/WinSystemOSX.mm b/xbmc/windowing/osx/WinSystemOSX.mm
index 04a0670a17..007fc14be3 100644
--- a/xbmc/windowing/osx/WinSystemOSX.mm
+++ b/xbmc/windowing/osx/WinSystemOSX.mm
@@ -1304,18 +1304,6 @@ CGLContextObj CWinSystemOSX::GetCGLContextObj()
return cglcontex;
}
-CGraphicContext& CWinSystemOSX::GetGfxContext() const
-{
- if (m_glView && [m_glView glContextOwned])
- {
- dispatch_sync(dispatch_get_main_queue(), ^{
- [m_glView NotifyContext];
- });
- }
-
- return CWinSystemBase::GetGfxContext();
-}
-
bool CWinSystemOSX::FlushBuffer()
{
if (m_appWindow)
diff --git a/xbmc/windowing/wayland/CMakeLists.txt b/xbmc/windowing/wayland/CMakeLists.txt
index d29b97c685..c406de112f 100644
--- a/xbmc/windowing/wayland/CMakeLists.txt
+++ b/xbmc/windowing/wayland/CMakeLists.txt
@@ -68,10 +68,12 @@ if(TARGET_WEBOS)
PROPERTIES GENERATED TRUE)
list(APPEND SOURCES OSScreenSaverWebOS.cpp
+ SeatWebOS.cpp
ShellSurfaceWebOSShell.cpp
WinSystemWaylandWebOS.cpp
${WAYLAND_EXTRA_PROTOCOL_GENERATED_DIR}/wayland-webos-protocols.cpp)
list(APPEND HEADERS OSScreenSaverWebOS.h
+ SeatWebOS.h
ShellSurfaceWebOSShell.h
WinSystemWaylandWebOS.h
${WAYLAND_EXTRA_PROTOCOL_GENERATED_DIR}/wayland-webos-protocols.hpp)
diff --git a/xbmc/windowing/wayland/Seat.cpp b/xbmc/windowing/wayland/Seat.cpp
index de22f1e218..770c274ed6 100644
--- a/xbmc/windowing/wayland/Seat.cpp
+++ b/xbmc/windowing/wayland/Seat.cpp
@@ -136,10 +136,7 @@ void CSeat::SetCursor(std::uint32_t serial, wayland::surface_t const &surface, s
{
if (m_pointer)
{
- // set_cursor on webOS completely breaks pointer input
-#ifndef TARGET_WEBOS
m_pointer.set_cursor(serial, surface, hotspotX, hotspotY);
-#endif
}
}
@@ -182,6 +179,11 @@ void CSeat::HandleKeyboardCapability()
handler->OnKeyboardModifiers(this, serial, modsDepressed, modsLatched, modsLocked, group);
}
};
+ InstallKeyboardRepeatInfo();
+}
+
+void CSeat::InstallKeyboardRepeatInfo()
+{
m_keyboard.on_repeat_info() = [this](std::int32_t rate, std::int32_t delay)
{
for (auto handler : m_rawKeyboardHandlers)
@@ -191,7 +193,6 @@ void CSeat::HandleKeyboardCapability()
};
}
-
void CSeat::HandlePointerCapability()
{
m_pointer.on_enter() = [this](std::uint32_t serial, const wayland::surface_t& surface,
diff --git a/xbmc/windowing/wayland/Seat.h b/xbmc/windowing/wayland/Seat.h
index 095f18dd89..edaf8e4df4 100644
--- a/xbmc/windowing/wayland/Seat.h
+++ b/xbmc/windowing/wayland/Seat.h
@@ -121,7 +121,7 @@ public:
* \param connection connection for retrieving additional globals
*/
CSeat(std::uint32_t globalName, wayland::seat_t const& seat, CConnection& connection);
- ~CSeat() noexcept;
+ virtual ~CSeat() noexcept;
void AddRawInputHandlerKeyboard(IRawInputHandlerKeyboard* rawKeyboardHandler);
void RemoveRawInputHandlerKeyboard(IRawInputHandlerKeyboard* rawKeyboardHandler);
@@ -172,7 +172,13 @@ public:
* Parameters are identical wo wl_pointer.set_cursor().
* If the seat does not currently have the pointer capability, this is a no-op.
*/
- void SetCursor(std::uint32_t serial, wayland::surface_t const& surface, std::int32_t hotspotX, std::int32_t hotspotY);
+ virtual void SetCursor(std::uint32_t serial,
+ wayland::surface_t const& surface,
+ std::int32_t hotspotX,
+ std::int32_t hotspotY);
+
+protected:
+ virtual void InstallKeyboardRepeatInfo();
private:
CSeat(CSeat const& other) = delete;
diff --git a/xbmc/windowing/wayland/SeatWebOS.cpp b/xbmc/windowing/wayland/SeatWebOS.cpp
new file mode 100644
index 0000000000..29eb0117ad
--- /dev/null
+++ b/xbmc/windowing/wayland/SeatWebOS.cpp
@@ -0,0 +1,29 @@
+/*
+* Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "SeatWebOS.h"
+
+namespace KODI::WINDOWING::WAYLAND
+{
+
+void CSeatWebOS::SetCursor(std::uint32_t serial,
+ wayland::surface_t const& surface,
+ std::int32_t hotspotX,
+ std::int32_t hotspotY)
+{
+ // set_cursor on webOS completely breaks pointer input
+}
+
+void CSeatWebOS::InstallKeyboardRepeatInfo()
+{
+ // Since webOS 7 the compositor sends the following key repeat info:
+ // Key repeat rate: 40 cps, delay 400 ms
+ // Which is too fast for the long press detection
+}
+
+} // namespace KODI::WINDOWING::WAYLAND
diff --git a/xbmc/windowing/wayland/SeatWebOS.h b/xbmc/windowing/wayland/SeatWebOS.h
new file mode 100644
index 0000000000..45bf155f6c
--- /dev/null
+++ b/xbmc/windowing/wayland/SeatWebOS.h
@@ -0,0 +1,33 @@
+/*
+* Copyright (C) 2024 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "Seat.h"
+
+namespace KODI::WINDOWING::WAYLAND
+{
+
+class CSeatWebOS final : public CSeat
+{
+public:
+ CSeatWebOS(std::uint32_t globalName, wayland::seat_t const& seat, CConnection& connection)
+ : CSeat(globalName, seat, connection)
+ {
+ }
+
+ void SetCursor(std::uint32_t serial,
+ wayland::surface_t const& surface,
+ std::int32_t hotspotX,
+ std::int32_t hotspotY) override;
+
+protected:
+ void InstallKeyboardRepeatInfo() override;
+};
+
+} // namespace KODI::WINDOWING::WAYLAND
diff --git a/xbmc/windowing/wayland/ShellSurfaceWebOSShell.cpp b/xbmc/windowing/wayland/ShellSurfaceWebOSShell.cpp
index 2bc6606587..048797fbfc 100644
--- a/xbmc/windowing/wayland/ShellSurfaceWebOSShell.cpp
+++ b/xbmc/windowing/wayland/ShellSurfaceWebOSShell.cpp
@@ -18,6 +18,11 @@ using namespace std::placeholders;
using namespace wayland;
+namespace
+{
+constexpr auto WEBOS_ACCESS_POLICY_KEYS_GUIDE = "_WEBOS_ACCESS_POLICY_KEYS_GUIDE";
+} // namespace
+
CShellSurfaceWebOSShell::CShellSurfaceWebOSShell(IShellSurfaceHandler& handler,
CConnection& connection,
const wayland::surface_t& surface,
@@ -35,6 +40,7 @@ CShellSurfaceWebOSShell::CShellSurfaceWebOSShell(IShellSurfaceHandler& handler,
m_shellSurface = m_shell.get_shell_surface(surface);
m_webos_shellSurface = m_webos_shell.get_shell_surface(surface);
+ m_webos_shellSurface.set_property(WEBOS_ACCESS_POLICY_KEYS_GUIDE, "true");
m_webos_shellSurface.on_exposed() = [this](const std::vector<std::int32_t>& rect) {
if (rect.size() >= 4)
diff --git a/xbmc/windowing/wayland/WinSystemWayland.cpp b/xbmc/windowing/wayland/WinSystemWayland.cpp
index e226563a35..01d7c8b7ea 100644
--- a/xbmc/windowing/wayland/WinSystemWayland.cpp
+++ b/xbmc/windowing/wayland/WinSystemWayland.cpp
@@ -1088,9 +1088,7 @@ bool CWinSystemWayland::HasCursor()
std::unique_lock<CCriticalSection> lock(m_seatsMutex);
return std::any_of(m_seats.cbegin(), m_seats.cend(),
[](decltype(m_seats)::value_type const& entry)
- {
- return entry.second.HasPointerCapability();
- });
+ { return entry.second->HasPointerCapability(); });
}
void CWinSystemWayland::ShowOSMouse(bool show)
@@ -1144,13 +1142,17 @@ void CWinSystemWayland::OnSeatAdded(std::uint32_t name, wayland::proxy_t&& proxy
std::unique_lock<CCriticalSection> lock(m_seatsMutex);
wayland::seat_t seat(proxy);
- auto newSeatEmplace = m_seats.emplace(std::piecewise_construct,
- std::forward_as_tuple(name),
- std::forward_as_tuple(name, seat, *m_connection));
+ auto newSeatEmplace = m_seats.emplace(std::piecewise_construct, std::forward_as_tuple(name),
+ std::forward_as_tuple(CreateSeat(name, seat)));
auto& seatInst = newSeatEmplace.first->second;
- m_seatInputProcessing->AddSeat(&seatInst);
- m_windowDecorator->AddSeat(&seatInst);
+ m_seatInputProcessing->AddSeat(seatInst.get());
+ m_windowDecorator->AddSeat(seatInst.get());
+}
+
+std::unique_ptr<CSeat> CWinSystemWayland::CreateSeat(std::uint32_t name, wayland::seat_t& seat)
+{
+ return std::make_unique<CSeat>(name, seat, *m_connection);
}
void CWinSystemWayland::OnSeatRemoved(std::uint32_t name)
@@ -1160,8 +1162,8 @@ void CWinSystemWayland::OnSeatRemoved(std::uint32_t name)
auto seatI = m_seats.find(name);
if (seatI != m_seats.end())
{
- m_seatInputProcessing->RemoveSeat(&seatI->second);
- m_windowDecorator->RemoveSeat(&seatI->second);
+ m_seatInputProcessing->RemoveSeat(seatI->second.get());
+ m_windowDecorator->RemoveSeat(seatI->second.get());
m_seats.erase(name);
}
}
@@ -1262,12 +1264,13 @@ void CWinSystemWayland::OnSetCursor(std::uint32_t seatGlobalName, std::uint32_t
LoadDefaultCursor();
if (m_cursorSurface) // Cursor loading could have failed
{
- seatI->second.SetCursor(serial, m_cursorSurface, m_cursorImage.hotspot_x(), m_cursorImage.hotspot_y());
+ seatI->second->SetCursor(serial, m_cursorSurface, m_cursorImage.hotspot_x(),
+ m_cursorImage.hotspot_y());
}
}
else
{
- seatI->second.SetCursor(serial, wayland::surface_t{}, 0, 0);
+ seatI->second->SetCursor(serial, wayland::surface_t{}, 0, 0);
}
}
@@ -1517,7 +1520,7 @@ std::string CWinSystemWayland::GetClipboardText()
// probably just not that relevant in practice
for (auto const& seat : m_seats)
{
- auto text = seat.second.GetSelectionText();
+ auto text = seat.second->GetSelectionText();
if (text != "")
{
return text;
diff --git a/xbmc/windowing/wayland/WinSystemWayland.h b/xbmc/windowing/wayland/WinSystemWayland.h
index 95f2a9cfea..62e96d2183 100644
--- a/xbmc/windowing/wayland/WinSystemWayland.h
+++ b/xbmc/windowing/wayland/WinSystemWayland.h
@@ -122,6 +122,8 @@ protected:
void OnConfigure(std::uint32_t serial, CSizeInt size, IShellSurface::StateBitset state) override;
void OnClose() override;
+ virtual std::unique_ptr<CSeat> CreateSeat(std::uint32_t name, wayland::seat_t& seat);
+
private:
// IInputHandler
void OnEnter(InputType type) override;
@@ -208,7 +210,7 @@ private:
// Seat handling
// -------------
- std::map<std::uint32_t, CSeat> m_seats;
+ std::map<std::uint32_t, std::unique_ptr<CSeat>> m_seats;
CCriticalSection m_seatsMutex;
std::unique_ptr<CSeatInputProcessing> m_seatInputProcessing;
std::map<std::uint32_t, std::shared_ptr<COutput>> m_outputs;
diff --git a/xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp b/xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp
index bfbb2fa286..f4137ee24b 100644
--- a/xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp
+++ b/xbmc/windowing/wayland/WinSystemWaylandWebOS.cpp
@@ -11,6 +11,7 @@
#include "Connection.h"
#include "OSScreenSaverWebOS.h"
#include "Registry.h"
+#include "SeatWebOS.h"
#include "ShellSurfaceWebOSShell.h"
#include "application/ApplicationComponents.h"
#include "application/ApplicationPlayer.h"
@@ -148,6 +149,11 @@ std::unique_ptr<KODI::WINDOWING::IOSScreenSaver> CWinSystemWaylandWebOS::GetOSSc
return std::make_unique<COSScreenSaverWebOS>();
}
+std::unique_ptr<CSeat> CWinSystemWaylandWebOS::CreateSeat(std::uint32_t name, wayland::seat_t& seat)
+{
+ return std::make_unique<CSeatWebOS>(name, seat, *GetConnection());
+}
+
bool CWinSystemWaylandWebOS::OnAppLifecycleEventWrapper(LSHandle* sh, LSMessage* reply, void* ctx)
{
HContext* context = static_cast<HContext*>(ctx);
@@ -164,23 +170,14 @@ void CWinSystemWaylandWebOS::OnConfigure(std::uint32_t serial,
// intercept minimized event, passing the minimized event causes a weird animation
if (state.none())
{
- m_resumePlayback = false;
-
- if (player->IsPlaying() && player->HasVideo() && !player->IsPaused())
+ if (player)
{
CServiceBroker::GetAppMessenger()->SendMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1,
- static_cast<void*>(new CAction(ACTION_PAUSE)));
- m_resumePlayback = true;
+ static_cast<void*>(new CAction(ACTION_STOP)));
}
}
else
{
- if (m_resumePlayback && player->IsPlaying() && player->HasVideo() && player->IsPaused())
- {
- CServiceBroker::GetAppMessenger()->SendMsg(
- TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_PLAYER_PLAY)));
- m_resumePlayback = false;
- }
CWinSystemWayland::OnConfigure(serial, size, state);
}
}
diff --git a/xbmc/windowing/wayland/WinSystemWaylandWebOS.h b/xbmc/windowing/wayland/WinSystemWaylandWebOS.h
index 3f3c9821b4..349922481d 100644
--- a/xbmc/windowing/wayland/WinSystemWaylandWebOS.h
+++ b/xbmc/windowing/wayland/WinSystemWaylandWebOS.h
@@ -50,6 +50,7 @@ public:
protected:
std::unique_ptr<KODI::WINDOWING::IOSScreenSaver> GetOSScreenSaverImpl() override;
+ std::unique_ptr<CSeat> CreateSeat(std::uint32_t name, wayland::seat_t& seat) override;
private:
static bool OnAppLifecycleEventWrapper(LSHandle* sh, LSMessage* reply, void* ctx);
@@ -65,8 +66,6 @@ private:
std::unique_ptr<HContext, int (*)(HContext*)> m_requestContext{new HContext(),
HUnregisterServiceCallback};
-
- bool m_resumePlayback{false};
};
} // namespace KODI::WINDOWING::WAYLAND
diff --git a/xbmc/windowing/wayland/XkbcommonKeymap.cpp b/xbmc/windowing/wayland/XkbcommonKeymap.cpp
index 9ccb0139df..9bc3da8451 100644
--- a/xbmc/windowing/wayland/XkbcommonKeymap.cpp
+++ b/xbmc/windowing/wayland/XkbcommonKeymap.cpp
@@ -210,6 +210,7 @@ static const std::map<xkb_keycode_t, XBMCKey> XkbKeycodeXBMCMappings = {
{XKB_KEY_WEBOS_CHANNEL_DOWN, XBMCK_PAGEDOWN},
{XKB_KEY_WEBOS_CHANNEL_UP, XBMCK_PAGEUP},
{XKB_KEY_WEBOS_INFO, XBMCK_INFO},
+ {XKB_KEY_WEBOS_TVGUIDE, XBMCK_GUIDE},
{XKB_KEY_WEBOS_CURSOR_HIDE, XBMCK_UNKNOWN},
{XKB_KEY_WEBOS_CURSOR_SHOW, XBMCK_UNKNOWN},
{XKB_KEY_WEBOS_INVALID, XBMCK_UNKNOWN},
diff --git a/xbmc/windowing/win10/WinSystemWin10.cpp b/xbmc/windowing/win10/WinSystemWin10.cpp
index ccdbc395f3..1461d797b0 100644
--- a/xbmc/windowing/win10/WinSystemWin10.cpp
+++ b/xbmc/windowing/win10/WinSystemWin10.cpp
@@ -692,7 +692,14 @@ float CWinSystemWin10::GetGuiSdrPeakLuminance() const
*/
bool CWinSystemWin10::HasSystemSdrPeakLuminance()
{
- return CWIN32Util::GetSystemSdrWhiteLevel(std::wstring(), nullptr);
+ if (m_uiThreadId == GetCurrentThreadId())
+ {
+ const bool hasSystemSdrPeakLum = CWIN32Util::GetSystemSdrWhiteLevel(std::wstring(), nullptr);
+ m_cachedHasSystemSdrPeakLum = hasSystemSdrPeakLum;
+ return hasSystemSdrPeakLum;
+ }
+
+ return m_cachedHasSystemSdrPeakLum;
}
/*!
diff --git a/xbmc/windowing/win10/WinSystemWin10.h b/xbmc/windowing/win10/WinSystemWin10.h
index c53fd01872..6b5be4bb4e 100644
--- a/xbmc/windowing/win10/WinSystemWin10.h
+++ b/xbmc/windowing/win10/WinSystemWin10.h
@@ -156,6 +156,10 @@ protected:
bool m_validSystemSdrPeakLuminance{false};
float m_systemSdrPeakLuminance{.0f};
+
+ DWORD m_uiThreadId{0};
+ HDR_STATUS m_cachedHdrStatus{HDR_STATUS::HDR_UNSUPPORTED};
+ bool m_cachedHasSystemSdrPeakLum{false};
};
#pragma pack(pop)
diff --git a/xbmc/windowing/win10/WinSystemWin10DX.cpp b/xbmc/windowing/win10/WinSystemWin10DX.cpp
index 1101b1a7ef..55167ff386 100644
--- a/xbmc/windowing/win10/WinSystemWin10DX.cpp
+++ b/xbmc/windowing/win10/WinSystemWin10DX.cpp
@@ -61,6 +61,14 @@ bool CWinSystemWin10DX::CreateNewWindow(const std::string& name, bool fullScreen
m_deviceResources = DX::DeviceResources::Get();
m_deviceResources->SetWindow(m_coreWindow);
+ // saves threadId of current thread (UI thread)
+ m_uiThreadId = GetCurrentThreadId();
+
+ // calls these methods to make sure cached values are properly initialized
+ // and can be used later when called from other thread
+ IsHDRDisplay();
+ HasSystemSdrPeakLuminance();
+
if (CWinSystemWin10::CreateNewWindow(name, fullScreen, res) && m_deviceResources->HasValidDevice())
{
CGenericTouchInputHandler::GetInstance().RegisterHandler(&CGenericTouchActionHandler::GetInstance());
@@ -166,7 +174,14 @@ void CWinSystemWin10DX::InitHooks(IDXGIOutput* pOutput)
bool CWinSystemWin10DX::IsHDRDisplay()
{
- return (CWIN32Util::GetWindowsHDRStatus() != HDR_STATUS::HDR_UNSUPPORTED);
+ if (m_uiThreadId == GetCurrentThreadId())
+ {
+ const HDR_STATUS hdrStatus = CWIN32Util::GetWindowsHDRStatus();
+ m_cachedHdrStatus = hdrStatus;
+ return (hdrStatus != HDR_STATUS::HDR_UNSUPPORTED);
+ }
+
+ return (m_cachedHdrStatus != HDR_STATUS::HDR_UNSUPPORTED);
}
HDR_STATUS CWinSystemWin10DX::GetOSHDRStatus()
diff --git a/xbmc/windows/GUIMediaWindow.cpp b/xbmc/windows/GUIMediaWindow.cpp
index 5dacf417a1..f764b671c5 100644
--- a/xbmc/windows/GUIMediaWindow.cpp
+++ b/xbmc/windows/GUIMediaWindow.cpp
@@ -10,6 +10,7 @@
#include "ContextMenuManager.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "FileItemListModification.h"
#include "GUIPassword.h"
#include "GUIUserMessages.h"
@@ -23,6 +24,7 @@
#include "addons/addoninfo/AddonType.h"
#include "application/Application.h"
#include "messaging/ApplicationMessenger.h"
+#include "network/NetworkFileItemClassify.h"
#if defined(TARGET_ANDROID)
#include "platform/android/activity/XBMCApp.h"
#endif
@@ -61,8 +63,6 @@
#include "utils/log.h"
#include "view/GUIViewState.h"
-#include <inttypes.h>
-
#define CONTROL_BTNVIEWASICONS 2
#define CONTROL_BTNSORTBY 3
#define CONTROL_BTNSORTASC 4
@@ -77,6 +77,7 @@
#define PLUGIN_REFRESH_DELAY 200
using namespace ADDON;
+using namespace KODI;
using namespace KODI::MESSAGING;
using namespace std::chrono_literals;
@@ -1500,7 +1501,7 @@ bool CGUIMediaWindow::OnPlayMedia(int iItem, const std::string &player)
CLog::Log(LOGDEBUG, "{} {}", __FUNCTION__, CURL::GetRedacted(pItem->GetPath()));
bool bResult = false;
- if (pItem->IsInternetStream() || pItem->IsPlayList())
+ if (NETWORK::IsInternetStream(*pItem) || pItem->IsPlayList())
bResult = g_application.PlayMedia(*pItem, player, m_guiState->GetPlaylist());
else
bResult = g_application.PlayFile(*pItem, player);
@@ -1525,39 +1526,24 @@ bool CGUIMediaWindow::OnPlayAndQueueMedia(const CFileItemPtr& item, const std::s
PLAYLIST::Id playlistId = m_guiState->GetPlaylist();
if (playlistId != PLAYLIST::TYPE_NONE)
{
+ // Remove ZIP, RAR files and folders
+ CFileItemList playlist;
+ playlist.Copy(*m_vecItems, true);
+ playlist.erase(std::remove_if(playlist.begin(), playlist.end(),
+ [](const std::shared_ptr<CFileItem>& i)
+ { return i->IsZIP() || i->IsRAR() || i->m_bIsFolder; }),
+ playlist.end());
+
+ // Chosen item
+ int mediaToPlay =
+ std::distance(playlist.begin(), std::find_if(playlist.begin(), playlist.end(),
+ [&item](const std::shared_ptr<CFileItem>& i)
+ { return i->GetPath() == item->GetPath(); }));
+
+ // Add to playlist
CServiceBroker::GetPlaylistPlayer().ClearPlaylist(playlistId);
CServiceBroker::GetPlaylistPlayer().Reset();
- int mediaToPlay = 0;
-
- // first try to find mainDVD file (VIDEO_TS.IFO).
- // If we find this we should not allow to queue VOB files
- std::string mainDVD;
- for (int i = 0; i < m_vecItems->Size(); i++)
- {
- std::string path = URIUtils::GetFileName(m_vecItems->Get(i)->GetDynPath());
- if (StringUtils::EqualsNoCase(path, "VIDEO_TS.IFO"))
- {
- mainDVD = path;
- break;
- }
- }
-
- // now queue...
- for ( int i = 0; i < m_vecItems->Size(); i++ )
- {
- CFileItemPtr nItem = m_vecItems->Get(i);
-
- if (nItem->m_bIsFolder)
- continue;
-
- if (!nItem->IsZIP() && !nItem->IsRAR() && (!nItem->IsDVDFile() || (URIUtils::GetFileName(nItem->GetDynPath()) == mainDVD)))
- CServiceBroker::GetPlaylistPlayer().Add(playlistId, nItem);
-
- if (item->IsSamePath(nItem.get()))
- { // item that was clicked
- mediaToPlay = CServiceBroker::GetPlaylistPlayer().GetPlaylist(playlistId).size() - 1;
- }
- }
+ CServiceBroker::GetPlaylistPlayer().Add(playlistId, playlist);
// Save current window and directory to know where the selected item was
if (m_guiState)
diff --git a/xbmc/windows/GUIWindowDebugInfo.cpp b/xbmc/windows/GUIWindowDebugInfo.cpp
index 764e6b0b71..866d506fe3 100644
--- a/xbmc/windows/GUIWindowDebugInfo.cpp
+++ b/xbmc/windows/GUIWindowDebugInfo.cpp
@@ -179,7 +179,13 @@ void CGUIWindowDebugInfo::Process(unsigned int currentTime, CDirtyRegionList &di
void CGUIWindowDebugInfo::Render()
{
+ RENDER_ORDER renderOrder = CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder();
+ if (renderOrder == RENDER_ORDER_FRONT_TO_BACK)
+ return;
+ else if (renderOrder == RENDER_ORDER_BACK_TO_FRONT)
+ CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderOrder(RENDER_ORDER_ALL_BACK_TO_FRONT);
CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderingResolution(CServiceBroker::GetWinSystem()->GetGfxContext().GetResInfo(), false);
if (m_layout)
m_layout->RenderOutline(m_renderRegion.x1, m_renderRegion.y1, 0xffffffff, 0xff000000, 0, 0);
+ CServiceBroker::GetWinSystem()->GetGfxContext().SetRenderOrder(renderOrder);
}
diff --git a/xbmc/windows/GUIWindowFileManager.cpp b/xbmc/windows/GUIWindowFileManager.cpp
index 2093101d08..fd001e0f99 100644
--- a/xbmc/windows/GUIWindowFileManager.cpp
+++ b/xbmc/windows/GUIWindowFileManager.cpp
@@ -39,6 +39,7 @@
#include "interfaces/generic/ScriptInvocationManager.h"
#include "messaging/ApplicationMessenger.h"
#include "messaging/helpers/DialogOKHelper.h"
+#include "music/MusicFileItemClassify.h"
#include "network/Network.h"
#include "pictures/SlideShowDelegator.h"
#include "platform/Filesystem.h"
@@ -56,9 +57,12 @@
#include "utils/URIUtils.h"
#include "utils/Variant.h"
#include "utils/log.h"
+#include "video/VideoFileItemClassify.h"
using namespace XFILE;
+using namespace KODI;
using namespace KODI::MESSAGING;
+using namespace KODI::VIDEO;
#define CONTROL_BTNSELECTALL 1
#define CONTROL_BTNFAVOURITES 2
@@ -655,7 +659,7 @@ void CGUIWindowFileManager::OnStart(CFileItem *pItem, const std::string &player)
g_application.ProcessAndStartPlaylist(strPlayList, *pPlayList, PLAYLIST::TYPE_MUSIC);
return;
}
- if (pItem->IsAudio() || pItem->IsVideo())
+ if (MUSIC::IsAudio(*pItem) || IsVideo(*pItem))
{
CServiceBroker::GetPlaylistPlayer().Play(std::make_shared<CFileItem>(*pItem), player);
return;
diff --git a/xbmc/windows/GUIWindowLoginScreen.cpp b/xbmc/windows/GUIWindowLoginScreen.cpp
index 04eb5f9041..c95f6e4b61 100644
--- a/xbmc/windows/GUIWindowLoginScreen.cpp
+++ b/xbmc/windows/GUIWindowLoginScreen.cpp
@@ -9,6 +9,7 @@
#include "GUIWindowLoginScreen.h"
#include "FileItem.h"
+#include "FileItemList.h"
#include "GUIPassword.h"
#include "ServiceBroker.h"
#include "addons/Skin.h"