From 3dd812052e0e472e9e60bf0631ab4ee155697160 Mon Sep 17 00:00:00 2001 From: Tom Poole Date: Fri, 17 Sep 2021 11:51:34 +0100 Subject: [PATCH] macOS/iOS: Add a Metal layer renderer This restores the functionality of JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS. Using this preprocessor flag may avoid Core Graphics rendering much larger regions than necessary, but the small regions that are rendered will likely be rendered slower. Whether using this flag improves or degrades the performance of your rendering overall will be specific to each application. Previously enabling JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS was ineffective from versions of macOS around 10.13, but enabling it didn't have any negative impact on performance. Now enabling JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS may result in slower rendering. --- BREAKING-CHANGES.txt | 29 ++ README.md | 2 +- .../Builds/Android/app/CMakeLists.txt | 2 + .../DemoRunner.xcodeproj/project.pbxproj | 2 + .../VisualStudio2015/DemoRunner_App.vcxproj | 1 + .../DemoRunner_App.vcxproj.filters | 3 + .../VisualStudio2017/DemoRunner_App.vcxproj | 1 + .../DemoRunner_App.vcxproj.filters | 3 + .../VisualStudio2019/DemoRunner_App.vcxproj | 1 + .../DemoRunner_App.vcxproj.filters | 3 + .../VisualStudio2022/DemoRunner_App.vcxproj | 1 + .../DemoRunner_App.vcxproj.filters | 3 + .../iOS/DemoRunner.xcodeproj/project.pbxproj | 2 + .../Builds/Android/app/CMakeLists.txt | 2 + .../project.pbxproj | 2 + .../AudioPerformanceTest_App.vcxproj | 1 + .../AudioPerformanceTest_App.vcxproj.filters | 3 + .../project.pbxproj | 2 + .../Builds/Android/app/CMakeLists.txt | 2 + .../AudioPluginHost.xcodeproj/project.pbxproj | 2 + .../AudioPluginHost_App.vcxproj | 1 + .../AudioPluginHost_App.vcxproj.filters | 3 + .../AudioPluginHost_App.vcxproj | 1 + .../AudioPluginHost_App.vcxproj.filters | 3 + .../AudioPluginHost_App.vcxproj | 1 + .../AudioPluginHost_App.vcxproj.filters | 3 + .../AudioPluginHost_App.vcxproj | 1 + .../AudioPluginHost_App.vcxproj.filters | 3 + .../AudioPluginHost.xcodeproj/project.pbxproj | 2 + .../Builds/Android/app/CMakeLists.txt | 2 + .../project.pbxproj | 2 + .../NetworkGraphicsDemo_App.vcxproj | 1 + .../NetworkGraphicsDemo_App.vcxproj.filters | 3 + .../project.pbxproj | 2 + .../MacOSX/Projucer.xcodeproj/project.pbxproj | 2 + .../VisualStudio2015/Projucer_App.vcxproj | 1 + .../Projucer_App.vcxproj.filters | 3 + .../VisualStudio2017/Projucer_App.vcxproj | 1 + .../Projucer_App.vcxproj.filters | 3 + .../VisualStudio2019/Projucer_App.vcxproj | 1 + .../Projucer_App.vcxproj.filters | 3 + .../VisualStudio2022/Projucer_App.vcxproj | 1 + .../Projucer_App.vcxproj.filters | 3 + .../UnitTestRunner.xcodeproj/project.pbxproj | 2 + .../UnitTestRunner_ConsoleApp.vcxproj | 1 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 + .../UnitTestRunner_ConsoleApp.vcxproj | 1 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 + .../UnitTestRunner_ConsoleApp.vcxproj | 1 + .../UnitTestRunner_ConsoleApp.vcxproj.filters | 3 + .../WindowsDLL_StaticLibrary.vcxproj | 1 + .../WindowsDLL_StaticLibrary.vcxproj.filters | 3 + .../juce_core/native/juce_mac_ObjCHelpers.h | 3 + .../juce_core/system/juce_TargetPlatform.h | 4 +- modules/juce_gui_basics/juce_gui_basics.cpp | 2 + modules/juce_gui_basics/juce_gui_basics.h | 6 +- .../native/juce_ios_UIViewComponentPeer.mm | 71 +++- .../native/juce_mac_CGMetalLayerRenderer.h | 338 ++++++++++++++++++ .../native/juce_mac_NSViewComponentPeer.mm | 96 ++++- 59 files changed, 622 insertions(+), 29 deletions(-) create mode 100644 modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h diff --git a/BREAKING-CHANGES.txt b/BREAKING-CHANGES.txt index c1902281f0..d1a426ed71 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING-CHANGES.txt @@ -4,6 +4,35 @@ JUCE breaking changes develop ======= +Change +------ +The optional JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS preprocessor +flag will now use a new Metal layer renderer when running on macOS 10.14 or +later. The minimum requirements for building macOS and iOS software are now +macOS 10.13.6 and Xcode 10.1. + +Possible Issues +--------------- +Previously enabling JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS had no +negative effect on performance. Now it may slow rendering down. + +Workaround +---------- +Disable JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS. + +Rationale +--------- +JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS has been ineffective when +running on macOS 10.13 or later. Enabling this flag, and hence using the new +Metal layer renderer when running on macOS 10.14, restores the previous +behaviour and fixes problems where Core Graphics will render much larger +regions than necessary. However, the new renderer will may be slower than the +recently introduced default of asynchronous Core Graphics rendering, depending +on the regions that Core Graphcis is redrawing. Whether +JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS improves or degrades +performance is specific to an application. + + Change ------ The optional JUCE_COREGRAPHICS_DRAW_ASYNC preprocessor flag has been removed diff --git a/README.md b/README.md index 0f0eaa8373..2bf83b76d7 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ of the target you wish to build. #### Building JUCE Projects -- __macOS/iOS__: Xcode 9.2 (macOS 10.12.6) +- __macOS/iOS__: Xcode 10.1 (macOS 10.13.6) - __Windows__: Windows 8.1 and Visual Studio 2015 Update 3 64-bit - __Linux__: g++ 5.0 or Clang 3.4 (for a full list of dependencies, see [here](/docs/Linux%20Dependencies.md)). diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index f85956f303..783e5a7d06 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -1598,6 +1598,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" "../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" + "../../../../../modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h" "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" @@ -3417,6 +3418,7 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj index 49a4fe2cea..5c11719299 100644 --- a/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/MacOSX/DemoRunner.xcodeproj/project.pbxproj @@ -563,6 +563,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.rmsl.jucedemorunner; PRODUCT_NAME = "DemoRunner"; USE_HEADERMAP = NO; @@ -644,6 +645,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.rmsl.jucedemorunner; PRODUCT_NAME = "DemoRunner"; USE_HEADERMAP = NO; diff --git a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj index 31f527656b..f8d1e5f5da 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj @@ -3322,6 +3322,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters index 28ea61fd3e..01719a20d2 100644 --- a/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2015/DemoRunner_App.vcxproj.filters @@ -5601,6 +5601,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj index f977722847..08341d4149 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj @@ -3322,6 +3322,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters index f3907e60c5..f294d18152 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters @@ -5601,6 +5601,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index d4ee8410a5..ad1fe5559b 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -3322,6 +3322,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 847b5bb6dd..b1474a9667 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -5601,6 +5601,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj index 3e9d6f6e0b..5417e09211 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -3322,6 +3322,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index c03cb7c744..276dd80790 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -5601,6 +5601,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj index 7c66b55946..c04e8f6fed 100644 --- a/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj +++ b/examples/DemoRunner/Builds/iOS/DemoRunner.xcodeproj/project.pbxproj @@ -566,6 +566,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.rmsl.jucedemorunner; PRODUCT_NAME = "DemoRunner"; USE_HEADERMAP = NO; @@ -647,6 +648,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.rmsl.jucedemorunner; PRODUCT_NAME = "DemoRunner"; USE_HEADERMAP = NO; diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 9eb85f99e3..c42821d270 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -1383,6 +1383,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" "../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" + "../../../../../modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h" "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" @@ -2900,6 +2901,7 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj index dd7d19f3ad..71ba34262a 100644 --- a/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj +++ b/extras/AudioPerformanceTest/Builds/MacOSX/AudioPerformanceTest.xcodeproj/project.pbxproj @@ -362,6 +362,7 @@ INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.AudioPerformanceTest; PRODUCT_NAME = "AudioPerformanceTest"; USE_HEADERMAP = NO; @@ -425,6 +426,7 @@ LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.AudioPerformanceTest; PRODUCT_NAME = "AudioPerformanceTest"; USE_HEADERMAP = NO; diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index 18254d60d9..bff451bd68 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -2821,6 +2821,7 @@ + diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index 7e4197a5d6..1427384857 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -4716,6 +4716,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj index 30323f434a..245d81c0eb 100644 --- a/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj +++ b/extras/AudioPerformanceTest/Builds/iOS/AudioPerformanceTest.xcodeproj/project.pbxproj @@ -374,6 +374,7 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.AudioPerformanceTest; PRODUCT_NAME = "AudioPerformanceTest"; USE_HEADERMAP = NO; @@ -436,6 +437,7 @@ INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.AudioPerformanceTest; PRODUCT_NAME = "AudioPerformanceTest"; USE_HEADERMAP = NO; diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 1bf2397d9f..fe6cac9bc4 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -1505,6 +1505,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" "../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" + "../../../../../modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h" "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" @@ -3176,6 +3177,7 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj index 4437f8df07..ecfff1ffe1 100644 --- a/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/MacOSX/AudioPluginHost.xcodeproj/project.pbxproj @@ -488,6 +488,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.pluginhost; PRODUCT_NAME = "AudioPluginHost"; USE_HEADERMAP = NO; @@ -617,6 +618,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.pluginhost; PRODUCT_NAME = "AudioPluginHost"; USE_HEADERMAP = NO; diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj index 0da54bedde..f96fb58475 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj @@ -3056,6 +3056,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters index f2d905b1d6..4359b5c838 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2015/AudioPluginHost_App.vcxproj.filters @@ -5151,6 +5151,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj index a7eaa77354..c774055738 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj @@ -3056,6 +3056,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters index 1c128475c9..fa1a45863f 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters @@ -5151,6 +5151,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index 928e7ffaa2..082fc45023 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -3056,6 +3056,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index 1c3e3efd7f..8a92d923ca 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -5151,6 +5151,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj index be5627fce7..a80f41b775 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -3056,6 +3056,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index 96eead24b2..93146206c1 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -5151,6 +5151,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj index 5895abd3e2..10f0744788 100644 --- a/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj +++ b/extras/AudioPluginHost/Builds/iOS/AudioPluginHost.xcodeproj/project.pbxproj @@ -496,6 +496,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.pluginhost; PRODUCT_NAME = "Plugin Host"; USE_HEADERMAP = NO; @@ -626,6 +627,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.pluginhost; PRODUCT_NAME = "Plugin Host"; USE_HEADERMAP = NO; diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index ba9a69d44e..8e220edddc 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -1402,6 +1402,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" "../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" "../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" + "../../../../../modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h" "../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" "../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" @@ -2999,6 +3000,7 @@ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_ios_Windowing.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_FileChooser.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp" PROPERTIES HEADER_FILE_ONLY TRUE) +set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MainMenu.mm" PROPERTIES HEADER_FILE_ONLY TRUE) set_source_files_properties("../../../../../modules/juce_gui_basics/native/juce_mac_MouseCursor.mm" PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj index d9d37e82ef..c366e31cf9 100644 --- a/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj +++ b/extras/NetworkGraphicsDemo/Builds/MacOSX/NetworkGraphicsDemo.xcodeproj/project.pbxproj @@ -406,6 +406,7 @@ LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.9; MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.NetworkGraphicsDemo; PRODUCT_NAME = "JUCE Network Graphics Demo"; USE_HEADERMAP = NO; @@ -569,6 +570,7 @@ INSTALL_PATH = "$(HOME)/Applications"; MACOSX_DEPLOYMENT_TARGET = 10.9; MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.NetworkGraphicsDemo; PRODUCT_NAME = "JUCE Network Graphics Demo"; USE_HEADERMAP = NO; diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index 462b5dc005..d7f49167cb 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -2919,6 +2919,7 @@ + diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 8b73614889..b18b5bc371 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -4878,6 +4878,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj index 4edd34810e..008d22fa09 100644 --- a/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj +++ b/extras/NetworkGraphicsDemo/Builds/iOS/NetworkGraphicsDemo.xcodeproj/project.pbxproj @@ -418,6 +418,7 @@ INSTALL_PATH = "$(HOME)/Applications"; LLVM_LTO = YES; MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.NetworkGraphicsDemo; PRODUCT_NAME = "JUCE Network Graphics Demo"; USE_HEADERMAP = NO; @@ -584,6 +585,7 @@ INFOPLIST_PREPROCESS = NO; INSTALL_PATH = "$(HOME)/Applications"; MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.NetworkGraphicsDemo; PRODUCT_NAME = "JUCE Network Graphics Demo"; USE_HEADERMAP = NO; diff --git a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj index 0f3d07cc02..e349790d8e 100644 --- a/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj +++ b/extras/Projucer/Builds/MacOSX/Projucer.xcodeproj/project.pbxproj @@ -1172,6 +1172,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../Build $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.theprojucer; PRODUCT_NAME = "Projucer"; USE_HEADERMAP = NO; @@ -1241,6 +1242,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../Build $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.theprojucer; PRODUCT_NAME = "Projucer"; USE_HEADERMAP = NO; diff --git a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj index e8f9dccb2b..e63ba2e8f1 100644 --- a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj @@ -2058,6 +2058,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters index 15a5ecd45a..ea2ebb5d59 100644 --- a/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2015/Projucer_App.vcxproj.filters @@ -3537,6 +3537,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj index 468c60158a..d4b497d1b7 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj @@ -2058,6 +2058,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters index 2be8d1126e..66ed6940c7 100644 --- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters @@ -3537,6 +3537,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj index 4753e8f76e..ae8ccd4d8c 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj @@ -2058,6 +2058,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters index c92b2abf45..05cd0c4f60 100644 --- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters @@ -3537,6 +3537,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj index 11fd5e5369..a49bcd0b7f 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj @@ -2058,6 +2058,7 @@ + diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters index bc6960b02d..a554318303 100644 --- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters +++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters @@ -3537,6 +3537,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj index d163bcd1ad..7db1976336 100644 --- a/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj +++ b/extras/UnitTestRunner/Builds/MacOSX/UnitTestRunner.xcodeproj/project.pbxproj @@ -453,6 +453,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.UnitTestRunner; PRODUCT_NAME = "UnitTestRunner"; USE_HEADERMAP = NO; @@ -575,6 +576,7 @@ MTL_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../../../modules/juce_audio_processors/format_types/VST3_SDK $(SRCROOT)/../../JuceLibraryCode $(SRCROOT)/../../../../modules"; OTHER_CFLAGS = "-Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; OTHER_CPLUSPLUSFLAGS = "-Woverloaded-virtual -Wreorder -Wzero-as-null-pointer-constant -Wunused-private-field -Winconsistent-missing-destructor-override -Wall -Wstrict-aliasing -Wuninitialized -Wunused-parameter -Wswitch-enum -Wsign-conversion -Wsign-compare -Wunreachable-code -Wcast-align -Wno-ignored-qualifiers -Wshorten-64-to-32 -Wconversion -Wint-conversion -Wconditional-uninitialized -Wconstant-conversion -Wbool-conversion -Wextra-semi -Wshift-sign-overflow -Wno-missing-field-initializers -Wshadow-all -Wnullable-to-nonnull-conversion"; + OTHER_LDFLAGS = "-weak_framework Metal -weak_framework MetalKit"; PRODUCT_BUNDLE_IDENTIFIER = com.juce.UnitTestRunner; PRODUCT_NAME = "UnitTestRunner"; USE_HEADERMAP = NO; diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj index d592dd4b30..f26e348a14 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj @@ -3124,6 +3124,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters index 59074ad2e3..3ece8e4e8f 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -5247,6 +5247,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 87f8d2c8f1..e651cd4558 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -3124,6 +3124,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index f4cc23b0b2..8d6d3f95a7 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -5247,6 +5247,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj index 58503efce2..4ec1ea6e95 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -3124,6 +3124,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index d965ab0abd..3791df5098 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -5247,6 +5247,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj index 1440270e7e..1e9bbe6e3b 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj @@ -2895,6 +2895,7 @@ + diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters index 1d5cfaaa27..2bb8f659e0 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters @@ -4845,6 +4845,9 @@ JUCE Modules\juce_gui_basics\native\x11 + + JUCE Modules\juce_gui_basics\native + JUCE Modules\juce_gui_basics\native diff --git a/modules/juce_core/native/juce_mac_ObjCHelpers.h b/modules/juce_core/native/juce_mac_ObjCHelpers.h index e91a0a02c2..cb29aca747 100644 --- a/modules/juce_core/native/juce_mac_ObjCHelpers.h +++ b/modules/juce_core/native/juce_mac_ObjCHelpers.h @@ -306,6 +306,9 @@ public: bool operator== (const ObjCObjectHandle& other) const { return item == other.item; } bool operator!= (const ObjCObjectHandle& other) const { return ! (*this == other); } + bool operator== (std::nullptr_t) const { return item == nullptr; } + bool operator!= (std::nullptr_t) const { return ! (*this == nullptr); } + private: void swap (ObjCObjectHandle& other) noexcept { std::swap (other.item, item); } diff --git a/modules/juce_core/system/juce_TargetPlatform.h b/modules/juce_core/system/juce_TargetPlatform.h index 3e14e9b741..aca2e65676 100644 --- a/modules/juce_core/system/juce_TargetPlatform.h +++ b/modules/juce_core/system/juce_TargetPlatform.h @@ -144,8 +144,8 @@ #endif #if JUCE_MAC - #if ! defined (MAC_OS_X_VERSION_10_11) - #error "The 10.11 SDK (Xcode 7.3.1+) is required to build JUCE apps. You can create apps that run on macOS 10.7+ by changing the deployment target." + #if ! defined (MAC_OS_X_VERSION_10_14) + #error "The 10.14 SDK (Xcode 10.1+) is required to build JUCE apps. You can create apps that run on macOS 10.7+ by changing the deployment target." #elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7 #error "Building for OSX 10.6 is no longer supported!" #endif diff --git a/modules/juce_gui_basics/juce_gui_basics.cpp b/modules/juce_gui_basics/juce_gui_basics.cpp index 217402c4ef..d9697568b7 100644 --- a/modules/juce_gui_basics/juce_gui_basics.cpp +++ b/modules/juce_gui_basics/juce_gui_basics.cpp @@ -42,6 +42,7 @@ #if JUCE_MAC #import #import + #import #if JUCE_SUPPORT_CARBON #import // still needed for SetSystemUIMode() @@ -52,6 +53,7 @@ #import #endif + #import #import //============================================================================== diff --git a/modules/juce_gui_basics/juce_gui_basics.h b/modules/juce_gui_basics/juce_gui_basics.h index 9d96b9580a..57d10f3ee1 100644 --- a/modules/juce_gui_basics/juce_gui_basics.h +++ b/modules/juce_gui_basics/juce_gui_basics.h @@ -36,8 +36,10 @@ minimumCppStandard: 14 dependencies: juce_graphics juce_data_structures - OSXFrameworks: Cocoa Carbon QuartzCore - iOSFrameworks: UIKit CoreServices + OSXFrameworks: Carbon Cocoa QuartzCore + WeakOSXFrameworks: Metal MetalKit + iOSFrameworks: CoreServices UIKit + WeakiOSFrameworks: Metal MetalKit END_JUCE_MODULE_DECLARATION diff --git a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm index b3e27c1233..765ecebe24 100644 --- a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm @@ -16,6 +16,13 @@ ============================================================================== */ +#include "juce_mac_CGMetalLayerRenderer.h" + +#if TARGET_OS_SIMULATOR && JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS + #warning JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS uses parts of the Metal API that are currently unsupported in the simulator - falling back to JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS=0 + #undef JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS +#endif + #if defined (__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 #define JUCE_HAS_IOS_POINTER_SUPPORT 1 #else @@ -125,6 +132,8 @@ struct CADisplayLinkDeleter - (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner withFrame: (CGRect) frame; - (void) dealloc; ++ (Class) layerClass; + - (void) displayLinkCallback: (CADisplayLink*) dl; - (void) drawRect: (CGRect) r; @@ -197,8 +206,8 @@ struct UIViewPeerControllerReceiver }; class UIViewComponentPeer : public ComponentPeer, - public FocusChangeListener, - public UIViewPeerControllerReceiver + private FocusChangeListener, + private UIViewPeerControllerReceiver { public: UIViewComponentPeer (Component&, int windowStyleFlags, UIView* viewToAttachTo); @@ -239,6 +248,7 @@ public: void displayLinkCallback(); void drawRect (CGRect); + void drawRectWithContext (CGContextRef, CGRect); bool canBecomeKeyWindow(); //============================================================================== @@ -315,6 +325,7 @@ private: } }; + std::unique_ptr metalRenderer; RectangleList deferredRepaints; //============================================================================== @@ -514,6 +525,16 @@ MultiTouchMapper UIViewComponentPeer::currentTouches; } //============================================================================== ++ (Class) layerClass +{ + #if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS + if (@available (iOS 12, *)) + return [CAMetalLayer class]; + #endif + + return [CALayer class]; +} + - (void) displayLinkCallback: (CADisplayLink*) dl { if (owner != nullptr) @@ -689,6 +710,11 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, int windowStyleFlags, view.opaque = component.isOpaque(); view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent: 0]; + #if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS + if (@available (iOS 12, *)) + metalRenderer = std::make_unique ((CAMetalLayer*) view.layer, comp); + #endif + if ((windowStyleFlags & ComponentPeer::windowRequiresSynchronousCoreGraphicsRendering) == 0) [[view layer] setDrawsAsynchronously: YES]; @@ -1170,10 +1196,40 @@ void UIViewComponentPeer::globalFocusChanged (Component*) //============================================================================== void UIViewComponentPeer::displayLinkCallback() { - for (const auto& r : deferredRepaints) - [view setNeedsDisplayInRect: convertToCGRect (r)]; + if (deferredRepaints.isEmpty()) + return; - deferredRepaints.clear(); + auto dispatchRectangles = [this] () + { + // We shouldn't need this preprocessor guard, but when running in the simulator + // CAMetalLayer is flagged as requiring iOS 13 + #if JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS + if (metalRenderer != nullptr) + { + if (@available (iOS 12, *)) + { + return metalRenderer->drawRectangleList ((CAMetalLayer*) view.layer, + (float) view.contentScaleFactor, + view.frame, + component, + [this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); }, + deferredRepaints); + } + + // The creation of metalRenderer should already be guarded with @available (iOS 12, *). + jassertfalse; + return false; + } + #endif + + for (const auto& r : deferredRepaints) + [view setNeedsDisplayInRect: convertToCGRect (r)]; + + return true; + }; + + if (dispatchRectangles()) + deferredRepaints.clear(); } //============================================================================== @@ -1182,8 +1238,11 @@ void UIViewComponentPeer::drawRect (CGRect r) if (r.size.width < 1.0f || r.size.height < 1.0f) return; - CGContextRef cg = UIGraphicsGetCurrentContext(); + drawRectWithContext (UIGraphicsGetCurrentContext(), r); +} +void UIViewComponentPeer::drawRectWithContext (CGContextRef cg, CGRect) +{ if (! component.isOpaque()) CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); diff --git a/modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h b/modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h new file mode 100644 index 0000000000..10f5e4d42e --- /dev/null +++ b/modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h @@ -0,0 +1,338 @@ +/* + ============================================================================== + + This file is part of the JUCE 7 technical preview. + Copyright (c) 2022 - Raw Material Software Limited + + You may use this code under the terms of the GPL v3 + (see www.gnu.org/licenses). + + For the technical preview this file cannot be licensed commercially. + + JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +// The CoreGraphicsMetalLayerRenderer requires macOS 10.14 and iOS 12. +JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wunguarded-availability", "-Wunguarded-availability-new") + +namespace juce +{ + +//============================================================================== +class CoreGraphicsMetalLayerRenderer +{ +public: + //============================================================================== + CoreGraphicsMetalLayerRenderer (CAMetalLayer* layer, const Component& comp) + { + device.reset (MTLCreateSystemDefaultDevice()); + + layer.device = device.get(); + layer.framebufferOnly = NO; + layer.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB; + layer.opaque = comp.isOpaque(); + layer.allowsNextDrawableTimeout = NO; + + commandQueue.reset ([device.get() newCommandQueue]); + + memoryBlitEvent.reset ([device.get() newSharedEvent]); + } + + ~CoreGraphicsMetalLayerRenderer() + { + stopGpuCommandSubmission = true; + [memoryBlitCommandBuffer.get() waitUntilCompleted]; + } + + template + bool drawRectangleList (CAMetalLayer* layer, + float scaleFactor, + CGRect viewFrame, + const Component& comp, + Callback&& drawRectWithContext, + const RectangleList& dirtyRegions) + { + if (resources != nullptr) + { + // If we haven't finished blitting the CPU texture to the GPU then + // report that we have been unable to draw anything. + if (memoryBlitEvent.get().signaledValue != memoryBlitCounter + 1) + return false; + + ++memoryBlitCounter; + } + + layer.contentsScale = scaleFactor; + const auto drawableSizeTansform = CGAffineTransformMakeScale (layer.contentsScale, + layer.contentsScale); + const auto transformedFrameSize = CGSizeApplyAffineTransform (viewFrame.size, drawableSizeTansform); + + const auto componentHeight = comp.getHeight(); + + if (! CGSizeEqualToSize (layer.drawableSize, transformedFrameSize)) + { + layer.drawableSize = transformedFrameSize; + resources = std::make_unique (device.get(), layer, componentHeight); + } + + auto gpuTexture = resources->getGpuTexture(); + + if (gpuTexture == nullptr) + { + jassertfalse; + return false; + } + + auto cgContext = resources->getCGContext(); + + for (auto rect : dirtyRegions) + { + const auto cgRect = convertToCGRect (rect); + + CGContextSaveGState (cgContext); + + CGContextClipToRect (cgContext, cgRect); + drawRectWithContext (cgContext, cgRect); + + CGContextRestoreGState (cgContext); + } + + auto cpuTexture = resources->getCpuTexture(); + + memoryBlitCommandBuffer.reset ([commandQueue.get() commandBuffer]); + + // Command buffers are usually considered temporary, and are automatically released by + // the operating system when the rendering pipeline is finsihed. However, we want to keep + // this one alive so that we can wait for pipeline completion in the destructor. + [memoryBlitCommandBuffer.get() retain]; + + auto blitCommandEncoder = [memoryBlitCommandBuffer.get() blitCommandEncoder]; + [blitCommandEncoder copyFromTexture: cpuTexture + sourceSlice: 0 + sourceLevel: 0 + sourceOrigin: MTLOrigin{} + sourceSize: MTLSize { cpuTexture.width, cpuTexture.height, 1 } + toTexture: gpuTexture + destinationSlice: 0 + destinationLevel: 0 + destinationOrigin: MTLOrigin{}]; + [blitCommandEncoder endEncoding]; + + // Signal that the GPU has finished using the CPU texture + [memoryBlitCommandBuffer.get() encodeSignalEvent: memoryBlitEvent.get() + value: memoryBlitCounter + 1]; + + [memoryBlitCommandBuffer.get() addScheduledHandler: ^(id) + { + // We're on a Metal thread, so we can make a blocking nextDrawable call + // without stalling the message thread. + + // Check if we can do an early exit. + if (stopGpuCommandSubmission) + return; + + @autoreleasepool + { + id drawable = [layer nextDrawable]; + + id presentationCommandBuffer = [commandQueue.get() commandBuffer]; + + auto presentationBlitCommandEncoder = [presentationCommandBuffer blitCommandEncoder]; + [presentationBlitCommandEncoder copyFromTexture: gpuTexture + sourceSlice: 0 + sourceLevel: 0 + sourceOrigin: MTLOrigin{} + sourceSize: MTLSize { gpuTexture.width, gpuTexture.height, 1 } + toTexture: drawable.texture + destinationSlice: 0 + destinationLevel: 0 + destinationOrigin: MTLOrigin{}]; + [presentationBlitCommandEncoder endEncoding]; + + [presentationCommandBuffer addScheduledHandler: ^(id) + { + [drawable present]; + }]; + + [presentationCommandBuffer commit]; + } + }]; + + [memoryBlitCommandBuffer.get() commit]; + + return true; + } + +private: + //============================================================================== + static auto alignTo (size_t n, size_t alignment) + { + return ((n + alignment - 1) / alignment) * alignment; + } + + //============================================================================== + struct TextureDeleter + { + void operator() (id texture) const noexcept + { + [texture setPurgeableState: MTLPurgeableStateEmpty]; + [texture release]; + } + }; + + using TextureUniquePtr = std::unique_ptr>, TextureDeleter>; + + //============================================================================== + class GpuTexturePool + { + public: + GpuTexturePool (id metalDevice, MTLTextureDescriptor* descriptor) + { + for (auto& t : textureCache) + t.reset ([metalDevice newTextureWithDescriptor: descriptor]); + } + + id take() const + { + auto iter = std::find_if (textureCache.begin(), textureCache.end(), + [] (const TextureUniquePtr& t) { return [t.get() retainCount] == 1; }); + return iter == textureCache.end() ? nullptr : (*iter).get(); + } + + private: + std::array textureCache; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GpuTexturePool) + JUCE_DECLARE_NON_MOVEABLE (GpuTexturePool) + }; + + //============================================================================== + class Resources + { + public: + Resources (id metalDevice, CAMetalLayer* layer, int componentHeight) + { + const auto bytesPerRow = alignTo ((size_t) layer.drawableSize.width * 4, 256); + + const auto allocationSize = cpuRenderMemory.ensureSize (bytesPerRow * (size_t) layer.drawableSize.height); + + ObjCObjectHandle> buffer { [metalDevice newBufferWithBytesNoCopy: cpuRenderMemory.get() + length: allocationSize + options: MTLResourceStorageModeShared + deallocator: nullptr] }; + + auto* textureDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: layer.pixelFormat + width: (NSUInteger) layer.drawableSize.width + height: (NSUInteger) layer.drawableSize.height + mipmapped: NO]; + textureDesc.storageMode = buffer.get().storageMode; + textureDesc.usage = MTLTextureUsageShaderRead; + + cpuTexture.reset ([buffer.get() newTextureWithDescriptor: textureDesc + offset: 0 + bytesPerRow: bytesPerRow]); + + cgContext.reset (CGBitmapContextCreate (cpuRenderMemory.get(), + (size_t) layer.drawableSize.width, + (size_t) layer.drawableSize.height, + 8, // Bits per component + bytesPerRow, + CGColorSpaceCreateWithName (kCGColorSpaceSRGB), + (uint32_t) kCGImageAlphaPremultipliedFirst | (uint32_t) kCGBitmapByteOrder32Host)); + + CGContextScaleCTM (cgContext.get(), layer.contentsScale, layer.contentsScale); + CGContextConcatCTM (cgContext.get(), CGAffineTransformMake (1, 0, 0, -1, 0, componentHeight)); + + textureDesc.storageMode = MTLStorageModePrivate; + gpuTexturePool = std::make_unique (metalDevice, textureDesc); + } + + CGContextRef getCGContext() const noexcept { return cgContext.get(); } + id getCpuTexture() const noexcept { return cpuTexture.get(); } + id getGpuTexture() noexcept { return gpuTexturePool == nullptr ? nullptr : gpuTexturePool->take(); } + + private: + class AlignedMemory + { + public: + AlignedMemory() = default; + + void* get() + { + return allocation != nullptr ? allocation->data : nullptr; + } + + size_t ensureSize (size_t newSize) + { + const auto alignedSize = alignTo (newSize, pagesize); + + if (alignedSize > size) + { + size = std::max (alignedSize, alignTo ((size_t) (size * growthFactor), pagesize)); + allocation = std::make_unique (pagesize, size); + } + + return size; + } + + private: + static constexpr float growthFactor = 1.3f; + + const size_t pagesize = (size_t) getpagesize(); + + struct AllocationWrapper + { + AllocationWrapper (size_t alignment, size_t allocationSize) + { + if (posix_memalign (&data, alignment, allocationSize) != 0) + jassertfalse; + } + + ~AllocationWrapper() + { + ::free (data); + } + + void* data = nullptr; + }; + + std::unique_ptr allocation; + size_t size = 0; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AlignedMemory) + JUCE_DECLARE_NON_MOVEABLE (AlignedMemory) + }; + + AlignedMemory cpuRenderMemory; + + detail::ContextPtr cgContext; + + TextureUniquePtr cpuTexture; + std::unique_ptr gpuTexturePool; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Resources) + JUCE_DECLARE_NON_MOVEABLE (Resources) + }; + + //============================================================================== + std::unique_ptr resources; + + ObjCObjectHandle> device; + ObjCObjectHandle> commandQueue; + ObjCObjectHandle> memoryBlitCommandBuffer; + ObjCObjectHandle> memoryBlitEvent; + + uint64_t memoryBlitCounter = 0; + std::atomic stopGpuCommandSubmission { false }; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreGraphicsMetalLayerRenderer) + JUCE_DECLARE_NON_MOVEABLE (CoreGraphicsMetalLayerRenderer) +}; + +JUCE_END_IGNORE_WARNINGS_GCC_LIKE + +} diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index 4b2da33571..630e6d3270 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -16,6 +16,8 @@ ============================================================================== */ +#include "juce_mac_CGMetalLayerRenderer.h" + @interface NSEvent (DeviceDelta) - (float)deviceDeltaX; - (float)deviceDeltaY; @@ -24,14 +26,11 @@ //============================================================================== namespace juce { - typedef void (*AppFocusChangeCallback)(); - extern AppFocusChangeCallback appFocusChangeCallback; - typedef bool (*CheckEventBlockedByModalComps) (NSEvent*); - extern CheckEventBlockedByModalComps isEventBlockedByModalComps; -} -namespace juce -{ +using AppFocusChangeCallback = void (*)(); +extern AppFocusChangeCallback appFocusChangeCallback; +using CheckEventBlockedByModalComps = bool (*) (NSEvent*); +extern CheckEventBlockedByModalComps isEventBlockedByModalComps; //============================================================================== static constexpr int translateVirtualToAsciiKeyCode (int keyCode) noexcept @@ -918,6 +917,11 @@ public: JUCE_END_IGNORE_WARNINGS_GCC_LIKE }(); + drawRectWithContext (cg, r); + } + + void drawRectWithContext (CGContextRef cg, NSRect r) + { if (! component.isOpaque()) CGContextClearRect (cg, CGContextGetClipBoundingBox (cg)); @@ -936,10 +940,12 @@ public: }; #if USE_COREGRAPHICS_RENDERING && JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS - // This option invokes a separate paint call for each rectangle of the clip region. - // It's a long story, but this is a basically a workaround for a CGContext not having - // a way of finding whether a rectangle falls within its clip region - if (usingCoreGraphics) + // This was a workaround for a CGContext not having a way of finding whether a rectangle + // falls within its clip region. However Apple removed the capability of + // [view getRectsBeingDrawn: ...] sometime around 10.13, so on later versions of macOS + // numRects will always be 1 and you'll need to use a CoreGraphicsMetalLayerRenderer + // to avoid CoreGraphics consolidating disparate rects. + if (usingCoreGraphics && metalRenderer == nullptr) { const NSRect* rects = nullptr; NSInteger numRects = 0; @@ -952,7 +958,7 @@ public: NSRect rect = rects[i]; CGContextSaveGState (cg); CGContextClipToRect (cg, CGRectMake (rect.origin.x, rect.origin.y, rect.size.width, rect.size.height)); - drawRectWithContext (cg, rect, displayScale); + renderRect (cg, rect, displayScale); CGContextRestoreGState (cg); } @@ -962,11 +968,11 @@ public: } #endif - drawRectWithContext (cg, r, displayScale); + renderRect (cg, r, displayScale); invalidateTransparentWindowShadow(); } - void drawRectWithContext (CGContextRef cg, NSRect r, float displayScale) + void renderRect (CGContextRef cg, NSRect r, float displayScale) { #if USE_COREGRAPHICS_RENDERING if (usingCoreGraphics) @@ -1049,11 +1055,61 @@ public: if (msSinceLastRepaint < minimumRepaintInterval && shouldThrottleRepaint()) return; - for (auto& i : deferredRepaints) - [view setNeedsDisplayInRect: makeNSRect (i)]; + #if USE_COREGRAPHICS_RENDERING && JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS + // We require macOS 10.14 to use the Metal layer renderer + if (@available (macOS 10.14, *)) + { + const auto& comp = getComponent(); - lastRepaintTime = Time::getMillisecondCounter(); - deferredRepaints.clear(); + // If we are resizing we need to fall back to synchronous drawing to avoid artefacts + if (areAnyWindowsInLiveResize()) + { + if (metalRenderer != nullptr) + { + metalRenderer.reset(); + view.wantsLayer = NO; + view.layer = nil; + deferredRepaints = comp.getLocalBounds().toFloat(); + } + } + else + { + if (metalRenderer == nullptr) + { + view.wantsLayer = YES; + view.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize; + view.layerContentsPlacement = NSViewLayerContentsPlacementTopLeft; + view.layer = [CAMetalLayer layer]; + metalRenderer = std::make_unique ((CAMetalLayer*) view.layer, getComponent()); + deferredRepaints = comp.getLocalBounds().toFloat(); + } + } + } + #endif + + auto dispatchRectangles = [this] () + { + if (metalRenderer != nullptr) + { + return metalRenderer->drawRectangleList ((CAMetalLayer*) view.layer, + (float) [[view window] backingScaleFactor], + view.frame, + getComponent(), + [this] (CGContextRef ctx, CGRect r) { drawRectWithContext (ctx, r); }, + deferredRepaints); + } + + for (auto& i : deferredRepaints) + [view setNeedsDisplayInRect: makeNSRect (i)]; + + return true; + }; + + if (dispatchRectangles()) + { + lastRepaintTime = Time::getMillisecondCounter(); + deferredRepaints.clear(); + } } void performAnyPendingRepaintsNow() override @@ -1157,6 +1213,7 @@ public: void redirectMovedOrResized() { handleMovedOrResized(); + setNeedsDisplayRectangles(); } void windowDidChangeScreen() @@ -1794,6 +1851,7 @@ private: [window setMaxFullScreenContentSize: NSMakeSize (100000, 100000)]; } + //============================================================================== void onDisplaySourceCallback() { setNeedsDisplayRectangles(); @@ -1836,6 +1894,8 @@ private: CVDisplayLinkRef displayLink = nullptr; dispatch_source_t displaySource = nullptr; + std::unique_ptr metalRenderer; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewComponentPeer) };