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; + + 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 - deferredRepaints.clear(); + 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(); + + // 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); + } - lastRepaintTime = Time::getMillisecondCounter(); - deferredRepaints.clear(); + 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) };