diff --git a/3rdparty/ext_qt/CMakeLists.txt b/3rdparty/ext_qt/CMakeLists.txt index 1845fee0b0..130d39fc80 100644 --- a/3rdparty/ext_qt/CMakeLists.txt +++ b/3rdparty/ext_qt/CMakeLists.txt @@ -1,214 +1,214 @@ SET(EXTPREFIX_qt "${EXTPREFIX}") if (WIN32) list(APPEND _QT_conf -skip qt3d -skip qtactiveqt -skip qtcanvas3d -skip qtconnectivity -skip qtdoc -skip qtenginio -skip qtgraphicaleffects -skip qtlocation -skip qtsensors -skip qtserialport -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtxmlpatterns -no-sql-sqlite -nomake examples -nomake tools -no-compile-examples -no-dbus -no-iconv -no-qml-debug -no-ssl -no-openssl -no-libproxy -no-system-proxies -no-icu -no-mtdev -skip qtcharts -skip qtdatavis3d -skip qtgamepad -skip qtnetworkauth -skip qtpurchasing -skip qtremoteobjects -skip qtscxml -skip qtserialbus -skip qtspeech -skip qtvirtualkeyboard # -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg # -opensource -confirm-license # -release -platform win32-g++ -prefix ${EXTPREFIX_qt} QMAKE_LFLAGS_APP+=${SECURITY_EXE_LINKER_FLAGS} QMAKE_LFLAGS_SHLIB+=${SECURITY_SHARED_LINKER_FLAGS} QMAKE_LFLAGS_SONAME+=${SECURITY_SHARED_LINKER_FLAGS} ) if (QT_ENABLE_DEBUG_INFO) # Set the option to build Qt with debugging info enabled list(APPEND _QT_conf -force-debug-info) endif(QT_ENABLE_DEBUG_INFO) if (QT_ENABLE_DYNAMIC_OPENGL) list(APPEND _QT_conf -opengl dynamic -angle) else (QT_ENABLE_DYNAMIC_OPENGL) list(APPEND _QT_conf -opengl desktop -no-angle) endif (QT_ENABLE_DYNAMIC_OPENGL) ExternalProject_Add( ext_qt DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} - URL https://download.qt.io/archive/qt/5.9/5.9.2/single/qt-everywhere-opensource-src-5.9.2.zip - URL_MD5 d5239e19f6b80dcf44f4dd2de04c7d3d + URL https://download.qt.io/archive/qt/5.9/5.9.3/single/qt-everywhere-opensource-src-5.9.3.zip + URL_HASH SHA1=2d3c53cd9dc76a479873548921a20d3d9b6fb9ac PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/disable-wintab.diff COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/qtgui-private-headers.diff COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/0001-Don-t-request-the-MIME-image-every-time-Windows-asks.patch COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/0002-Hack-always-return-we-support-DIBV5.patch COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/0003-Hack-for-fullscreen-workaround.patch COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/qopengldebug-gles.patch COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/gerrit-189539-ANGLE-mingw-fix.patch - COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/QTBUG-63654-fonts-too-small.patch + COMMAND ${PATCH_COMMAND} -p1 -d qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/gerrit-212811_qtbase-angle-d3d11-warp-crash-fix.patch INSTALL_DIR ${EXTPREFIX_qt} CONFIGURE_COMMAND /configure.bat ${_QT_conf} BUILD_COMMAND mingw32-make -j${SUBMAKE_JOBS} INSTALL_COMMAND mingw32-make -j${SUBMAKE_JOBS} install UPDATE_COMMAND "" # Use a short name to reduce the chance of exceeding path length limit SOURCE_DIR s BINARY_DIR b DEPENDS ext_patch ) elseif (NOT APPLE) ExternalProject_Add( ext_qt DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} URL https://download.qt.io/official_releases/qt/5.6/5.6.1-1/single/qt-everywhere-opensource-src-5.6.1-1.tar.gz URL_MD5 8fdec6d657bc370bd3183d8fe8e9c47a PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/qt-no-motion-compression.diff INSTALL_DIR ${EXTPREFIX_qt} CONFIGURE_COMMAND /configure -prefix ${EXTPREFIX_qt} -opensource -confirm-license -nomake examples -no-sql-sqlite -no-openssl -no-qml-debug -no-mtdev -no-journald -no-syslog -no-nis -no-cups -no-tslib -no-directfb -no-linuxfb -no-libproxy -no-pch -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-harfbuzz -qt-freetype -qt-xcb -qt-xkbcommon-x11 -optimized-qmake -skip qt3d -skip qtactiveqt -skip qtcanvas3d -skip qtconnectivity -skip qtenginio -skip qtgraphicaleffects -skip qtlocation -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtandroidextras -skip qtserialport BUILD_COMMAND $(MAKE) INSTALL_COMMAND $(MAKE) install UPDATE_COMMAND "" BUILD_IN_SOURCE 1 ) else( APPLE ) # XCODE_VERSION is set by CMake when using the Xcode generator, otherwise we need # to detect it manually here. if (NOT XCODE_VERSION) execute_process( COMMAND xcodebuild -version OUTPUT_VARIABLE xcodebuild_version OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_FILE /dev/null ) string(REGEX MATCH "Xcode ([0-9]([.][0-9])+)" version_match ${xcodebuild_version}) if (version_match) message(STATUS "${EXTPREFIX_qt}:Identified Xcode Version: ${CMAKE_MATCH_1}") set(XCODE_VERSION ${CMAKE_MATCH_1}) else() # If detecting Xcode version failed, set a crazy high version so we default # to the newest. set(XCODE_VERSION 99) message(WARNING "${EXTPREFIX_qt}:Failed to detect the version of an installed copy of Xcode, falling back to highest supported version. Set XCODE_VERSION to override.") endif(version_match) endif(NOT XCODE_VERSION) # ------------------------------------------------------------------------------- # Verify the Xcode installation on Mac OS like Qt5.7 does/will # If not stop now, the system isn't configured correctly for Qt. # No reason to even proceed. # ------------------------------------------------------------------------------- set(XCSELECT_OUTPUT) find_program(XCSELECT_PROGRAM "xcode-select") if(XCSELECT_PROGRAM) message(STATUS "${EXTPREFIX_qt}:Found XCSELECT_PROGRAM as ${XCSELECT_PROGRAM}") set(XCSELECT_COMMAND ${XCSELECT_PROGRAM} "--print-path") execute_process( COMMAND ${XCSELECT_COMMAND} RESULT_VARIABLE XCSELECT_COMMAND_RESULT OUTPUT_VARIABLE XCSELECT_COMMAND_OUTPUT ERROR_FILE /dev/null ) if(NOT XCSELECT_COMMAND_RESULT) # returned 0, we're ok. string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" XCSELECT_COMMAND_OUTPUT ${XCSELECT_COMMAND_OUTPUT}) else() string(REPLACE ";" " " XCSELECT_COMMAND_STR "${XCSELECT_COMMAND}") # message(STATUS "${XCSELECT_COMMAND_STR}") message(FATAL_ERROR "${EXTPREFIX_qt}:${XCSELECT_PROGRAM} test failed with status ${XCSELECT_COMMAND_RESULT}") endif() else() message(FATAL_ERROR "${EXTPREFIX_qt}:${XCSELECT_PROGRAM} not found. No Xcode is selected. Use xcode-select -switch to choose an Xcode version") endif() # Belts and suspenders # Beyond all the Xcode and Qt version checking, the proof of the pudding # lies in the success/failure of this command: xcrun --find xcrun. # On failure a patch is necessary, otherwise we're ok # So hard check xcrun now... set(XCRUN_OUTPUT) find_program(XCRUN_PROGRAM "xcrun") if(XCRUN_PROGRAM) message(STATUS "${EXTPREFIX_qt}:Found XCRUN_PROGRAM as ${XCRUN_PROGRAM}") set(XCRUN_COMMAND ${XCRUN_PROGRAM} "--find xcrun") execute_process( COMMAND ${XCRUN_COMMAND} RESULT_VARIABLE XCRUN_COMMAND_RESULT OUTPUT_VARIABLE XCRUN_COMMAND_OUTPUT ERROR_FILE /dev/null ) if(NOT XCRUN_COMMAND_RESULT) # returned 0, we're ok. string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" XCRUN_COMMAND_OUTPUT ${XCRUN_COMMAND_OUTPUT}) else() string(REPLACE ";" " " XCRUN_COMMAND_STR "${XCRUN_COMMAND}") # message(STATUS "${XCRUN_COMMAND_STR}") message(STATUS "${EXTPREFIX_qt}:xcrun test failed with status ${XCRUN_COMMAND_RESULT}") endif() else() message(STATUS "${EXTPREFIX_qt}:xcrun not found -- ${XCRUN_PROGRAM}") endif() # # Now configure ext_qt accordingly # if ((XCRUN_COMMAND_RESULT) AND (NOT (XCODE_VERSION VERSION_LESS 8.0.0))) # Fix Xcode xcrun related issue. # NOTE: This should be fixed by Qt 5.7.1 see here: http://code.qt.io/cgit/qt/qtbase.git/commit/?h=dev&id=77a71c32c9d19b87f79b208929e71282e8d8b5d9 # NOTE: but no one's holding their breath. set(ext_qt_PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/gerrit-166202.diff COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/macdeploy-qt.diff COMMAND ${PATCH_COMMAND} -p1 -b -d /qtbase -i ${CMAKE_CURRENT_SOURCE_DIR}/qtbase-configure.patch COMMAND ${PATCH_COMMAND} -p1 -b -d /qtbase/mkspecs/features/mac -i ${CMAKE_CURRENT_SOURCE_DIR}/mac-default.patch) message(STATUS "${EXTPREFIX_qt}:Additional patches injected.") else() # No extra patches will be applied # NOTE: defaults for some untested scenarios like xcrun fails and xcode_version < 8. # NOTE: that is uncharted territory and (hopefully) a very unlikely scenario... set(ext_qt_PATCH_COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/gerrit-166202.diff COMMAND ${PATCH_COMMAND} -p1 -i ${CMAKE_CURRENT_SOURCE_DIR}/macdeploy-qt.diff) endif() # Qt is big - try and parallelize if at all possible include(ProcessorCount) ProcessorCount(NUM_CORES) if(NOT NUM_CORES EQUAL 0) if (NUM_CORES GREATER 2) # be nice... MATH( EXPR NUM_CORES "${NUM_CORES} - 2" ) endif() set(PARALLEL_MAKE "make;-j${NUM_CORES}") message(STATUS "${EXTPREFIX_qt}:Parallelized make: ${PARALLEL_MAKE}") else() set(PARALLEL_MAKE "make") endif() ExternalProject_Add(ext_qt DOWNLOAD_DIR ${EXTERNALS_DOWNLOAD_DIR} LOG_DOWNLOAD ON LOG_UPDATE ON LOG_CONFIGURE ON LOG_BUILD ON LOG_TEST ON LOG_INSTALL ON BUILD_IN_SOURCE ON URL https://download.qt.io/official_releases/qt/5.7/5.7.0/single/qt-everywhere-opensource-src-5.7.0.tar.gz URL_MD5 9a46cce61fc64c20c3ac0a0e0fa41b42 PATCH_COMMAND ${ext_qt_PATCH_COMMAND} INSTALL_DIR ${EXTPREFIX_qt} CONFIGURE_COMMAND /configure -confirm-license -opensource -nomake examples -no-openssl -no-compile-examples -qt-freetype -qt-harfbuzz -opengl desktop -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -skip qt3d -skip qtactiveqt -skip qtcanvas3d -skip qtconnectivity -skip qtgraphicaleffects -skip qtlocation -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtxmlpatterns -prefix ${EXTPREFIX_qt} BUILD_COMMAND ${PARALLEL_MAKE} INSTALL_COMMAND make install UPDATE_COMMAND "" BUILD_IN_SOURCE 1 ) endif() diff --git a/3rdparty/ext_qt/QTBUG-63654-fonts-too-small.patch b/3rdparty/ext_qt/QTBUG-63654-fonts-too-small.patch deleted file mode 100644 index b2a1dd30b5..0000000000 --- a/3rdparty/ext_qt/QTBUG-63654-fonts-too-small.patch +++ /dev/null @@ -1,52 +0,0 @@ -commit 10444f68fb25bc0eebd4f161a58c494f68cce32f -Author: Alvin Wong -Date: Sun Oct 8 02:04:26 2017 +0800 - - Revert "Windows QPA: Hardcode a limit for the default point size" - - This reverts commit a72513cab7cdfac638ef572838277aa062f1d296. - -diff --git a/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp -index 58b700b93f..d3e4daa341 100644 ---- a/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp -+++ b/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp -@@ -1621,7 +1621,6 @@ void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont) - m_uniqueFontData[uniqueFont].refCount.ref(); - } - --// ### fixme Qt 6 (QTBUG-58610): See comment at QWindowsFontDatabase::systemDefaultFont() - HFONT QWindowsFontDatabase::systemFont() - { - static const HFONT stock_sysfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); -@@ -1962,31 +1961,12 @@ QFontEngine *QWindowsFontDatabase::createEngine(const QFontDef &request, const Q - - QFont QWindowsFontDatabase::systemDefaultFont() - { --#if QT_VERSION >= 0x060000 -- // Qt 6: Obtain default GUI font (typically "Segoe UI, 9pt", see QTBUG-58610) -- NONCLIENTMETRICS ncm; -- ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); -- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); -- const QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont); --#else - LOGFONT lf; - GetObject(QWindowsFontDatabase::systemFont(), sizeof(lf), &lf); - QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(lf); - // "MS Shell Dlg 2" is the correct system font >= Win2k - if (systemFont.family() == QLatin1String("MS Shell Dlg")) - systemFont.setFamily(QStringLiteral("MS Shell Dlg 2")); -- // Qt 5 by (Qt 4) legacy uses GetStockObject(DEFAULT_GUI_FONT) to -- // obtain the default GUI font (typically "MS Shell Dlg 2, 8pt"). This has been -- // long deprecated; the message font of the NONCLIENTMETRICS structure obtained by -- // SystemParametersInfo(SPI_GETNONCLIENTMETRICS) should be used instead (see -- // QWindowsTheme::refreshFonts(), typically "Segoe UI, 9pt"), which is larger. -- // In single monitor setups, the point sizes revolve around 8 (depending on UI -- // scale factor, but not proportional to it). However, in multi monitor setups, -- // where the DPI of the primary monitor are smaller than those of the secondary, -- // large bogus values are returned. Limit to 8.25 in that case. -- if (GetSystemMetrics(SM_CMONITORS) > 1 && systemFont.pointSizeF() > 8.25) -- systemFont.setPointSizeF(8.25); --#endif // Qt 5 - qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont; - return systemFont; - } diff --git a/3rdparty/ext_qt/gerrit-212811_qtbase-angle-d3d11-warp-crash-fix.patch b/3rdparty/ext_qt/gerrit-212811_qtbase-angle-d3d11-warp-crash-fix.patch new file mode 100644 index 0000000000..ff9ddf96e1 --- /dev/null +++ b/3rdparty/ext_qt/gerrit-212811_qtbase-angle-d3d11-warp-crash-fix.patch @@ -0,0 +1,50 @@ +commit 644ff9428853f138649de0419de4b49bf41bc738 +Author: Oliver Wolff +Date: Tue Nov 28 13:30:52 2017 +0100 + + ANGLE: D3D11: Fix shared handle support detection for WARP when MinGW is used + + The MinGW version we support supports IsWindows8OrGreater so that we can + check the windows version properly. As the OpenGL detection falls back + to WARP in case of RDP it was possible, that shared handles were wrongly + stated as supported, which caused crashes in users' code. + + Task-number: QTBUG-64657 + Change-Id: Iaca2bd169f2764cf6ec68a1d36112a735246b29a + Reviewed-by: Andre de la Rocha + Reviewed-by: Andy Shaw + (cherry picked from commit 6508fdca1dcc7105947befadba272d0fd4bbc27f) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +index 0173311bc6..5118bdbe9c 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +@@ -2645,7 +2645,7 @@ bool Renderer11::getShareHandleSupport() const + + if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP) + { +-#if !defined(ANGLE_ENABLE_WINDOWS_STORE) && !defined(__GNUC__) ++#ifndef ANGLE_ENABLE_WINDOWS_STORE + if (!IsWindows8OrGreater()) + { + // WARP on Windows 7 doesn't support shared handles +diff --git a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch +index dc091b0497..f42ff2141b 100644 +--- a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch ++++ b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch +@@ -405,15 +405,6 @@ index ea84783..62badcc 100644 + + if (mD3d11Module) + { +-@@ -2618,7 +2642,7 @@ bool Renderer11::getShareHandleSupport() const +- +- if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP) +- { +--#ifndef ANGLE_ENABLE_WINDOWS_STORE +-+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) && !defined(__GNUC__) +- if (!IsWindows8OrGreater()) +- { +- // WARP on Windows 7 doesn't support shared handles + diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h + index 62e9816..b4e7761 100644 + --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index 7519eeac96..30d7be8d73 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -1,579 +1,580 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/qtlockedfile ${EXIV2_INCLUDE_DIR} ) include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR} ${OCIO_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ) add_subdirectory( tests ) if (APPLE) find_library(FOUNDATION_LIBRARY Foundation) find_library(APPKIT_LIBRARY AppKit) endif () set(kritaui_LIB_SRCS canvas/kis_canvas_widget_base.cpp canvas/kis_canvas2.cpp canvas/kis_canvas_updates_compressor.cpp canvas/kis_canvas_controller.cpp canvas/kis_paintop_transformation_connector.cpp canvas/kis_display_color_converter.cpp canvas/kis_display_filter.cpp canvas/kis_exposure_gamma_correction_interface.cpp canvas/kis_tool_proxy.cpp canvas/kis_canvas_decoration.cc canvas/kis_coordinates_converter.cpp canvas/kis_grid_manager.cpp canvas/kis_grid_decoration.cpp canvas/kis_grid_config.cpp canvas/kis_prescaled_projection.cpp canvas/kis_qpainter_canvas.cpp canvas/kis_projection_backend.cpp canvas/kis_update_info.cpp canvas/kis_image_patch.cpp canvas/kis_image_pyramid.cpp canvas/kis_infinity_manager.cpp canvas/kis_change_guides_command.cpp canvas/kis_guides_decoration.cpp canvas/kis_guides_manager.cpp canvas/kis_guides_config.cpp canvas/kis_snap_config.cpp canvas/kis_snap_line_strategy.cpp canvas/KisSnapPointStrategy.cpp dialogs/kis_about_application.cpp dialogs/kis_dlg_adj_layer_props.cc dialogs/kis_dlg_adjustment_layer.cc dialogs/kis_dlg_filter.cpp dialogs/kis_dlg_generator_layer.cpp dialogs/kis_dlg_file_layer.cpp dialogs/kis_dlg_filter.cpp dialogs/kis_dlg_stroke_selection_properties.cpp dialogs/kis_dlg_image_properties.cc dialogs/kis_dlg_layer_properties.cc dialogs/kis_dlg_preferences.cc dialogs/slider_and_spin_box_sync.cpp dialogs/kis_dlg_blacklist_cleanup.cpp dialogs/kis_dlg_layer_style.cpp dialogs/kis_dlg_png_import.cpp dialogs/kis_dlg_import_image_sequence.cpp dialogs/kis_delayed_save_dialog.cpp dialogs/kis_dlg_internal_color_selector.cpp flake/kis_node_dummies_graph.cpp flake/kis_dummies_facade_base.cpp flake/kis_dummies_facade.cpp flake/kis_node_shapes_graph.cpp flake/kis_node_shape.cpp flake/kis_shape_controller.cpp flake/kis_shape_layer.cc flake/kis_shape_layer_canvas.cpp flake/kis_shape_selection.cpp flake/kis_shape_selection_canvas.cpp flake/kis_shape_selection_model.cpp flake/kis_take_all_shapes_command.cpp brushhud/kis_uniform_paintop_property_widget.cpp brushhud/kis_brush_hud.cpp brushhud/kis_round_hud_button.cpp brushhud/kis_dlg_brush_hud_config.cpp brushhud/kis_brush_hud_properties_list.cpp brushhud/kis_brush_hud_properties_config.cpp kis_aspect_ratio_locker.cpp kis_autogradient.cc kis_bookmarked_configurations_editor.cc kis_bookmarked_configurations_model.cc kis_bookmarked_filter_configurations_model.cc kis_base_option.cpp kis_canvas_resource_provider.cpp kis_derived_resources.cpp kis_categories_mapper.cpp kis_categorized_list_model.cpp kis_categorized_item_delegate.cpp kis_clipboard.cc kis_config.cc kis_config_notifier.cpp kis_control_frame.cpp kis_composite_ops_model.cc kis_paint_ops_model.cpp kis_cursor.cc kis_cursor_cache.cpp kis_custom_pattern.cc kis_file_layer.cpp kis_change_file_layer_command.h kis_safe_document_loader.cpp kis_splash_screen.cpp kis_filter_manager.cc kis_filters_model.cc kis_histogram_view.cc KisImageBarrierLockerWithFeedback.cpp kis_image_manager.cc kis_image_view_converter.cpp kis_import_catcher.cc kis_layer_manager.cc kis_mask_manager.cc kis_mimedata.cpp kis_node_commands_adapter.cpp kis_node_manager.cpp kis_node_juggler_compressed.cpp kis_node_selection_adapter.cpp kis_node_insertion_adapter.cpp kis_node_model.cpp kis_node_filter_proxy_model.cpp kis_model_index_converter_base.cpp kis_model_index_converter.cpp kis_model_index_converter_show_all.cpp kis_painting_assistant.cc kis_painting_assistants_decoration.cpp kis_painting_assistants_manager.cpp kis_paintop_box.cc kis_paintop_option.cpp kis_paintop_options_model.cpp kis_paintop_settings_widget.cpp kis_popup_palette.cpp kis_png_converter.cpp kis_preference_set_registry.cpp kis_script_manager.cpp kis_resource_server_provider.cpp KisSelectedShapesProxy.cpp kis_selection_decoration.cc kis_selection_manager.cc kis_statusbar.cc kis_zoom_manager.cc kis_favorite_resource_manager.cpp kis_workspace_resource.cpp kis_action.cpp kis_action_manager.cpp kis_view_plugin.cpp kis_canvas_controls_manager.cpp kis_tooltip_manager.cpp kis_multinode_property.cpp kis_stopgradient_editor.cpp kisexiv2/kis_exif_io.cpp kisexiv2/kis_exiv2.cpp kisexiv2/kis_iptc_io.cpp kisexiv2/kis_xmp_io.cpp opengl/kis_opengl.cpp opengl/kis_opengl_canvas2.cpp opengl/kis_opengl_canvas_debugger.cpp opengl/kis_opengl_image_textures.cpp opengl/kis_texture_tile.cpp opengl/kis_opengl_shader_loader.cpp opengl/kis_texture_tile_info_pool.cpp kis_fps_decoration.cpp recorder/kis_node_query_path_editor.cc recorder/kis_recorded_action_creator.cc recorder/kis_recorded_action_creator_factory.cc recorder/kis_recorded_action_creator_factory_registry.cc recorder/kis_recorded_action_editor_factory.cc recorder/kis_recorded_action_editor_factory_registry.cc recorder/kis_recorded_filter_action_editor.cc recorder/kis_recorded_filter_action_creator.cpp recorder/kis_recorded_paint_action_editor.cc tool/kis_selection_tool_helper.cpp tool/kis_selection_tool_config_widget_helper.cpp tool/kis_rectangle_constraint_widget.cpp tool/kis_shape_tool_helper.cpp tool/kis_tool.cc tool/kis_delegated_tool_policies.cpp tool/kis_tool_freehand.cc tool/kis_speed_smoother.cpp tool/kis_painting_information_builder.cpp tool/kis_stabilized_events_sampler.cpp tool/kis_tool_freehand_helper.cpp tool/kis_tool_multihand_helper.cpp tool/kis_figure_painting_tool_helper.cpp tool/kis_recording_adapter.cpp tool/kis_tool_paint.cc tool/kis_tool_shape.cc tool/kis_tool_ellipse_base.cpp tool/kis_tool_rectangle_base.cpp tool/kis_tool_polyline_base.cpp tool/kis_tool_utils.cpp tool/kis_resources_snapshot.cpp tool/kis_smoothing_options.cpp tool/KisStabilizerDelayedPaintHelper.cpp tool/KisStrokeSpeedMonitor.cpp tool/strokes/freehand_stroke.cpp tool/strokes/KisStrokeEfficiencyMeasurer.cpp tool/strokes/kis_painter_based_stroke_strategy.cpp tool/strokes/kis_filter_stroke_strategy.cpp tool/strokes/kis_color_picker_stroke_strategy.cpp widgets/kis_cmb_composite.cc widgets/kis_cmb_contour.cpp widgets/kis_cmb_gradient.cpp widgets/kis_paintop_list_widget.cpp widgets/kis_cmb_idlist.cc widgets/kis_color_space_selector.cc widgets/kis_advanced_color_space_selector.cc widgets/kis_cie_tongue_widget.cpp widgets/kis_tone_curve_widget.cpp widgets/kis_curve_widget.cpp widgets/kis_custom_image_widget.cc widgets/kis_image_from_clipboard_widget.cpp widgets/kis_double_widget.cc widgets/kis_filter_selector_widget.cc widgets/kis_gradient_chooser.cc widgets/kis_gradient_slider_widget.cc widgets/kis_gradient_slider.cpp widgets/kis_iconwidget.cc widgets/kis_mask_widgets.cpp widgets/kis_meta_data_merge_strategy_chooser_widget.cc widgets/kis_multi_bool_filter_widget.cc widgets/kis_multi_double_filter_widget.cc widgets/kis_multi_integer_filter_widget.cc widgets/kis_multipliers_double_slider_spinbox.cpp widgets/kis_paintop_presets_popup.cpp widgets/kis_tool_options_popup.cpp widgets/kis_paintop_presets_chooser_popup.cpp widgets/kis_paintop_presets_save.cpp widgets/kis_paintop_preset_icon_library.cpp widgets/kis_pattern_chooser.cc widgets/kis_popup_button.cc widgets/kis_preset_chooser.cpp widgets/kis_progress_widget.cpp widgets/kis_selection_options.cc widgets/kis_scratch_pad.cpp widgets/kis_scratch_pad_event_filter.cpp widgets/kis_preset_selector_strip.cpp widgets/kis_slider_spin_box.cpp widgets/kis_size_group.cpp widgets/kis_size_group_p.cpp widgets/kis_wdg_generator.cpp widgets/kis_workspace_chooser.cpp widgets/squeezedcombobox.cpp widgets/kis_categorized_list_view.cpp widgets/kis_widget_chooser.cpp widgets/kis_tool_button.cpp widgets/kis_floating_message.cpp widgets/kis_lod_availability_widget.cpp widgets/kis_color_label_selector_widget.cpp widgets/kis_color_filter_combo.cpp widgets/kis_elided_label.cpp widgets/kis_stopgradient_slider_widget.cpp widgets/kis_spinbox_color_selector.cpp widgets/kis_screen_color_picker.cpp widgets/kis_preset_live_preview_view.cpp widgets/KoDualColorButton.cpp widgets/kis_color_input.cpp widgets/kis_color_button.cpp widgets/KisVisualColorSelector.cpp widgets/KisVisualColorSelectorShape.cpp widgets/KisVisualEllipticalSelectorShape.cpp widgets/KisVisualRectangleSelectorShape.cpp widgets/KisVisualTriangleSelectorShape.cpp widgets/KoStrokeConfigWidget.cpp widgets/KoFillConfigWidget.cpp widgets/KoShapeFillWrapper.cpp utils/kis_document_aware_spin_box_unit_manager.cpp input/kis_input_manager.cpp input/kis_input_manager_p.cpp input/kis_extended_modifiers_mapper.cpp input/kis_abstract_input_action.cpp input/kis_tool_invocation_action.cpp input/kis_pan_action.cpp input/kis_alternate_invocation_action.cpp input/kis_rotate_canvas_action.cpp input/kis_zoom_action.cpp input/kis_change_frame_action.cpp input/kis_gamma_exposure_action.cpp input/kis_show_palette_action.cpp input/kis_change_primary_setting_action.cpp input/kis_abstract_shortcut.cpp input/kis_native_gesture_shortcut.cpp input/kis_single_action_shortcut.cpp input/kis_stroke_shortcut.cpp input/kis_shortcut_matcher.cpp input/kis_select_layer_action.cpp input/KisQtWidgetsTweaker.cpp operations/kis_operation.cpp operations/kis_operation_configuration.cpp operations/kis_operation_registry.cpp operations/kis_operation_ui_factory.cpp operations/kis_operation_ui_widget.cpp operations/kis_filter_selection_operation.cpp actions/kis_selection_action_factories.cpp actions/KisPasteActionFactory.cpp input/kis_touch_shortcut.cpp kis_document_undo_store.cpp kis_transaction_based_command.cpp kis_gui_context_command.cpp kis_gui_context_command_p.cpp input/kis_tablet_debugger.cpp input/kis_input_profile_manager.cpp input/kis_input_profile.cpp input/kis_shortcut_configuration.cpp input/config/kis_input_configuration_page.cpp input/config/kis_edit_profiles_dialog.cpp input/config/kis_input_profile_model.cpp input/config/kis_input_configuration_page_item.cpp input/config/kis_action_shortcuts_model.cpp input/config/kis_input_type_delegate.cpp input/config/kis_input_mode_delegate.cpp input/config/kis_input_button.cpp input/config/kis_input_editor_delegate.cpp input/config/kis_mouse_input_editor.cpp input/config/kis_wheel_input_editor.cpp input/config/kis_key_input_editor.cpp processing/fill_processing_visitor.cpp kis_asl_layer_style_serializer.cpp kis_psd_layer_style_resource.cpp canvas/kis_mirror_axis.cpp kis_abstract_perspective_grid.cpp KisApplication.cpp KisAutoSaveRecoveryDialog.cpp KisDetailsPane.cpp KisDocument.cpp KisNodeDelegate.cpp kis_node_view_visibility_delegate.cpp KisNodeToolTip.cpp KisNodeView.cpp kis_node_view_color_scheme.cpp KisImportExportFilter.cpp KisFilterEntry.cpp KisImportExportManager.cpp KisImportExportUtils.cpp kis_async_action_feedback.cpp KisMainWindow.cpp KisOpenPane.cpp KisPart.cpp KisPrintJob.cpp KisTemplate.cpp KisTemplateCreateDia.cpp KisTemplateGroup.cpp KisTemplates.cpp KisTemplatesPane.cpp KisTemplateTree.cpp KisUndoStackAction.cpp KisView.cpp thememanager.cpp kis_mainwindow_observer.cpp KisViewManager.cpp kis_mirror_manager.cpp qtlockedfile/qtlockedfile.cpp qtsingleapplication/qtlocalpeer.cpp qtsingleapplication/qtsingleapplication.cpp KisResourceBundle.cpp KisResourceBundleManifest.cpp kis_md5_generator.cpp KisApplicationArguments.cpp KisNetworkAccessManager.cpp KisMultiFeedRSSModel.cpp KisRemoteFileFetcher.cpp KisPaletteModel.cpp kis_palette_delegate.cpp kis_palette_view.cpp KisColorsetChooser.cpp KisSaveGroupVisitor.cpp ) if(WIN32) if (NOT Qt5Gui_PRIVATE_INCLUDE_DIRS) message(FATAL_ERROR "Qt5Gui Private header are missing!") endif() set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/kis_tablet_event.cpp input/wintab/kis_tablet_support_win.cpp input/wintab/kis_screen_size_choice_dialog.cpp qtlockedfile/qtlockedfile_win.cpp input/wintab/kis_tablet_support_win8.cpp + opengl/kis_opengl_win.cpp ) include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) endif() set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} kis_animation_frame_cache.cpp kis_animation_cache_populator.cpp KisAsyncAnimationRendererBase.cpp KisAsyncAnimationCacheRenderer.cpp KisAsyncAnimationFramesSavingRenderer.cpp dialogs/KisAsyncAnimationRenderDialogBase.cpp dialogs/KisAsyncAnimationCacheRenderDialog.cpp dialogs/KisAsyncAnimationFramesSaveDialog.cpp canvas/kis_animation_player.cpp kis_animation_importer.cpp KisSyncedAudioPlayback.cpp ) if(UNIX) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/kis_tablet_event.cpp input/wintab/kis_tablet_support.cpp qtlockedfile/qtlockedfile_unix.cpp ) if(NOT APPLE) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} input/wintab/kis_tablet_support_x11.cpp input/wintab/qxcbconnection_xi2.cpp input/wintab/qxcbconnection.cpp input/wintab/kis_xi2_event_filter.cpp ) endif() endif() if(APPLE) set(kritaui_LIB_SRCS ${kritaui_LIB_SRCS} osx.mm ) endif() ki18n_wrap_ui(kritaui_LIB_SRCS widgets/KoFillConfigWidget.ui widgets/KoStrokeConfigWidget.ui forms/wdgdlgpngimport.ui forms/wdgfullscreensettings.ui forms/wdgautogradient.ui forms/wdggeneralsettings.ui forms/wdgperformancesettings.ui forms/wdggenerators.ui forms/wdgbookmarkedconfigurationseditor.ui forms/wdgapplyprofile.ui forms/wdgcustompattern.ui forms/wdglayerproperties.ui forms/wdgcolorsettings.ui forms/wdgtabletsettings.ui forms/wdgcolorspaceselector.ui forms/wdgcolorspaceselectoradvanced.ui forms/wdgdisplaysettings.ui forms/kis_previewwidgetbase.ui forms/kis_matrix_widget.ui forms/wdgselectionoptions.ui forms/wdggeometryoptions.ui forms/wdgnewimage.ui forms/wdgimageproperties.ui forms/wdgmaskfromselection.ui forms/wdgmasksource.ui forms/wdgfilterdialog.ui forms/wdgmetadatamergestrategychooser.ui forms/wdgpaintoppresets.ui forms/wdgpaintopsettings.ui forms/wdgdlggeneratorlayer.ui forms/wdgdlgfilelayer.ui forms/wdgfilterselector.ui forms/wdgfilternodecreation.ui forms/wdgpaintactioneditor.ui forms/wdgmultipliersdoublesliderspinbox.ui forms/wdgnodequerypatheditor.ui forms/wdgpresetselectorstrip.ui forms/wdgsavebrushpreset.ui forms/wdgpreseticonlibrary.ui forms/wdgdlgblacklistcleanup.ui forms/wdgrectangleconstraints.ui forms/wdgimportimagesequence.ui forms/wdgstrokeselectionproperties.ui forms/KisDetailsPaneBase.ui forms/KisOpenPaneBase.ui forms/wdgstopgradienteditor.ui brushhud/kis_dlg_brush_hud_config.ui forms/wdgdlginternalcolorselector.ui dialogs/kis_delayed_save_dialog.ui input/config/kis_input_configuration_page.ui input/config/kis_edit_profiles_dialog.ui input/config/kis_input_configuration_page_item.ui input/config/kis_mouse_input_editor.ui input/config/kis_wheel_input_editor.ui input/config/kis_key_input_editor.ui layerstyles/wdgBevelAndEmboss.ui layerstyles/wdgblendingoptions.ui layerstyles/WdgColorOverlay.ui layerstyles/wdgContour.ui layerstyles/wdgdropshadow.ui layerstyles/WdgGradientOverlay.ui layerstyles/wdgInnerGlow.ui layerstyles/wdglayerstyles.ui layerstyles/WdgPatternOverlay.ui layerstyles/WdgSatin.ui layerstyles/WdgStroke.ui layerstyles/wdgstylesselector.ui layerstyles/wdgTexture.ui wdgsplash.ui input/wintab/kis_screen_size_choice_dialog.ui ) QT5_WRAP_CPP(kritaui_HEADERS_MOC KisNodePropertyAction_p.h) add_library(kritaui SHARED ${kritaui_HEADERS_MOC} ${kritaui_LIB_SRCS} ) generate_export_header(kritaui BASE_NAME kritaui) target_link_libraries(kritaui KF5::CoreAddons KF5::Completion KF5::I18n KF5::ItemViews Qt5::Network kritaimpex kritacolor kritaimage kritalibbrush kritawidgets kritawidgetutils ${PNG_LIBRARIES} ${EXIV2_LIBRARIES} ) if (HAVE_QT_MULTIMEDIA) target_link_libraries(kritaui Qt5::Multimedia) endif() if (HAVE_KIO) target_link_libraries(kritaui KF5::KIOCore) endif() if (NOT WIN32 AND NOT APPLE) target_link_libraries(kritaui ${X11_X11_LIB} ${X11_Xinput_LIB} ${XCB_LIBRARIES}) endif() if(APPLE) target_link_libraries(kritaui ${FOUNDATION_LIBRARY}) target_link_libraries(kritaui ${APPKIT_LIBRARY}) endif () target_link_libraries(kritaui ${OPENEXR_LIBRARIES}) # Add VSync disable workaround if(NOT WIN32 AND NOT APPLE) target_link_libraries(kritaui ${CMAKE_DL_LIBS} Qt5::X11Extras) endif() if(X11_FOUND) target_link_libraries(kritaui Qt5::X11Extras ${X11_LIBRARIES}) endif() target_include_directories(kritaui PUBLIC $ $ $ $ $ $ $ ) set_target_properties(kritaui PROPERTIES VERSION ${GENERIC_KRITA_LIB_VERSION} SOVERSION ${GENERIC_KRITA_LIB_SOVERSION} ) install(TARGETS kritaui ${INSTALL_TARGETS_DEFAULT_ARGS}) if (APPLE) install(FILES osx.stylesheet DESTINATION ${DATA_INSTALL_DIR}/krita) endif () diff --git a/libs/ui/opengl/kis_opengl.cpp b/libs/ui/opengl/kis_opengl.cpp index 41aa35db36..5539df2008 100644 --- a/libs/ui/opengl/kis_opengl.cpp +++ b/libs/ui/opengl/kis_opengl.cpp @@ -1,600 +1,289 @@ /* * Copyright (c) 2007 Adrian Page * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "opengl/kis_opengl.h" +#include "opengl/kis_opengl_p.h" #include #include #include #include #include #include #include #include #include -#include -#include -#include #include -#include - #include #include -#include #include #ifndef GL_RENDERER # define GL_RENDERER 0x1F01 #endif +using namespace KisOpenGLPrivate; + namespace { bool defaultFormatIsSet = false; bool isDebugEnabled = false; bool isDebugSynchronous = false; - struct OpenGLCheckResult { - // bool contextValid = false; - int glMajorVersion = 0; - int glMinorVersion = 0; - bool supportsDeprecatedFunctions = false; - bool isOpenGLES = false; - QString rendererString; - QString driverVersionString; - - OpenGLCheckResult(QOpenGLContext &context) { - if (!context.isValid()) { - return; - } - - QOpenGLFunctions *funcs = context.functions(); // funcs is ready to be used - - rendererString = QString(reinterpret_cast(funcs->glGetString(GL_RENDERER))); - driverVersionString = QString(reinterpret_cast(funcs->glGetString(GL_VERSION))); - glMajorVersion = context.format().majorVersion(); - glMinorVersion = context.format().minorVersion(); - supportsDeprecatedFunctions = (context.format().options() & QSurfaceFormat::DeprecatedFunctions); - isOpenGLES = context.isOpenGLES(); - } - - bool isSupportedVersion() const { - return -#ifdef Q_OS_OSX - ((glMajorVersion * 100 + glMinorVersion) >= 302) -#else - (glMajorVersion >= 3 && (supportsDeprecatedFunctions || isOpenGLES)) || - ((glMajorVersion * 100 + glMinorVersion) == 201) -#endif - ; - } - - bool supportsLoD() const { - return (glMajorVersion * 100 + glMinorVersion) >= 300; - } - - bool hasOpenGL3() const { - return (glMajorVersion * 100 + glMinorVersion) >= 302; - } - - bool supportsFenceSync() const { - return glMajorVersion >= 3; - } -#ifdef Q_OS_WIN - // This is only for detecting whether ANGLE is being used. - // For detecting generic OpenGL ES please check isOpenGLES - bool isUsingAngle() const { - return rendererString.startsWith("ANGLE", Qt::CaseInsensitive); - } -#endif - }; boost::optional openGLCheckResult; bool NeedsFenceWorkaround = false; bool NeedsPixmapCacheWorkaround = false; QString debugText("OpenGL Info\n **OpenGL not initialized**"); void openglOnMessageLogged(const QOpenGLDebugMessage& debugMessage) { qDebug() << "OpenGL:" << debugMessage; } } -#ifdef Q_OS_WIN -namespace -{ - struct WindowsOpenGLStatus { - bool supportsDesktopGL = false; - bool supportsAngleD3D11 = false; - bool isQtPreferAngle = false; - bool overridePreferAngle = false; // override Qt to force ANGLE to be preferred - }; - WindowsOpenGLStatus windowsOpenGLStatus = {}; - KisOpenGL::OpenGLRenderer userRendererConfig; - KisOpenGL::OpenGLRenderer nextUserRendererConfig; - KisOpenGL::OpenGLRenderer currentRenderer; - - QStringList qpaDetectionLog; - - boost::optional checkQpaOpenGLStatus() { - QWindow surface; - surface.setSurfaceType(QSurface::OpenGLSurface); - surface.create(); - QOpenGLContext context; - if (!context.create()) { - qDebug() << "OpenGL context cannot be created"; - return boost::none; - } - if (!context.isValid()) { - qDebug() << "OpenGL context is not valid while checking Qt's OpenGL status"; - return boost::none; - } - if (!context.makeCurrent(&surface)) { - qDebug() << "OpenGL context cannot be made current"; - return boost::none; - } - return OpenGLCheckResult(context); - } - - bool checkIsSupportedDesktopGL(const OpenGLCheckResult &checkResult) { - if (checkResult.isUsingAngle()) { - qWarning() << "ANGLE was being used when desktop OpenGL was wanted, assuming no desktop OpenGL support"; - return false; - } - if (checkResult.isOpenGLES) { - qWarning() << "Got OpenGL ES instead of desktop OpenGL, this shouldn't happen!"; - return false; - } - return checkResult.isSupportedVersion(); - } - - bool checkIsSupportedAngleD3D11(const OpenGLCheckResult &checkResult) { - if (!checkResult.isUsingAngle()) { - qWarning() << "Desktop OpenGL was being used when ANGLE was wanted, assuming no ANGLE support"; - return false; - } - if (!checkResult.isOpenGLES) { - qWarning() << "Got desktop OpenGL instead of OpenGL ES, this shouldn't happen!"; - return false; - } - // HACK: Block ANGLE with Direct3D9 - // Direct3D9 does not give OpenGL ES 3.0 - // Some versions of ANGLE returns OpenGL version 3.0 incorrectly - if (checkResult.rendererString.contains("Direct3D9", Qt::CaseInsensitive)) { - qWarning() << "ANGLE tried to use Direct3D9, Krita won't work with it"; - return false; - } - return checkResult.isSupportedVersion(); - } - - void specialOpenGLVendorFilter(WindowsOpenGLStatus &status, const OpenGLCheckResult &checkResult) { - if (!status.supportsAngleD3D11) { - return; - } - // HACK: Make ANGLE the preferred renderer for Intel driver versions - // between build 4636 and 4729 (exclusive) due to an UI offset bug. - // See https://communities.intel.com/thread/116003 - // (Build 4636 is known to work from some test results) - if (checkResult.rendererString.startsWith("Intel")) { - QRegularExpression regex("\\b\\d{2}\\.\\d{2}\\.\\d{2}\\.(\\d{4})\\b"); - QRegularExpressionMatch match = regex.match(checkResult.driverVersionString); - if (match.hasMatch()) { - int driverBuild = match.captured(1).toInt(); - if (driverBuild > 4636 && driverBuild < 4729) { - qDebug() << "Detected Intel driver build between 4636 and 4729, making ANGLE the preferred renderer"; - status.overridePreferAngle = true; - } - } - } - } - -} // namespace - -/** - * This function probes the Qt Platform Abstraction (QPA) for OpenGL diagnostics - * information. The code works under the assumption that the bundled Qt is built - * with `-opengl dynamic` and includes support for ANGLE. - * - * This function is written for Qt 5.9.1. On other versions it might not work - * as well. - */ -void KisOpenGL::probeWindowsQpaOpenGL(int argc, char **argv, QString userRendererConfigString) -{ - KIS_SAFE_ASSERT_RECOVER(defaultFormatIsSet) { - qWarning() << "Default OpenGL format was not set before calling KisOpenGL::probeWindowsQpaOpenGL. This might be a BUG!"; - setDefaultFormat(); - } - - // Clear env var to prevent affecting tests - qunsetenv("QT_OPENGL"); - - boost::optional qpaDetectionResult; - - qDebug() << "Probing Qt OpenGL detection:"; - { - KisLoggingManager::ScopedLogCapturer logCapturer( - "qt.qpa.gl", - [](QtMsgType type, const QMessageLogContext &context, const QString &msg) { - Q_UNUSED(type) - Q_UNUSED(context) - qpaDetectionLog.append(msg); - } - ); - { - QGuiApplication app(argc, argv); - qpaDetectionResult = checkQpaOpenGLStatus(); - } - } - if (!qpaDetectionResult) { - qWarning() << "Could not initialize OpenGL context!"; +KisOpenGLPrivate::OpenGLCheckResult::OpenGLCheckResult(QOpenGLContext &context) { + if (!context.isValid()) { return; } - qDebug() << "Done probing Qt OpenGL detection"; - - windowsOpenGLStatus.isQtPreferAngle = qpaDetectionResult->isUsingAngle(); - - boost::optional checkResultAngle, checkResultDesktopGL; - if (qpaDetectionResult->isUsingAngle()) { - checkResultAngle = qpaDetectionResult; - // We already checked ANGLE, now check desktop OpenGL - qputenv("QT_OPENGL", "desktop"); - qDebug() << "Checking desktop OpenGL..."; - { - QGuiApplication app(argc, argv); - checkResultDesktopGL = checkQpaOpenGLStatus(); - } - if (!checkResultDesktopGL) { - qWarning() << "Could not initialize OpenGL context!"; - } - qDebug() << "Done checking desktop OpenGL"; - qunsetenv("QT_OPENGL"); - } else { - checkResultDesktopGL = qpaDetectionResult; - // We already checked desktop OpenGL, now check ANGLE - qputenv("QT_OPENGL", "angle"); - qDebug() << "Checking ANGLE..."; - { - QGuiApplication app(argc, argv); - checkResultAngle = checkQpaOpenGLStatus(); - } - if (!checkResultAngle) { - qWarning() << "Could not initialize OpenGL context!"; - } - qDebug() << "Done checking ANGLE"; - qunsetenv("QT_OPENGL"); - } - - windowsOpenGLStatus.supportsDesktopGL = - checkResultDesktopGL && checkIsSupportedDesktopGL(*checkResultDesktopGL); - windowsOpenGLStatus.supportsAngleD3D11 = - checkResultAngle && checkIsSupportedAngleD3D11(*checkResultAngle); - - // HACK: Filter specific buggy drivers not handled by Qt OpenGL buglist - if (checkResultDesktopGL) { - specialOpenGLVendorFilter(windowsOpenGLStatus, *checkResultDesktopGL); - } - - userRendererConfig = convertConfigToOpenGLRenderer(userRendererConfigString); - if ((userRendererConfig == RendererDesktopGL && !windowsOpenGLStatus.supportsDesktopGL) || - (userRendererConfig == RendererAngle && !windowsOpenGLStatus.supportsAngleD3D11)) { - // Set it to auto so we won't get stuck - userRendererConfig = RendererAuto; - } - nextUserRendererConfig = userRendererConfig; - switch (userRendererConfig) { - case RendererDesktopGL: - QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true); - currentRenderer = RendererDesktopGL; - break; - case RendererAngle: - QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); - currentRenderer = RendererAngle; - break; - default: - if (windowsOpenGLStatus.isQtPreferAngle && windowsOpenGLStatus.supportsAngleD3D11) { - currentRenderer = RendererAngle; - } else if (windowsOpenGLStatus.overridePreferAngle && windowsOpenGLStatus.supportsAngleD3D11) { - QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); - currentRenderer = RendererAngle; - } else if (!windowsOpenGLStatus.isQtPreferAngle && windowsOpenGLStatus.supportsDesktopGL) { - currentRenderer = RendererDesktopGL; - } else { - currentRenderer = RendererNone; - } - break; - } -} - -KisOpenGL::OpenGLRenderer KisOpenGL::getCurrentOpenGLRenderer() -{ - return currentRenderer; -} -KisOpenGL::OpenGLRenderer KisOpenGL::getQtPreferredOpenGLRenderer() -{ - return (windowsOpenGLStatus.isQtPreferAngle || windowsOpenGLStatus.overridePreferAngle) - ? RendererAngle : RendererDesktopGL; -} + QOpenGLFunctions *funcs = context.functions(); // funcs is ready to be used -KisOpenGL::OpenGLRenderers KisOpenGL::getSupportedOpenGLRenderers() -{ - return RendererAuto | - (windowsOpenGLStatus.supportsDesktopGL ? RendererDesktopGL : static_cast(0)) | - (windowsOpenGLStatus.supportsAngleD3D11 ? RendererAngle : static_cast(0)); + m_rendererString = QString(reinterpret_cast(funcs->glGetString(GL_RENDERER))); + m_driverVersionString = QString(reinterpret_cast(funcs->glGetString(GL_VERSION))); + m_glMajorVersion = context.format().majorVersion(); + m_glMinorVersion = context.format().minorVersion(); + m_supportsDeprecatedFunctions = (context.format().options() & QSurfaceFormat::DeprecatedFunctions); + m_isOpenGLES = context.isOpenGLES(); } -KisOpenGL::OpenGLRenderer KisOpenGL::getUserOpenGLRendererConfig() -{ - return userRendererConfig; +bool KisOpenGLPrivate::isDefaultFormatSet() { + return defaultFormatIsSet; } -KisOpenGL::OpenGLRenderer KisOpenGL::getNextUserOpenGLRendererConfig() -{ - return nextUserRendererConfig; -} - -void KisOpenGL::setNextUserOpenGLRendererConfig(KisOpenGL::OpenGLRenderer renderer) -{ - nextUserRendererConfig = renderer; -} - -QString KisOpenGL::convertOpenGLRendererToConfig(KisOpenGL::OpenGLRenderer renderer) -{ - switch (renderer) { - case RendererDesktopGL: - return QStringLiteral("desktop"); - case RendererAngle: - return QStringLiteral("angle"); - default: - return QStringLiteral("auto"); - } -} - -KisOpenGL::OpenGLRenderer KisOpenGL::convertConfigToOpenGLRenderer(QString renderer) -{ - if (renderer == "desktop") { - return RendererDesktopGL; - } else if (renderer == "angle") { - return RendererAngle; - } else { - return RendererAuto; - } -} -#endif - void KisOpenGL::initialize() { if (openGLCheckResult) return; KIS_SAFE_ASSERT_RECOVER(defaultFormatIsSet) { qWarning() << "Default OpenGL format was not set before calling KisOpenGL::initialize. This might be a BUG!"; setDefaultFormat(); } // we need a QSurface active to get our GL functions from the context QWindow surface; surface.setSurfaceType( QSurface::OpenGLSurface ); surface.create(); QOpenGLContext context; if (!context.create()) { qDebug() << "OpenGL context cannot be created"; return; } if (!context.isValid()) { qDebug() << "OpenGL context is not valid"; return; } if (!context.makeCurrent(&surface)) { qDebug() << "OpenGL context cannot be made current"; return; } QOpenGLFunctions *funcs = context.functions(); openGLCheckResult = OpenGLCheckResult(context); debugText.clear(); QDebug debugOut(&debugText); debugOut << "OpenGL Info"; debugOut << "\n Vendor: " << reinterpret_cast(funcs->glGetString(GL_VENDOR)); - debugOut << "\n Renderer: " << openGLCheckResult->rendererString; - debugOut << "\n Version: " << openGLCheckResult->driverVersionString; + debugOut << "\n Renderer: " << openGLCheckResult->rendererString(); + debugOut << "\n Version: " << openGLCheckResult->driverVersionString(); debugOut << "\n Shading language: " << reinterpret_cast(funcs->glGetString(GL_SHADING_LANGUAGE_VERSION)); debugOut << "\n Requested format: " << QSurfaceFormat::defaultFormat(); debugOut << "\n Current format: " << context.format(); debugOut.nospace(); - debugOut << "\n Version: " << openGLCheckResult->glMajorVersion << "." << openGLCheckResult->glMinorVersion; + debugOut << "\n Version: " << openGLCheckResult->glMajorVersion() << "." << openGLCheckResult->glMinorVersion(); debugOut.resetFormat(); - debugOut << "\n Supports deprecated functions" << openGLCheckResult->supportsDeprecatedFunctions; - debugOut << "\n is OpenGL ES:" << openGLCheckResult->isOpenGLES; -#ifdef Q_OS_WIN - debugOut << "\n\nQPA OpenGL Detection Info"; - debugOut << "\n supportsDesktopGL:" << windowsOpenGLStatus.supportsDesktopGL; - debugOut << "\n supportsAngleD3D11:" << windowsOpenGLStatus.supportsAngleD3D11; - debugOut << "\n isQtPreferAngle:" << windowsOpenGLStatus.isQtPreferAngle; - debugOut << "\n overridePreferAngle:" << windowsOpenGLStatus.overridePreferAngle; - debugOut << "\n== log ==\n"; - debugOut.noquote(); - debugOut << qpaDetectionLog.join('\n'); - debugOut.resetFormat(); - debugOut << "\n== end log =="; -#endif + debugOut << "\n Supports deprecated functions" << openGLCheckResult->supportsDeprecatedFunctions(); + debugOut << "\n is OpenGL ES:" << openGLCheckResult->isOpenGLES(); + appendPlatformOpenGLDebugText(debugOut); qDebug().noquote() << debugText; } void KisOpenGL::initializeContext(QOpenGLContext *ctx) { KisConfig cfg; initialize(); dbgUI << "OpenGL: Opening new context"; if (isDebugEnabled) { // Passing ctx for ownership management only, not specifying context. // QOpenGLDebugLogger only function on the current active context. // FIXME: Do we need to make sure ctx is the active context? QOpenGLDebugLogger* openglLogger = new QOpenGLDebugLogger(ctx); if (openglLogger->initialize()) { qDebug() << "QOpenGLDebugLogger is initialized. Check whether you get a message below."; QObject::connect(openglLogger, &QOpenGLDebugLogger::messageLogged, &openglOnMessageLogged); openglLogger->startLogging(isDebugSynchronous ? QOpenGLDebugLogger::SynchronousLogging : QOpenGLDebugLogger::AsynchronousLogging); openglLogger->logMessage(QOpenGLDebugMessage::createApplicationMessage(QStringLiteral("QOpenGLDebugLogger is logging."))); } else { qDebug() << "QOpenGLDebugLogger cannot be initialized."; delete openglLogger; } } // Double check we were given the version we requested QSurfaceFormat format = ctx->format(); QOpenGLFunctions *f = ctx->functions(); f->initializeOpenGLFunctions(); QFile log(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/krita-opengl.txt"); log.open(QFile::WriteOnly); QString vendor((const char*)f->glGetString(GL_VENDOR)); log.write(vendor.toLatin1()); log.write(", "); - log.write(openGLCheckResult->rendererString.toLatin1()); + log.write(openGLCheckResult->rendererString().toLatin1()); log.write(", "); QString version((const char*)f->glGetString(GL_VERSION)); log.write(version.toLatin1()); log.close(); // Check if we have a bugged driver that needs fence workaround bool isOnX11 = false; #ifdef HAVE_X11 isOnX11 = true; #endif - if ((isOnX11 && openGLCheckResult->rendererString.startsWith("AMD")) || cfg.forceOpenGLFenceWorkaround()) { + if ((isOnX11 && openGLCheckResult->rendererString().startsWith("AMD")) || cfg.forceOpenGLFenceWorkaround()) { NeedsFenceWorkaround = true; } /** * NVidia + Qt's openGL don't play well together and one cannot * draw a pixmap on a widget more than once in one rendering cycle. * * It can be workarounded by drawing strictly via QPixmapCache and * only when the pixmap size in bigger than doubled size of the * display framebuffer. That is for 8-bit HD display, you should have * a cache bigger than 16 MiB. Don't ask me why. (DK) * * See bug: https://bugs.kde.org/show_bug.cgi?id=361709 * * TODO: check if this workaround is still needed after merging * Qt5+openGL3 branch. */ if (vendor.toUpper().contains("NVIDIA")) { NeedsPixmapCacheWorkaround = true; const QRect screenSize = QApplication::desktop()->screenGeometry(); const int minCacheSize = 20 * 1024; const int cacheSize = 2048 + 2 * 4 * screenSize.width() * screenSize.height() / 1024; //KiB QPixmapCache::setCacheLimit(qMax(minCacheSize, cacheSize)); } } const QString &KisOpenGL::getDebugText() { initialize(); return debugText; } // XXX Temporary function to allow LoD on OpenGL3 without triggering // all of the other 3.2 functionality, can be removed once we move to Qt5.7 bool KisOpenGL::supportsLoD() { initialize(); return openGLCheckResult->supportsLoD(); } bool KisOpenGL::hasOpenGL3() { initialize(); return openGLCheckResult->hasOpenGL3(); } bool KisOpenGL::hasOpenGLES() { initialize(); - return openGLCheckResult->isOpenGLES; + return openGLCheckResult->isOpenGLES(); } bool KisOpenGL::supportsFenceSync() { initialize(); return openGLCheckResult->supportsFenceSync(); } bool KisOpenGL::needsFenceWorkaround() { initialize(); return NeedsFenceWorkaround; } bool KisOpenGL::needsPixmapCacheWorkaround() { initialize(); return NeedsPixmapCacheWorkaround; } void KisOpenGL::setDefaultFormat(bool enableDebug, bool debugSynchronous) { if (defaultFormatIsSet) { return; } defaultFormatIsSet = true; QSurfaceFormat format; #ifdef Q_OS_OSX format.setVersion(3, 2); format.setProfile(QSurfaceFormat::CoreProfile); #else // XXX This can be removed once we move to Qt5.7 format.setVersion(3, 0); format.setProfile(QSurfaceFormat::CompatibilityProfile); format.setOptions(QSurfaceFormat::DeprecatedFunctions); #endif format.setDepthBufferSize(24); format.setStencilBufferSize(8); format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); format.setSwapInterval(0); // Disable vertical refresh syncing isDebugEnabled = enableDebug; if (enableDebug) { format.setOption(QSurfaceFormat::DebugContext, true); isDebugSynchronous = debugSynchronous; qDebug() << "QOpenGLDebugLogger will be enabled, synchronous:" << debugSynchronous; } QSurfaceFormat::setDefaultFormat(format); } bool KisOpenGL::hasOpenGL() { return openGLCheckResult->isSupportedVersion(); } diff --git a/libs/ui/opengl/kis_opengl.h b/libs/ui/opengl/kis_opengl.h index 4d3e20d52f..e87c41fe21 100644 --- a/libs/ui/opengl/kis_opengl.h +++ b/libs/ui/opengl/kis_opengl.h @@ -1,116 +1,114 @@ /* * Copyright (c) 2007 Adrian Page * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIS_OPENGL_H_ #define KIS_OPENGL_H_ /** @file */ -#include - #include #include -class QOpenGLContext; -class QString; #include "kritaui_export.h" +class QOpenGLContext; +class QString; /** * This class manages a shared OpenGL context and provides utility * functions for checking capabilities and error reporting. */ class KRITAUI_EXPORT KisOpenGL { public: enum FilterMode { NearestFilterMode, // nearest BilinearFilterMode, // linear, no mipmap TrilinearFilterMode, // LINEAR_MIPMAP_LINEAR HighQualityFiltering // Mipmaps + custom shader }; public: #ifdef Q_OS_WIN enum OpenGLRenderer { RendererNone = 0x00, RendererAuto = 0x01, RendererDesktopGL = 0x02, RendererAngle = 0x04, }; Q_DECLARE_FLAGS(OpenGLRenderers, OpenGLRenderer); // Probe the Windows platform abstraction layer for OpenGL detection static void probeWindowsQpaOpenGL(int argc, char **argv, QString userRendererConfigString); static OpenGLRenderer getCurrentOpenGLRenderer(); static OpenGLRenderer getQtPreferredOpenGLRenderer(); static OpenGLRenderers getSupportedOpenGLRenderers(); static OpenGLRenderer getUserOpenGLRendererConfig(); static OpenGLRenderer getNextUserOpenGLRendererConfig(); static void setNextUserOpenGLRendererConfig(OpenGLRenderer renderer); static QString convertOpenGLRendererToConfig(OpenGLRenderer renderer); static OpenGLRenderer convertConfigToOpenGLRenderer(QString renderer); #endif /// Request OpenGL version 3.2 static void initialize(); /// Initialize shared OpenGL context static void initializeContext(QOpenGLContext *ctx); static const QString &getDebugText(); static bool supportsLoD(); static bool hasOpenGL3(); static bool hasOpenGLES(); /// Check for OpenGL static bool hasOpenGL(); /** * @brief supportsFilter * @return True if OpenGL provides fence sync methods. */ static bool supportsFenceSync(); /** * Returns true if we have a driver that has bugged support to sync objects (a fence) * and false otherwise. */ static bool needsFenceWorkaround(); /** * @see a comment in initializeContext() */ static bool needsPixmapCacheWorkaround(); static void setDefaultFormat(bool enableDebug = false, bool debugSynchronous = false); private: KisOpenGL(); }; #ifdef Q_OS_WIN Q_DECLARE_OPERATORS_FOR_FLAGS(KisOpenGL::OpenGLRenderers); #endif #endif // KIS_OPENGL_H_ diff --git a/libs/ui/opengl/kis_opengl_p.h b/libs/ui/opengl/kis_opengl_p.h new file mode 100644 index 0000000000..2fd47b6601 --- /dev/null +++ b/libs/ui/opengl/kis_opengl_p.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017 Alvin Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KIS_OPENGL_P_H_ +#define KIS_OPENGL_P_H_ + +#include +#include + +class QDebug; +class QOpenGLContext; + +namespace KisOpenGLPrivate +{ + +class OpenGLCheckResult { + int m_glMajorVersion = 0; + int m_glMinorVersion = 0; + bool m_supportsDeprecatedFunctions = false; + bool m_isOpenGLES = false; + QString m_rendererString; + QString m_driverVersionString; + +public: + OpenGLCheckResult(QOpenGLContext &context); + + int glMajorVersion() const { + return m_glMajorVersion; + } + + int glMinorVersion() const { + return m_glMinorVersion; + } + + bool supportsDeprecatedFunctions() const { + return m_supportsDeprecatedFunctions; + } + + bool isOpenGLES() const { + return m_isOpenGLES; + } + + QString rendererString() const { + return m_rendererString; + } + + QString driverVersionString() const { + return m_driverVersionString; + } + + bool isSupportedVersion() const { + return +#ifdef Q_OS_OSX + ((m_glMajorVersion * 100 + m_glMinorVersion) >= 302) +#else + (m_glMajorVersion >= 3 && (m_supportsDeprecatedFunctions || m_isOpenGLES)) || + ((m_glMajorVersion * 100 + m_glMinorVersion) == 201) +#endif + ; + } + + bool supportsLoD() const { + return (m_glMajorVersion * 100 + m_glMinorVersion) >= 300; + } + + bool hasOpenGL3() const { + return (m_glMajorVersion * 100 + m_glMinorVersion) >= 302; + } + + bool supportsFenceSync() const { + return m_glMajorVersion >= 3; + } + +#ifdef Q_OS_WIN + // This is only for detecting whether ANGLE is being used. + // For detecting generic OpenGL ES please check isOpenGLES + bool isUsingAngle() const { + return m_rendererString.startsWith("ANGLE", Qt::CaseInsensitive); + } +#endif +}; + +void appendPlatformOpenGLDebugText(QDebug &debugOut); +#ifndef Q_OS_WIN +void appendPlatformOpenGLDebugText(QDebug &debugOut) {} +#endif + +bool isDefaultFormatSet(); + +} // namespace KisOpenGLPrivate + +#endif // KIS_OPENGL_P_H_ diff --git a/libs/ui/opengl/kis_opengl_win.cpp b/libs/ui/opengl/kis_opengl_win.cpp new file mode 100644 index 0000000000..2843f9c225 --- /dev/null +++ b/libs/ui/opengl/kis_opengl_win.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2017 Alvin Wong + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "opengl/kis_opengl.h" +#include "opengl/kis_opengl_p.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +using namespace KisOpenGLPrivate; + +namespace +{ + +struct WindowsOpenGLStatus { + bool supportsDesktopGL = false; + bool supportsAngleD3D11 = false; + bool isQtPreferAngle = false; + bool overridePreferAngle = false; // override Qt to force ANGLE to be preferred +}; +WindowsOpenGLStatus windowsOpenGLStatus = {}; +KisOpenGL::OpenGLRenderer userRendererConfig; +KisOpenGL::OpenGLRenderer nextUserRendererConfig; +KisOpenGL::OpenGLRenderer currentRenderer; + +QStringList qpaDetectionLog; + +boost::optional checkQpaOpenGLStatus() { + QWindow surface; + surface.setSurfaceType(QSurface::OpenGLSurface); + surface.create(); + QOpenGLContext context; + if (!context.create()) { + qDebug() << "OpenGL context cannot be created"; + return boost::none; + } + if (!context.isValid()) { + qDebug() << "OpenGL context is not valid while checking Qt's OpenGL status"; + return boost::none; + } + if (!context.makeCurrent(&surface)) { + qDebug() << "OpenGL context cannot be made current"; + return boost::none; + } + return OpenGLCheckResult(context); +} + +bool checkIsSupportedDesktopGL(const OpenGLCheckResult &checkResult) { + if (checkResult.isUsingAngle()) { + qWarning() << "ANGLE was being used when desktop OpenGL was wanted, assuming no desktop OpenGL support"; + return false; + } + if (checkResult.isOpenGLES()) { + qWarning() << "Got OpenGL ES instead of desktop OpenGL, this shouldn't happen!"; + return false; + } + return checkResult.isSupportedVersion(); +} + +bool checkIsSupportedAngleD3D11(const OpenGLCheckResult &checkResult) { + if (!checkResult.isUsingAngle()) { + qWarning() << "Desktop OpenGL was being used when ANGLE was wanted, assuming no ANGLE support"; + return false; + } + if (!checkResult.isOpenGLES()) { + qWarning() << "Got desktop OpenGL instead of OpenGL ES, this shouldn't happen!"; + return false; + } + // HACK: Block ANGLE with Direct3D9 + // Direct3D9 does not give OpenGL ES 3.0 + // Some versions of ANGLE returns OpenGL version 3.0 incorrectly + if (checkResult.rendererString().contains("Direct3D9", Qt::CaseInsensitive)) { + qWarning() << "ANGLE tried to use Direct3D9, Krita won't work with it"; + return false; + } + return checkResult.isSupportedVersion(); +} + +void specialOpenGLVendorFilter(WindowsOpenGLStatus &status, const OpenGLCheckResult &checkResult) { + if (!status.supportsAngleD3D11) { + return; + } + // HACK: Make ANGLE the preferred renderer for Intel driver versions + // between build 4636 and 4729 (exclusive) due to an UI offset bug. + // See https://communities.intel.com/thread/116003 + // (Build 4636 is known to work from some test results) + if (checkResult.rendererString().startsWith("Intel")) { + QRegularExpression regex("\\b\\d{2}\\.\\d{2}\\.\\d{2}\\.(\\d{4})\\b"); + QRegularExpressionMatch match = regex.match(checkResult.driverVersionString()); + if (match.hasMatch()) { + int driverBuild = match.captured(1).toInt(); + if (driverBuild > 4636 && driverBuild < 4729) { + qDebug() << "Detected Intel driver build between 4636 and 4729, making ANGLE the preferred renderer"; + status.overridePreferAngle = true; + } + } + } +} + +} // namespace + +void KisOpenGLPrivate::appendPlatformOpenGLDebugText(QDebug &debugOut) { + debugOut << "\n\nQPA OpenGL Detection Info"; + debugOut << "\n supportsDesktopGL:" << windowsOpenGLStatus.supportsDesktopGL; + debugOut << "\n supportsAngleD3D11:" << windowsOpenGLStatus.supportsAngleD3D11; + debugOut << "\n isQtPreferAngle:" << windowsOpenGLStatus.isQtPreferAngle; + debugOut << "\n overridePreferAngle:" << windowsOpenGLStatus.overridePreferAngle; + debugOut << "\n== log ==\n"; + debugOut.noquote(); + debugOut << qpaDetectionLog.join('\n'); + debugOut.resetFormat(); + debugOut << "\n== end log =="; +} + +/** + * This function probes the Qt Platform Abstraction (QPA) for OpenGL diagnostics + * information. The code works under the assumption that the bundled Qt is built + * with `-opengl dynamic` and includes support for ANGLE. + * + * This function is written for Qt 5.9.1. On other versions it might not work + * as well. + */ +void KisOpenGL::probeWindowsQpaOpenGL(int argc, char **argv, QString userRendererConfigString) +{ + KIS_SAFE_ASSERT_RECOVER(isDefaultFormatSet()) { + qWarning() << "Default OpenGL format was not set before calling KisOpenGL::probeWindowsQpaOpenGL. This might be a BUG!"; + setDefaultFormat(); + } + + // Clear env var to prevent affecting tests + qunsetenv("QT_OPENGL"); + + boost::optional qpaDetectionResult; + + qDebug() << "Probing Qt OpenGL detection:"; + { + KisLoggingManager::ScopedLogCapturer logCapturer( + "qt.qpa.gl", + [](QtMsgType type, const QMessageLogContext &context, const QString &msg) { + Q_UNUSED(type) + Q_UNUSED(context) + qpaDetectionLog.append(msg); + } + ); + { + QGuiApplication app(argc, argv); + qpaDetectionResult = checkQpaOpenGLStatus(); + } + } + if (!qpaDetectionResult) { + qWarning() << "Could not initialize OpenGL context!"; + return; + } + qDebug() << "Done probing Qt OpenGL detection"; + + windowsOpenGLStatus.isQtPreferAngle = qpaDetectionResult->isUsingAngle(); + + boost::optional checkResultAngle, checkResultDesktopGL; + if (qpaDetectionResult->isUsingAngle()) { + checkResultAngle = qpaDetectionResult; + // We already checked ANGLE, now check desktop OpenGL + qputenv("QT_OPENGL", "desktop"); + qDebug() << "Checking desktop OpenGL..."; + { + QGuiApplication app(argc, argv); + checkResultDesktopGL = checkQpaOpenGLStatus(); + } + if (!checkResultDesktopGL) { + qWarning() << "Could not initialize OpenGL context!"; + } + qDebug() << "Done checking desktop OpenGL"; + qunsetenv("QT_OPENGL"); + } else { + checkResultDesktopGL = qpaDetectionResult; + // We already checked desktop OpenGL, now check ANGLE + qputenv("QT_OPENGL", "angle"); + qDebug() << "Checking ANGLE..."; + { + QGuiApplication app(argc, argv); + checkResultAngle = checkQpaOpenGLStatus(); + } + if (!checkResultAngle) { + qWarning() << "Could not initialize OpenGL context!"; + } + qDebug() << "Done checking ANGLE"; + qunsetenv("QT_OPENGL"); + } + + windowsOpenGLStatus.supportsDesktopGL = + checkResultDesktopGL && checkIsSupportedDesktopGL(*checkResultDesktopGL); + windowsOpenGLStatus.supportsAngleD3D11 = + checkResultAngle && checkIsSupportedAngleD3D11(*checkResultAngle); + + // HACK: Filter specific buggy drivers not handled by Qt OpenGL buglist + if (checkResultDesktopGL) { + specialOpenGLVendorFilter(windowsOpenGLStatus, *checkResultDesktopGL); + } + + userRendererConfig = convertConfigToOpenGLRenderer(userRendererConfigString); + if ((userRendererConfig == RendererDesktopGL && !windowsOpenGLStatus.supportsDesktopGL) || + (userRendererConfig == RendererAngle && !windowsOpenGLStatus.supportsAngleD3D11)) { + // Set it to auto so we won't get stuck + userRendererConfig = RendererAuto; + } + nextUserRendererConfig = userRendererConfig; + switch (userRendererConfig) { + case RendererDesktopGL: + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true); + currentRenderer = RendererDesktopGL; + break; + case RendererAngle: + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); + currentRenderer = RendererAngle; + break; + default: + if (windowsOpenGLStatus.isQtPreferAngle && windowsOpenGLStatus.supportsAngleD3D11) { + currentRenderer = RendererAngle; + } else if (windowsOpenGLStatus.overridePreferAngle && windowsOpenGLStatus.supportsAngleD3D11) { + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); + currentRenderer = RendererAngle; + } else if (!windowsOpenGLStatus.isQtPreferAngle && windowsOpenGLStatus.supportsDesktopGL) { + currentRenderer = RendererDesktopGL; + } else { + currentRenderer = RendererNone; + } + break; + } +} + +KisOpenGL::OpenGLRenderer KisOpenGL::getCurrentOpenGLRenderer() +{ + return currentRenderer; +} + +KisOpenGL::OpenGLRenderer KisOpenGL::getQtPreferredOpenGLRenderer() +{ + return (windowsOpenGLStatus.isQtPreferAngle || windowsOpenGLStatus.overridePreferAngle) + ? RendererAngle : RendererDesktopGL; +} + +KisOpenGL::OpenGLRenderers KisOpenGL::getSupportedOpenGLRenderers() +{ + return RendererAuto | + (windowsOpenGLStatus.supportsDesktopGL ? RendererDesktopGL : static_cast(0)) | + (windowsOpenGLStatus.supportsAngleD3D11 ? RendererAngle : static_cast(0)); +} + +KisOpenGL::OpenGLRenderer KisOpenGL::getUserOpenGLRendererConfig() +{ + return userRendererConfig; +} + +KisOpenGL::OpenGLRenderer KisOpenGL::getNextUserOpenGLRendererConfig() +{ + return nextUserRendererConfig; +} + +void KisOpenGL::setNextUserOpenGLRendererConfig(KisOpenGL::OpenGLRenderer renderer) +{ + nextUserRendererConfig = renderer; +} + +QString KisOpenGL::convertOpenGLRendererToConfig(KisOpenGL::OpenGLRenderer renderer) +{ + switch (renderer) { + case RendererDesktopGL: + return QStringLiteral("desktop"); + case RendererAngle: + return QStringLiteral("angle"); + default: + return QStringLiteral("auto"); + } +} + +KisOpenGL::OpenGLRenderer KisOpenGL::convertConfigToOpenGLRenderer(QString renderer) +{ + if (renderer == "desktop") { + return RendererDesktopGL; + } else if (renderer == "angle") { + return RendererAngle; + } else { + return RendererAuto; + } +} diff --git a/plugins/extensions/pykrita/plugin/plugins/tenscripts/kritapykrita_tenscripts.desktop b/plugins/extensions/pykrita/plugin/plugins/tenscripts/kritapykrita_tenscripts.desktop index d96e4a02b3..a79a0b01aa 100644 --- a/plugins/extensions/pykrita/plugin/plugins/tenscripts/kritapykrita_tenscripts.desktop +++ b/plugins/extensions/pykrita/plugin/plugins/tenscripts/kritapykrita_tenscripts.desktop @@ -1,7 +1,20 @@ [Desktop Entry] Type=Service ServiceTypes=Krita/PythonPlugin X-KDE-Library=tenscripts X-Python-2-Compatible=false Name=Ten Scripts +Name[ca]=Deu scripts +Name[en_GB]=Ten Scripts +Name[nl]=Tien scripts +Name[pt]=Dez Programas +Name[sv]=Tio skript +Name[uk]=Десять скриптів +Name[x-test]=xxTen Scriptsxx Comment=A Python-based plugin for creating ten actions and assign them to Python scripts +Comment[ca]=Un connector basant en el Python per crear deu accions i assignar-les a scripts del Python +Comment[en_GB]=A Python-based plugin for creating ten actions and assign them to Python scripts +Comment[nl]=Een op Python gebaseerde plug-in voor aanmaken van tien acties en ze dan toewijzen aan Python-scripts +Comment[sv]=Ett Python-baserat insticksprogram för att skapa tio åtgärder och tilldela dem till Python-skript +Comment[uk]=Скрипт на основі Python для створення десяти дій і прив'язування до них скриптів Python +Comment[x-test]=xxA Python-based plugin for creating ten actions and assign them to Python scriptsxx