diff --git a/direct/src/dist/FreezeTool.py b/direct/src/dist/FreezeTool.py index b9be5933f7..678f8c0888 100644 --- a/direct/src/dist/FreezeTool.py +++ b/direct/src/dist/FreezeTool.py @@ -1948,6 +1948,9 @@ class Freezer: if self.platform.startswith('win'): # We don't use mmap on Windows. Align just for good measure. blob_align = 32 + elif self.platform.endswith('_aarch64') or self.platform.endswith('_arm64'): + # Most arm64 operating systems are configured with 16 KiB pages. + blob_align = 16384 else: # Align to page size, so that it can be mmapped. blob_align = 4096 diff --git a/direct/src/wxwidgets/WxSlider.py b/direct/src/wxwidgets/WxSlider.py index 5f504c8896..d92a28e206 100755 --- a/direct/src/wxwidgets/WxSlider.py +++ b/direct/src/wxwidgets/WxSlider.py @@ -16,7 +16,7 @@ class WxSlider(wx.Slider): self.maxValue = maxValue self.minValue = minValue - intVal = 100.0 / (self.maxValue - self.minValue) * (value - self.minValue) + intVal = int(100.0 / (self.maxValue - self.minValue) * (value - self.minValue)) intMin = 0 intMax = 100 @@ -35,33 +35,37 @@ class WxSlider(wx.Slider): textSize, wx.TE_CENTER | wx.TE_PROCESS_ENTER) self.textValue.Disable() - newPos = (pos[0], pos[1] + 20) + pos = (pos[0], pos[1] + 20) else: newStyle = wx.SL_VERTICAL - newPos = (pos[0], pos[1] + 40) + pos = (pos[0], pos[1] + 40) if style & wx.SL_AUTOTICKS: newStyle |= wx.SL_AUTOTICKS - wx.Slider.__init__(self, parent, id, intVal, intMin, intMax, newPos, size, style=newStyle) + wx.Slider.__init__(self, parent, id, intVal, intMin, intMax, pos, size, style=newStyle) self.Disable() def GetValue(self): # overriding wx.Slider.GetValue() - #return (wx.Slider.GetValue(self) * (self.maxValue - self.minValue) / 100.0 + self.minValue) - return float(self.textValue.GetValue()) # [gjeon] since the value from the slider is not as precise as the value entered by the user + if self.textValue is not None: # Horizontal with labels + return float(self.textValue.GetValue()) # [gjeon] since the value from the slider is not as precise as the value entered by the user + else: + return (wx.Slider.GetValue(self) * (self.maxValue - self.minValue) / 100.0 + self.minValue) def SetValue(self, value): # overriding wx.Slider.SetValue() - self.textValue.SetValue("%.2f" % value) + if self.textValue is not None: + self.textValue.SetValue("%.2f" % value) intVal = 100.0 / (self.maxValue - self.minValue) * (value - self.minValue) wx.Slider.SetValue(self, intVal) def onChange(self, event): # update textValue from slider - self.textValue.Clear() - floatVal = wx.Slider.GetValue(self) * (self.maxValue - self.minValue) / 100.0 + self.minValue - self.textValue.WriteText("%.2f" % floatVal) + if self.textValue is not None: + self.textValue.Clear() + floatVal = wx.Slider.GetValue(self) * (self.maxValue - self.minValue) / 100.0 + self.minValue + self.textValue.WriteText("%.2f" % floatVal) if self.updateCB: # callback function sould receive event as the argument self.updateCB(event) event.Skip() @@ -82,13 +86,14 @@ class WxSlider(wx.Slider): def Disable(self): # overriding wx.Slider.Disable() wx.Slider.Disable(self) - self.textValue.Disable() + if self.textValue is not None: + self.textValue.Disable() def Enable(self): # overriding wx.Slider.Enable() wx.Slider.Enable(self) self.Bind(wx.EVT_SLIDER, self.onChange) - if not self.textValue is None: + if self.textValue is not None: self.textValue.Enable() self.textValue.Bind(wx.EVT_TEXT_ENTER, self.onEnter) diff --git a/panda/src/cocoadisplay/cocoaGraphicsPipe.mm b/panda/src/cocoadisplay/cocoaGraphicsPipe.mm index ea86753305..3734f37af8 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsPipe.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsPipe.mm @@ -105,11 +105,19 @@ load_display_information() { &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); size_t num_modes = 0; + int32_t current_mode_id = -1; CFArrayRef modes = CGDisplayCopyAllDisplayModes(_display, options); if (modes != NULL) { num_modes = CFArrayGetCount(modes); _display_information->_total_display_modes = num_modes; _display_information->_display_mode_array = new DisplayMode[num_modes]; + + // Get information about the current mode. + CGDisplayModeRef mode = CGDisplayCopyDisplayMode(_display); + if (mode) { + current_mode_id = CGDisplayModeGetIODisplayModeID(mode); + CGDisplayModeRelease(mode); + } } if (options != NULL) { CFRelease(options); @@ -153,6 +161,14 @@ load_display_information() { // pixel can be deduced from the string length. Nifty! _display_information->_display_mode_array[i].bits_per_pixel = CFStringGetLength(encoding); } + + if (current_mode_id >= 0 && current_mode_id == CGDisplayModeGetIODisplayModeID(mode)) { + _display_information->_current_display_mode_index = i; + + // Stop checking + current_mode_id = -1; + } + CFRelease(encoding); } if (modes != nullptr) { diff --git a/panda/src/display/displayInformation.cxx b/panda/src/display/displayInformation.cxx index 0253b7a7c3..8f758f6f58 100644 --- a/panda/src/display/displayInformation.cxx +++ b/panda/src/display/displayInformation.cxx @@ -75,7 +75,6 @@ DisplayInformation:: DisplayInformation:: DisplayInformation() { DisplayInformation::DetectionState state; - int get_adapter_display_mode_state; int get_device_caps_state; int window_width; int window_height; @@ -88,7 +87,6 @@ DisplayInformation() { uint64_t available_physical_memory; state = DisplayInformation::DS_unknown; - get_adapter_display_mode_state = false; get_device_caps_state = false; window_width = 0; window_height = 0; @@ -101,7 +99,7 @@ DisplayInformation() { available_physical_memory = 0; _state = state; - _get_adapter_display_mode_state = get_adapter_display_mode_state; + _current_display_mode_index = -1; _get_device_caps_state = get_device_caps_state; _maximum_window_width = window_width; _maximum_window_height = window_height; @@ -209,6 +207,16 @@ get_display_mode(int display_index) { return _display_mode_array[display_index]; } +/** + * Returns the index of the current display mode (determined at the time of + * application start) in the display mode array, or -1 if this could not be + * determined. + */ +int DisplayInformation:: +get_current_display_mode_index() const { + return _current_display_mode_index; +} + /** * @deprecated use get_display_mode instead. */ diff --git a/panda/src/display/displayInformation.h b/panda/src/display/displayInformation.h index fc3c1ea35a..e2ffe1fc6c 100644 --- a/panda/src/display/displayInformation.h +++ b/panda/src/display/displayInformation.h @@ -56,6 +56,8 @@ PUBLISHED: const DisplayMode &get_display_mode(int display_index); MAKE_SEQ(get_display_modes, get_total_display_modes, get_display_mode); + int get_current_display_mode_index() const; + // Older interface for display modes. int get_display_mode_width(int display_index); int get_display_mode_height(int display_index); @@ -115,7 +117,7 @@ PUBLISHED: public: DetectionState _state; - int _get_adapter_display_mode_state; + int _current_display_mode_index; int _get_device_caps_state; int _maximum_window_width; int _maximum_window_height; diff --git a/panda/src/windisplay/winDetectDx.h b/panda/src/windisplay/winDetectDx.h index a6da2e143f..4b659cb135 100644 --- a/panda/src/windisplay/winDetectDx.h +++ b/panda/src/windisplay/winDetectDx.h @@ -99,7 +99,6 @@ static int get_display_information (DisplaySearchParameters &display_search_para int success; DisplayInformation::DetectionState state; - int get_adapter_display_mode_state; int get_device_caps_state; GraphicsStateGuardian::ShaderModel shader_model; @@ -117,6 +116,7 @@ static int get_display_information (DisplaySearchParameters &display_search_para int window_height; int window_bits_per_pixel; int total_display_modes; + int current_display_mode_index; DisplayMode *display_mode_array; uint64_t physical_memory; @@ -139,6 +139,7 @@ static int get_display_information (DisplaySearchParameters &display_search_para window_height = 0; window_bits_per_pixel = 0; total_display_modes = 0; + current_display_mode_index = -1; display_mode_array = nullptr; minimum_width = display_search_parameters._minimum_width; @@ -153,7 +154,6 @@ static int get_display_information (DisplaySearchParameters &display_search_para texture_memory = 0; state = DisplayInformation::DS_unknown; - get_adapter_display_mode_state = false; get_device_caps_state = false; physical_memory = 0; @@ -193,6 +193,7 @@ static int get_display_information (DisplaySearchParameters &display_search_para device_type = D3DDEVTYPE_HAL; // windowed mode max res and format + bool get_adapter_display_mode_state = false; if (direct_3d -> GetAdapterDisplayMode (adapter, ¤t_d3d_display_mode) == D3D_OK) { if (debug) { printf ("current mode w = %d h = %d r = %d f = %d \n", @@ -428,6 +429,14 @@ static int get_display_information (DisplaySearchParameters &display_search_para display_mode -> refresh_rate = d3d_display_mode.RefreshRate; display_mode -> fullscreen_only = display_format_array [format_index].fullscreen_only; + if (get_adapter_display_mode_state && + d3d_display_mode.Width == current_d3d_display_mode.Width && + d3d_display_mode.Height == current_d3d_display_mode.Height && + d3d_display_mode.RefreshRate == current_d3d_display_mode.RefreshRate && + d3d_display_mode.Format == current_d3d_display_mode.Format) { + current_display_mode_index = total_display_modes; + } + total_display_modes++; } } @@ -587,7 +596,7 @@ static int get_display_information (DisplaySearchParameters &display_search_para if (success) { display_information -> _state = state; - display_information -> _get_adapter_display_mode_state = get_adapter_display_mode_state; + display_information -> _current_display_mode_index = current_display_mode_index; display_information -> _get_device_caps_state = get_device_caps_state; display_information -> _maximum_window_width = window_width; display_information -> _maximum_window_height = window_height; diff --git a/panda/src/windisplay/winGraphicsPipe.cxx b/panda/src/windisplay/winGraphicsPipe.cxx index 28787c43b3..428040f0f6 100644 --- a/panda/src/windisplay/winGraphicsPipe.cxx +++ b/panda/src/windisplay/winGraphicsPipe.cxx @@ -328,9 +328,21 @@ WinGraphicsPipe() { if (windisplay_cat.is_debug()) { windisplay_cat.debug() << "Using EnumDisplaySettings to fetch display information.\n"; } + pvector display_modes; + DisplayMode current_mode = {0}; + int current_mode_index = -1; DEVMODE dm{}; dm.dmSize = sizeof(dm); + + if (EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dm) != 0) { + current_mode.width = dm.dmPelsWidth; + current_mode.height = dm.dmPelsHeight; + current_mode.bits_per_pixel = dm.dmBitsPerPel; + current_mode.refresh_rate = dm.dmDisplayFrequency; + current_mode.fullscreen_only = 0; + } + for (int i = 0; EnumDisplaySettings(nullptr, i, &dm) != 0; ++i) { DisplayMode mode; mode.width = dm.dmPelsWidth; @@ -339,6 +351,9 @@ WinGraphicsPipe() { mode.refresh_rate = dm.dmDisplayFrequency; mode.fullscreen_only = 0; if (i == 0 || mode != display_modes.back()) { + if (current_mode_index < 0 && mode == current_mode) { + current_mode_index = (int)display_modes.size(); + } display_modes.push_back(mode); } } @@ -346,6 +361,7 @@ WinGraphicsPipe() { // Copy this information to the DisplayInformation object. _display_information->_total_display_modes = display_modes.size(); if (!display_modes.empty()) { + _display_information->_current_display_mode_index = current_mode_index; _display_information->_display_mode_array = new DisplayMode[display_modes.size()]; std::copy(display_modes.begin(), display_modes.end(), _display_information->_display_mode_array); diff --git a/panda/src/x11display/x11GraphicsPipe.cxx b/panda/src/x11display/x11GraphicsPipe.cxx index bfbacfc972..1f74c64fdb 100644 --- a/panda/src/x11display/x11GraphicsPipe.cxx +++ b/panda/src/x11display/x11GraphicsPipe.cxx @@ -283,11 +283,25 @@ x11GraphicsPipe(const std::string &display) : x11display_cat.debug() << "Using XRRScreenResources to obtain display modes\n"; } + + // Query current configuration, we just grab the first CRTC for now, + // since we don't have a way to represent multiple monitors. + RRMode current_mode_id = 0; + if (res->ncrtc > 0) { + if (auto info = get_crtc_info(res.get(), res->crtcs[0])) { + current_mode_id = info->mode; + } + } + _display_information->_total_display_modes = res->nmode; _display_information->_display_mode_array = new DisplayMode[res->nmode]; for (int i = 0; i < res->nmode; ++i) { XRRModeInfo &mode = res->modes[i]; + if (mode.id == current_mode_id) { + _display_information->_current_display_mode_index = i; + } + DisplayMode *dm = _display_information->_display_mode_array + i; dm->width = mode.width; dm->height = mode.height; diff --git a/pandatool/src/assimp/loaderFileTypeAssimp.cxx b/pandatool/src/assimp/loaderFileTypeAssimp.cxx index f19ce58e2f..80e9793431 100644 --- a/pandatool/src/assimp/loaderFileTypeAssimp.cxx +++ b/pandatool/src/assimp/loaderFileTypeAssimp.cxx @@ -57,22 +57,49 @@ get_extension() const { */ string LoaderFileTypeAssimp:: get_additional_extensions() const { + // This may be called at static init time, so ensure it is constructed now. + static ConfigVariableString assimp_disable_extensions + ("assimp-disable-extensions", "", + PRC_DESC("A list of extensions (without preceding dot) that should not be " + "loaded via the Assimp loader, even if Assimp supports these " + "formats. It is useful to set this for eg. gltf and glb files " + "to prevent them from being accidentally loaded via the Assimp " + "plug-in instead of via a superior plug-in like panda3d-gltf.")); + + bool has_disabled_exts = !assimp_disable_extensions.empty(); + aiString aexts; aiGetExtensionList(&aexts); + char *buffer = (char *)alloca(aexts.length + 2); + char *p = buffer; + // The format is like: *.mdc;*.mdl;*.mesh.xml;*.mot - std::string ext; char *sub = strtok(aexts.data, ";"); while (sub != nullptr) { - ext += sub + 2; - sub = strtok(nullptr, ";"); - - if (sub != nullptr) { - ext += ' '; + bool enabled = true; + if (has_disabled_exts) { + for (size_t i = 0; i < assimp_disable_extensions.get_num_words(); ++i) { + std::string disabled_ext = assimp_disable_extensions.get_word(i); + if (strcmp(sub + 2, disabled_ext.c_str()) == 0) { + enabled = false; + break; + } + } } + if (enabled) { + *(p++) = ' '; + size_t len = strlen(sub + 2); + memcpy(p, sub + 2, len); + p += len; + } + + sub = strtok(nullptr, ";"); } - return ext; + // Strip first space + ++buffer; + return std::string(buffer, p - buffer); } /**