feat: Add EDR support to Metal and all Apple platforms
This commit is contained in:
parent
923c751af4
commit
d5504ffc69
24 changed files with 912 additions and 450 deletions
|
|
@ -2751,7 +2751,7 @@
|
|||
Display server supports interaction with screen reader or Braille display. [b]Linux (X11/Wayland), macOS, Windows[/b]
|
||||
</constant>
|
||||
<constant name="FEATURE_HDR_OUTPUT" value="35" enum="Feature">
|
||||
Display server supports HDR output. [b]Windows[/b]
|
||||
Display server supports HDR output. [b]macOS, iOS, visionOS, Windows[/b]
|
||||
</constant>
|
||||
<constant name="ROLE_UNKNOWN" value="0" enum="AccessibilityRole">
|
||||
Unknown or custom role.
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
class InputEvent;
|
||||
class NativeMenu;
|
||||
|
||||
/// "Embedded" as in "Embedded Device".
|
||||
class DisplayServerAppleEmbedded : public DisplayServer {
|
||||
GDSOFTCLASS(DisplayServerAppleEmbedded, DisplayServer);
|
||||
|
||||
|
|
@ -87,7 +88,16 @@ class DisplayServerAppleEmbedded : public DisplayServer {
|
|||
|
||||
void initialize_tts() const;
|
||||
|
||||
bool edr_requested = false;
|
||||
void _update_hdr_output();
|
||||
float _calculate_current_reference_luminance() const;
|
||||
|
||||
protected:
|
||||
virtual bool _screen_hdr_is_supported() const { return false; }
|
||||
virtual float _screen_potential_edr_headroom() const { return 1.0f; }
|
||||
virtual float _screen_current_edr_headroom() const { return 1.0f; }
|
||||
float hardware_reference_luminance_nits = 100.0f;
|
||||
|
||||
DisplayServerAppleEmbedded(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
|
||||
~DisplayServerAppleEmbedded();
|
||||
|
||||
|
|
@ -230,6 +240,24 @@ public:
|
|||
virtual void screen_set_keep_on(bool p_enable) override;
|
||||
virtual bool screen_is_kept_on() const override;
|
||||
|
||||
// MARK: - HDR / EDR
|
||||
|
||||
void current_edr_headroom_changed();
|
||||
virtual bool window_is_hdr_output_supported(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
virtual void window_request_hdr_output(const bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual bool window_is_hdr_output_requested(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
virtual bool window_is_hdr_output_enabled(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
virtual void window_set_hdr_output_reference_luminance(const float p_reference_luminance, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual float window_get_hdr_output_reference_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
virtual float window_get_hdr_output_current_reference_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
virtual void window_set_hdr_output_max_luminance(const float p_max_luminance, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual float window_get_hdr_output_max_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
virtual float window_get_hdr_output_current_max_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
virtual float window_get_output_max_linear_value(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
void resize_window(CGSize size);
|
||||
virtual void swap_buffers() override {}
|
||||
|
||||
|
|
|
|||
|
|
@ -376,6 +376,7 @@ bool DisplayServerAppleEmbedded::has_feature(Feature p_feature) const {
|
|||
// case FEATURE_NATIVE_ICON:
|
||||
// case FEATURE_WINDOW_TRANSPARENCY:
|
||||
case FEATURE_CLIPBOARD:
|
||||
case FEATURE_HDR_OUTPUT:
|
||||
case FEATURE_KEEP_SCREEN_ON:
|
||||
case FEATURE_ORIENTATION:
|
||||
case FEATURE_TOUCHSCREEN:
|
||||
|
|
@ -820,6 +821,106 @@ DisplayServer::VSyncMode DisplayServerAppleEmbedded::window_get_vsync_mode(Windo
|
|||
return DisplayServer::VSYNC_ENABLED;
|
||||
}
|
||||
|
||||
// MARK: - HDR / EDR
|
||||
|
||||
void DisplayServerAppleEmbedded::_update_hdr_output() {
|
||||
#ifdef RD_ENABLED
|
||||
if (!rendering_context) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool desired = edr_requested && _screen_hdr_is_supported();
|
||||
if (rendering_context->window_get_hdr_output_enabled(MAIN_WINDOW_ID) != desired) {
|
||||
rendering_context->window_set_hdr_output_enabled(MAIN_WINDOW_ID, desired);
|
||||
}
|
||||
|
||||
float reference_luminance = _calculate_current_reference_luminance();
|
||||
rendering_context->window_set_hdr_output_reference_luminance(MAIN_WINDOW_ID, reference_luminance);
|
||||
|
||||
float max_luminance = _screen_potential_edr_headroom() * hardware_reference_luminance_nits;
|
||||
rendering_context->window_set_hdr_output_max_luminance(MAIN_WINDOW_ID, max_luminance);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DisplayServerAppleEmbedded::current_edr_headroom_changed() {
|
||||
_update_hdr_output();
|
||||
}
|
||||
|
||||
bool DisplayServerAppleEmbedded::window_is_hdr_output_supported(WindowID p_window) const {
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_device && !rendering_device->has_feature(RenderingDevice::Features::SUPPORTS_HDR_OUTPUT)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return _screen_hdr_is_supported();
|
||||
}
|
||||
|
||||
void DisplayServerAppleEmbedded::window_request_hdr_output(const bool p_enabled, WindowID p_window) {
|
||||
#if defined(RD_ENABLED)
|
||||
ERR_FAIL_COND_MSG(p_enabled && rendering_device && !rendering_device->has_feature(RenderingDevice::Features::SUPPORTS_HDR_OUTPUT), "HDR output is not supported by the rendering device.");
|
||||
#endif
|
||||
|
||||
edr_requested = p_enabled;
|
||||
_update_hdr_output();
|
||||
}
|
||||
|
||||
bool DisplayServerAppleEmbedded::window_is_hdr_output_requested(WindowID p_window) const {
|
||||
return edr_requested;
|
||||
}
|
||||
|
||||
bool DisplayServerAppleEmbedded::window_is_hdr_output_enabled(WindowID p_window) const {
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
return rendering_context->window_get_hdr_output_enabled(p_window);
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void DisplayServerAppleEmbedded::window_set_hdr_output_reference_luminance(const float p_reference_luminance, WindowID p_window) {
|
||||
ERR_PRINT_ONCE("Manually setting reference white luminance is not supported on Apple devices, as they provide a user-facing brightness setting that directly controls reference white luminance.");
|
||||
}
|
||||
|
||||
float DisplayServerAppleEmbedded::window_get_hdr_output_reference_luminance(WindowID p_window) const {
|
||||
return -1.0f; // Always auto-adjusted by the OS on Apple platforms.
|
||||
}
|
||||
|
||||
float DisplayServerAppleEmbedded::_calculate_current_reference_luminance() const {
|
||||
float potential = _screen_potential_edr_headroom();
|
||||
float current = _screen_current_edr_headroom();
|
||||
return potential * hardware_reference_luminance_nits / current;
|
||||
}
|
||||
|
||||
float DisplayServerAppleEmbedded::window_get_hdr_output_current_reference_luminance(WindowID p_window) const {
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
return rendering_context->window_get_hdr_output_reference_luminance(p_window);
|
||||
}
|
||||
#endif
|
||||
return 200.0f;
|
||||
}
|
||||
|
||||
void DisplayServerAppleEmbedded::window_set_hdr_output_max_luminance(const float p_max_luminance, WindowID p_window) {
|
||||
ERR_PRINT_ONCE("Manually setting max luminance is not supported on Apple embedded devices as they provide accurate max luminance values for their built-in screens.");
|
||||
}
|
||||
|
||||
float DisplayServerAppleEmbedded::window_get_hdr_output_max_luminance(WindowID p_window) const {
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
float DisplayServerAppleEmbedded::window_get_hdr_output_current_max_luminance(WindowID p_window) const {
|
||||
return _screen_potential_edr_headroom() * hardware_reference_luminance_nits;
|
||||
}
|
||||
|
||||
float DisplayServerAppleEmbedded::window_get_output_max_linear_value(WindowID p_window) const {
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
return rendering_context->window_get_output_max_linear_value(p_window);
|
||||
}
|
||||
#endif
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void DisplayServerAppleEmbedded::set_native_icon(const String &p_filename) {
|
||||
// Not supported on Apple embedded platforms.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ static const float earth_gravity = 9.80665;
|
|||
|
||||
@interface GDTView () {
|
||||
UITouch *godot_touches[max_touches];
|
||||
CGFloat last_edr_headroom;
|
||||
}
|
||||
|
||||
@property(assign, nonatomic) BOOL isActive;
|
||||
|
|
@ -121,6 +122,7 @@ static const float earth_gravity = 9.80665;
|
|||
- (void)godot_commonInit {
|
||||
self.preferredFrameRate = 60;
|
||||
self.useCADisplayLink = bool(GLOBAL_DEF("display.AppleEmbedded/use_cadisplaylink", true)) ? YES : NO;
|
||||
last_edr_headroom = 0.0;
|
||||
|
||||
#if !defined(VISIONOS_ENABLED)
|
||||
self.contentScaleFactor = [UIScreen mainScreen].scale;
|
||||
|
|
@ -249,6 +251,20 @@ static const float earth_gravity = 9.80665;
|
|||
}
|
||||
|
||||
[self handleMotion];
|
||||
|
||||
#if !defined(VISIONOS_ENABLED)
|
||||
if (@available(iOS 16.0, *)) {
|
||||
CGFloat edr_headroom = UIScreen.mainScreen.currentEDRHeadroom;
|
||||
if (last_edr_headroom != edr_headroom) {
|
||||
last_edr_headroom = edr_headroom;
|
||||
if (DisplayServerAppleEmbedded::get_singleton()) {
|
||||
DisplayServerAppleEmbedded::get_singleton()->current_edr_headroom_changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
[self.renderer renderOnView:self];
|
||||
|
||||
[self.renderingLayer stopRenderDisplayLayer];
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ public:
|
|||
layer = nullptr;
|
||||
}
|
||||
|
||||
Error resize(uint32_t p_desired_framebuffer_count) override final {
|
||||
Error resize(uint32_t p_desired_framebuffer_count, RDD::DataFormat &r_format, RDD::ColorSpace &r_color_space) override final {
|
||||
if (width == 0 || height == 0) {
|
||||
// Very likely the window is minimized, don't create a swap chain.
|
||||
return ERR_SKIP;
|
||||
|
|
@ -155,6 +155,28 @@ public:
|
|||
frame_buffers[i].set_texture_count(1);
|
||||
}
|
||||
|
||||
if (hdr_output) {
|
||||
layer->setWantsExtendedDynamicRangeContent(true);
|
||||
CGColorSpaceRef color_space = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearSRGB);
|
||||
layer->setColorspace(color_space);
|
||||
CGColorSpaceRelease(color_space);
|
||||
layer->setPixelFormat(MTL::PixelFormatRGBA16Float);
|
||||
|
||||
r_color_space = RDD::COLOR_SPACE_REC709_LINEAR;
|
||||
r_format = RDD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||
pixel_format = MTL::PixelFormatRGBA16Float;
|
||||
} else {
|
||||
layer->setWantsExtendedDynamicRangeContent(false);
|
||||
CGColorSpaceRef color_space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
|
||||
layer->setColorspace(color_space);
|
||||
CGColorSpaceRelease(color_space);
|
||||
layer->setPixelFormat(MTL::PixelFormatBGRA8Unorm);
|
||||
|
||||
r_color_space = RDD::COLOR_SPACE_REC709_NONLINEAR_SRGB;
|
||||
r_format = RDD::DATA_FORMAT_B8G8R8A8_UNORM;
|
||||
pixel_format = MTL::PixelFormatBGRA8Unorm;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +278,7 @@ public:
|
|||
memdelete_arr(frame_buffers);
|
||||
}
|
||||
|
||||
Error resize(uint32_t p_desired_framebuffer_count) override final {
|
||||
Error resize(uint32_t p_desired_framebuffer_count, RDD::DataFormat &r_format, RDD::ColorSpace &r_color_space) override final {
|
||||
if (width == 0 || height == 0) {
|
||||
// Very likely the window is minimized, don't create a swap chain.
|
||||
return ERR_SKIP;
|
||||
|
|
@ -379,13 +401,12 @@ DisplayServer::VSyncMode RenderingContextDriverMetal::surface_get_vsync_mode(Sur
|
|||
|
||||
void RenderingContextDriverMetal::surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) {
|
||||
Surface *surface = (Surface *)(p_surface);
|
||||
surface->hdr_output = p_enabled;
|
||||
surface->needs_resize = true;
|
||||
surface->set_hdr_output_enabled(p_enabled);
|
||||
}
|
||||
|
||||
bool RenderingContextDriverMetal::surface_get_hdr_output_enabled(SurfaceID p_surface) const {
|
||||
Surface *surface = (Surface *)(p_surface);
|
||||
return surface->hdr_output;
|
||||
return surface->is_hdr_output_enabled();
|
||||
}
|
||||
|
||||
void RenderingContextDriverMetal::surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) {
|
||||
|
|
@ -394,7 +415,7 @@ void RenderingContextDriverMetal::surface_set_hdr_output_reference_luminance(Sur
|
|||
}
|
||||
|
||||
float RenderingContextDriverMetal::surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const {
|
||||
Surface *surface = (Surface *)(p_surface);
|
||||
const Surface *surface = (Surface *)(p_surface);
|
||||
return surface->hdr_reference_luminance;
|
||||
}
|
||||
|
||||
|
|
@ -404,18 +425,16 @@ void RenderingContextDriverMetal::surface_set_hdr_output_max_luminance(SurfaceID
|
|||
}
|
||||
|
||||
float RenderingContextDriverMetal::surface_get_hdr_output_max_luminance(SurfaceID p_surface) const {
|
||||
Surface *surface = (Surface *)(p_surface);
|
||||
const Surface *surface = (Surface *)(p_surface);
|
||||
return surface->hdr_max_luminance;
|
||||
}
|
||||
|
||||
void RenderingContextDriverMetal::surface_set_hdr_output_linear_luminance_scale(SurfaceID p_surface, float p_linear_luminance_scale) {
|
||||
Surface *surface = (Surface *)(p_surface);
|
||||
surface->hdr_linear_luminance_scale = p_linear_luminance_scale;
|
||||
}
|
||||
|
||||
float RenderingContextDriverMetal::surface_get_hdr_output_linear_luminance_scale(SurfaceID p_surface) const {
|
||||
Surface *surface = (Surface *)(p_surface);
|
||||
return surface->hdr_linear_luminance_scale;
|
||||
return surface->hdr_reference_luminance;
|
||||
}
|
||||
|
||||
float RenderingContextDriverMetal::surface_get_hdr_output_max_value(SurfaceID p_surface) const {
|
||||
|
|
|
|||
|
|
@ -91,22 +91,32 @@ public:
|
|||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
|
||||
bool needs_resize = false;
|
||||
double present_minimum_duration = 0.0;
|
||||
MTL::PixelFormat pixel_format = MTL::PixelFormatBGRA8Unorm;
|
||||
|
||||
bool hdr_output = false;
|
||||
// BT.2408 recommendation of 203 nits for HDR Reference White, rounded to 200
|
||||
// to be a more pleasant player-facing value.
|
||||
float hdr_reference_luminance = 200.0f;
|
||||
float hdr_max_luminance = 1000.0f;
|
||||
float hdr_linear_luminance_scale = 100.0f;
|
||||
bool needs_resize = false;
|
||||
bool hdr_output = false;
|
||||
|
||||
Surface(MTL::Device *p_device) :
|
||||
device(p_device) {}
|
||||
virtual ~Surface() = default;
|
||||
|
||||
MTL::PixelFormat get_pixel_format() const { return MTL::PixelFormatBGRA8Unorm; }
|
||||
virtual Error resize(uint32_t p_desired_framebuffer_count) = 0;
|
||||
MTL::PixelFormat get_pixel_format() const { return pixel_format; }
|
||||
void set_hdr_output_enabled(bool p_enabled) {
|
||||
if (hdr_output != p_enabled) {
|
||||
hdr_output = p_enabled;
|
||||
needs_resize = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_hdr_output_enabled() const {
|
||||
return hdr_output;
|
||||
}
|
||||
virtual Error resize(uint32_t p_desired_framebuffer_count, RDD::DataFormat &r_format, RDD::ColorSpace &r_color_space) = 0;
|
||||
virtual RDD::FramebufferID acquire_next_frame_buffer() = 0;
|
||||
virtual void present(MTL3::MDCommandBuffer *p_cmd_buffer) = 0;
|
||||
virtual MTL::Drawable *next_drawable() = 0;
|
||||
|
|
|
|||
|
|
@ -881,6 +881,11 @@ void RenderingDeviceDriverMetal::command_buffer_execute_secondary(CommandBufferI
|
|||
|
||||
void RenderingDeviceDriverMetal::_swap_chain_release(SwapChain *p_swap_chain) {
|
||||
_swap_chain_release_buffers(p_swap_chain);
|
||||
|
||||
if (p_swap_chain->render_pass.id != 0) {
|
||||
render_pass_free(p_swap_chain->render_pass);
|
||||
p_swap_chain->render_pass = RenderPassID();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingDeviceDriverMetal::_swap_chain_release_buffers(SwapChain *p_swap_chain) {
|
||||
|
|
@ -894,9 +899,15 @@ RDD::SwapChainID RenderingDeviceDriverMetal::swap_chain_create(RenderingContextD
|
|||
GODOT_CLANG_WARNING_POP
|
||||
}
|
||||
|
||||
SwapChain *swap_chain = memnew(SwapChain);
|
||||
swap_chain->surface = p_surface;
|
||||
return SwapChainID(swap_chain);
|
||||
}
|
||||
|
||||
RDD::RenderPassID RenderingDeviceDriverMetal::_swap_chain_create_render_pass(RDD::DataFormat p_format) {
|
||||
// Create the render pass that will be used to draw to the swap chain's framebuffers.
|
||||
RDD::Attachment attachment;
|
||||
attachment.format = pixel_formats->getDataFormat(surface->get_pixel_format());
|
||||
attachment.format = p_format;
|
||||
attachment.samples = RDD::TEXTURE_SAMPLES_1;
|
||||
attachment.load_op = RDD::ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachment.store_op = RDD::ATTACHMENT_STORE_OP_STORE;
|
||||
|
|
@ -907,15 +918,7 @@ RDD::SwapChainID RenderingDeviceDriverMetal::swap_chain_create(RenderingContextD
|
|||
color_ref.aspect.set_flag(RDD::TEXTURE_ASPECT_COLOR_BIT);
|
||||
subpass.color_references.push_back(color_ref);
|
||||
|
||||
RenderPassID render_pass = render_pass_create(attachment, subpass, {}, 1, RDD::AttachmentReference());
|
||||
ERR_FAIL_COND_V(!render_pass, SwapChainID());
|
||||
|
||||
// Create the empty swap chain until it is resized.
|
||||
SwapChain *swap_chain = memnew(SwapChain);
|
||||
swap_chain->surface = p_surface;
|
||||
swap_chain->data_format = attachment.format;
|
||||
swap_chain->render_pass = render_pass;
|
||||
return SwapChainID(swap_chain);
|
||||
return render_pass_create(attachment, subpass, {}, 1, RDD::AttachmentReference());
|
||||
}
|
||||
|
||||
Error RenderingDeviceDriverMetal::swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) {
|
||||
|
|
@ -924,7 +927,24 @@ Error RenderingDeviceDriverMetal::swap_chain_resize(CommandQueueID p_cmd_queue,
|
|||
|
||||
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
|
||||
RenderingContextDriverMetal::Surface *surface = (RenderingContextDriverMetal::Surface *)(swap_chain->surface);
|
||||
surface->resize(p_desired_framebuffer_count);
|
||||
|
||||
DataFormat new_data_format = DATA_FORMAT_MAX;
|
||||
ColorSpace new_color_space = COLOR_SPACE_MAX;
|
||||
Error err = surface->resize(p_desired_framebuffer_count, new_data_format, new_color_space);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (new_data_format != swap_chain->data_format) {
|
||||
_swap_chain_release(swap_chain);
|
||||
swap_chain->render_pass = _swap_chain_create_render_pass(new_data_format);
|
||||
if (!swap_chain->render_pass) {
|
||||
return ERR_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
swap_chain->data_format = new_data_format;
|
||||
swap_chain->color_space = new_color_space;
|
||||
|
||||
// Once everything's been created correctly, indicate the surface no longer needs to be resized.
|
||||
context_driver->surface_set_needs_resize(swap_chain->surface, false);
|
||||
|
|
@ -957,7 +977,8 @@ RDD::DataFormat RenderingDeviceDriverMetal::swap_chain_get_format(SwapChainID p_
|
|||
}
|
||||
|
||||
RDD::ColorSpace RenderingDeviceDriverMetal::swap_chain_get_color_space(SwapChainID p_swap_chain) {
|
||||
return RDD::COLOR_SPACE_REC709_NONLINEAR_SRGB;
|
||||
const SwapChain *swap_chain = (const SwapChain *)(p_swap_chain.id);
|
||||
return swap_chain->color_space;
|
||||
}
|
||||
|
||||
void RenderingDeviceDriverMetal::swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) {
|
||||
|
|
@ -975,7 +996,6 @@ void RenderingDeviceDriverMetal::swap_chain_free(SwapChainID p_swap_chain) {
|
|||
GODOT_CLANG_WARNING_POP
|
||||
}
|
||||
_swap_chain_release(swap_chain);
|
||||
render_pass_free(swap_chain->render_pass);
|
||||
memdelete(swap_chain);
|
||||
}
|
||||
|
||||
|
|
@ -2645,6 +2665,8 @@ bool RenderingDeviceDriverMetal::has_feature(Features p_feature) {
|
|||
return device_properties->features.metal_fx_spatial;
|
||||
case SUPPORTS_METALFX_TEMPORAL:
|
||||
return device_properties->features.metal_fx_temporal;
|
||||
case SUPPORTS_HDR_OUTPUT:
|
||||
return true;
|
||||
case SUPPORTS_IMAGE_ATOMIC_32_BIT:
|
||||
return device_properties->features.supports_native_image_atomics;
|
||||
case SUPPORTS_VULKAN_MEMORY_MODEL:
|
||||
|
|
|
|||
|
|
@ -301,11 +301,11 @@ protected:
|
|||
struct SwapChain {
|
||||
RenderingContextDriver::SurfaceID surface = RenderingContextDriver::SurfaceID();
|
||||
RenderPassID render_pass;
|
||||
RDD::DataFormat data_format = DATA_FORMAT_MAX;
|
||||
SwapChain() :
|
||||
render_pass(nullptr) {}
|
||||
DataFormat data_format = DATA_FORMAT_MAX;
|
||||
ColorSpace color_space = COLOR_SPACE_MAX;
|
||||
};
|
||||
|
||||
RenderPassID _swap_chain_create_render_pass(DataFormat p_format);
|
||||
void _swap_chain_release(SwapChain *p_swap_chain);
|
||||
void _swap_chain_release_buffers(SwapChain *p_swap_chain);
|
||||
|
||||
|
|
|
|||
|
|
@ -7327,6 +7327,9 @@ bool RenderingDeviceDriverVulkan::has_feature(Features p_feature) {
|
|||
// involving integrated GPU hardware do not function correctly
|
||||
// with HDR output.
|
||||
return false;
|
||||
#elif defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
|
||||
// HDR support has not yet been thoroughly tested and validated for Apple platforms.
|
||||
return false;
|
||||
#else
|
||||
return context_driver->is_colorspace_supported();
|
||||
#endif // defined(WINDOWS_ENABLED)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "drivers/apple_embedded/display_server_apple_embedded.h"
|
||||
|
||||
class DisplayServerIOS : public DisplayServerAppleEmbedded {
|
||||
class DisplayServerIOS final : public DisplayServerAppleEmbedded {
|
||||
GDSOFTCLASS(DisplayServerIOS, DisplayServerAppleEmbedded);
|
||||
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
|
@ -51,4 +51,9 @@ public:
|
|||
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
|
||||
protected:
|
||||
virtual bool _screen_hdr_is_supported() const override;
|
||||
virtual float _screen_potential_edr_headroom() const override;
|
||||
virtual float _screen_current_edr_headroom() const override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ DisplayServerIOS *DisplayServerIOS::get_singleton() {
|
|||
|
||||
DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) :
|
||||
DisplayServerAppleEmbedded(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error) {
|
||||
// See: https://github.com/godotengine/godot/pull/106814#discussion_r2854262156 for why this was set to 203 nits.
|
||||
hardware_reference_luminance_nits = 203.0f;
|
||||
}
|
||||
|
||||
DisplayServerIOS::~DisplayServerIOS() {
|
||||
|
|
@ -118,3 +120,24 @@ float DisplayServerIOS::screen_get_scale(int p_screen) const {
|
|||
|
||||
return [UIScreen mainScreen].scale;
|
||||
}
|
||||
|
||||
bool DisplayServerIOS::_screen_hdr_is_supported() const {
|
||||
if (@available(iOS 16.0, *)) {
|
||||
return [UIScreen mainScreen].potentialEDRHeadroom > 1.0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float DisplayServerIOS::_screen_potential_edr_headroom() const {
|
||||
if (@available(iOS 16.0, *)) {
|
||||
return [UIScreen mainScreen].potentialEDRHeadroom;
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
float DisplayServerIOS::_screen_current_edr_headroom() const {
|
||||
if (@available(iOS 16.0, *)) {
|
||||
return [UIScreen mainScreen].currentEDRHeadroom;
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ files = [
|
|||
|
||||
if env.editor_build:
|
||||
files += [
|
||||
"display_server_embedded.mm",
|
||||
"display_server_macos_embedded.mm",
|
||||
"embedded_debugger.mm",
|
||||
"embedded_gl_manager.mm",
|
||||
"editor/embedded_game_view_plugin.mm",
|
||||
|
|
|
|||
|
|
@ -151,6 +151,8 @@ public:
|
|||
bool extend_to_title = false;
|
||||
bool hide_from_capture = false;
|
||||
|
||||
HDROutput hdr_output;
|
||||
|
||||
Rect2i parent_safe_rect;
|
||||
};
|
||||
|
||||
|
|
@ -160,13 +162,11 @@ public:
|
|||
GodotProgressView *dock_progress = nullptr;
|
||||
|
||||
private:
|
||||
id screen_observer = nil;
|
||||
|
||||
#if defined(GLES3_ENABLED)
|
||||
GLManagerLegacy_MacOS *gl_manager_legacy = nullptr;
|
||||
GLManagerANGLE_MacOS *gl_manager_angle = nullptr;
|
||||
#endif
|
||||
#if defined(RD_ENABLED)
|
||||
RenderingContextDriver *rendering_context = nullptr;
|
||||
RenderingDevice *rendering_device = nullptr;
|
||||
#endif
|
||||
String rendering_driver;
|
||||
|
||||
|
|
@ -184,15 +184,11 @@ private:
|
|||
id menu_delegate = nullptr;
|
||||
NativeMenuMacOS *native_menu = nullptr;
|
||||
|
||||
Point2i im_selection;
|
||||
String im_text;
|
||||
|
||||
CGEventSourceRef event_source;
|
||||
MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
|
||||
MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE;
|
||||
MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
|
||||
bool mouse_mode_override_enabled = false;
|
||||
void _mouse_update_mode();
|
||||
void _mouse_apply_mode(MouseMode p_prev_mode, MouseMode p_new_mode) override;
|
||||
|
||||
HDROutput &_get_hdr_output(WindowID p_window) override;
|
||||
const HDROutput &_get_hdr_output(WindowID p_window) const override;
|
||||
|
||||
bool drop_events = false;
|
||||
bool in_dispatch_input_event = false;
|
||||
|
|
@ -205,7 +201,6 @@ private:
|
|||
mutable bool displays_arrangement_dirty = true;
|
||||
bool is_resizing = false;
|
||||
|
||||
CursorShape cursor_shape = CURSOR_ARROW;
|
||||
NSCursor *cursors[CURSOR_MAX];
|
||||
HashMap<CursorShape, Vector<Variant>> cursors_cache;
|
||||
|
||||
|
|
@ -219,8 +214,6 @@ private:
|
|||
IndicatorID indicator_id_counter = 0;
|
||||
HashMap<IndicatorID, IndicatorData> indicators;
|
||||
|
||||
IOPMAssertionID screen_keep_on_assertion = kIOPMNullAssertionID;
|
||||
|
||||
Callable help_search_callback;
|
||||
Callable help_action_callback;
|
||||
|
||||
|
|
@ -275,7 +268,6 @@ public:
|
|||
void update_mouse_pos(WindowData &p_wd, NSPoint p_location_in_window);
|
||||
void push_to_key_event_buffer(const KeyEvent &p_event);
|
||||
void pop_last_key_event();
|
||||
void update_im_text(const Point2i &p_selection, const String &p_text);
|
||||
void set_last_focused_window(WindowID p_window);
|
||||
bool mouse_process_popups(bool p_close = false);
|
||||
void popup_open(WindowID p_window);
|
||||
|
|
@ -312,22 +304,12 @@ public:
|
|||
virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const Callable &p_callback, WindowID p_window_id) override;
|
||||
virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector<String> &p_filters, const TypedArray<Dictionary> &p_options, const Callable &p_callback, WindowID p_window_id) override;
|
||||
|
||||
virtual void beep() const override;
|
||||
|
||||
virtual void mouse_set_mode(MouseMode p_mode) override;
|
||||
virtual MouseMode mouse_get_mode() const override;
|
||||
virtual void mouse_set_mode_override(MouseMode p_mode) override;
|
||||
virtual MouseMode mouse_get_mode_override() const override;
|
||||
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
|
||||
virtual bool mouse_is_mode_override_enabled() const override;
|
||||
|
||||
bool update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp);
|
||||
virtual void warp_mouse(const Point2i &p_position) override;
|
||||
virtual Point2i mouse_get_position() const override;
|
||||
virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
|
||||
|
||||
virtual int get_screen_count() const override;
|
||||
virtual int get_primary_screen() const override;
|
||||
virtual int get_keyboard_focus_screen() const override;
|
||||
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
|
|
@ -335,13 +317,9 @@ public:
|
|||
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual float screen_get_max_scale() const override;
|
||||
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual Color screen_get_pixel(const Point2i &p_position) const override;
|
||||
virtual Ref<Image> screen_get_image(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual Ref<Image> screen_get_image_rect(const Rect2i &p_rect) const override;
|
||||
virtual void screen_set_keep_on(bool p_enable) override;
|
||||
virtual bool screen_is_kept_on() const override;
|
||||
|
||||
virtual Vector<int> get_window_list() const override;
|
||||
|
||||
virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID) override;
|
||||
|
|
@ -416,6 +394,9 @@ public:
|
|||
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
|
||||
|
||||
public:
|
||||
void update_screen_parameters();
|
||||
|
||||
virtual bool window_maximize_on_title_dbl_click() const override;
|
||||
virtual bool window_minimize_on_title_dbl_click() const override;
|
||||
|
||||
|
|
@ -425,17 +406,8 @@ public:
|
|||
virtual void window_set_window_buttons_offset(const Vector2i &p_offset, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual Vector3i window_get_safe_title_margins(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
virtual int accessibility_should_increase_contrast() const override;
|
||||
virtual int accessibility_should_reduce_animation() const override;
|
||||
virtual int accessibility_should_reduce_transparency() const override;
|
||||
virtual int accessibility_screen_reader_active() const override;
|
||||
|
||||
virtual Point2i ime_get_selection() const override;
|
||||
virtual String ime_get_text() const override;
|
||||
|
||||
void cursor_update_shape();
|
||||
virtual void cursor_set_shape(CursorShape p_shape) override;
|
||||
virtual CursorShape cursor_get_shape() const override;
|
||||
virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
|
||||
|
||||
virtual bool get_swap_cancel_ok() override;
|
||||
|
|
@ -467,6 +439,8 @@ public:
|
|||
|
||||
virtual bool is_window_transparency_available() const override;
|
||||
|
||||
void window_get_edr_values(WindowID p_window, CGFloat *r_max_potential_edr_value, CGFloat *r_max_edr_value) const override;
|
||||
|
||||
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
|
||||
static Vector<String> get_rendering_drivers_func();
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
#include "servers/rendering/dummy/rasterizer_dummy.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#import "display_server_embedded.h"
|
||||
#import "display_server_macos_embedded.h"
|
||||
#import "editor/embedded_process_macos.h"
|
||||
#endif
|
||||
|
||||
|
|
@ -742,13 +742,6 @@ void DisplayServerMacOS::push_to_key_event_buffer(const DisplayServerMacOS::KeyE
|
|||
key_event_buffer.write[key_event_pos++] = p_event;
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::update_im_text(const Point2i &p_selection, const String &p_text) {
|
||||
im_selection = p_selection;
|
||||
im_text = p_text;
|
||||
|
||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::set_last_focused_window(WindowID p_window) {
|
||||
last_focused_window = p_window;
|
||||
}
|
||||
|
|
@ -842,6 +835,7 @@ bool DisplayServerMacOS::has_feature(Feature p_feature) const {
|
|||
case FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE:
|
||||
case FEATURE_EMOJI_AND_SYMBOL_PICKER:
|
||||
case FEATURE_WINDOW_EMBEDDING:
|
||||
case FEATURE_HDR_OUTPUT:
|
||||
return true;
|
||||
#ifdef ACCESSKIT_ENABLED
|
||||
case FEATURE_ACCESSIBILITY_SCREEN_READER: {
|
||||
|
|
@ -1174,10 +1168,6 @@ Error DisplayServerMacOS::_file_dialog_with_options_show(const String &p_title,
|
|||
return OK;
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::beep() const {
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -1214,32 +1204,24 @@ Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description
|
|||
return OK;
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::_mouse_update_mode() {
|
||||
void DisplayServerMacOS::_mouse_apply_mode(MouseMode p_prev_mode, MouseMode p_new_mode) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
|
||||
? mouse_mode_override
|
||||
: mouse_mode_base;
|
||||
|
||||
if (wanted_mouse_mode == mouse_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
WindowID window_id = _get_focused_window_or_popup();
|
||||
if (!windows.has(window_id)) {
|
||||
window_id = MAIN_WINDOW_ID;
|
||||
}
|
||||
WindowData &wd = windows[window_id];
|
||||
|
||||
bool show_cursor = (wanted_mouse_mode == MOUSE_MODE_VISIBLE || wanted_mouse_mode == MOUSE_MODE_CONFINED);
|
||||
bool previously_shown = (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED);
|
||||
bool show_cursor = (p_new_mode == MOUSE_MODE_VISIBLE || p_new_mode == MOUSE_MODE_CONFINED);
|
||||
bool previously_shown = (p_prev_mode == MOUSE_MODE_VISIBLE || p_prev_mode == MOUSE_MODE_CONFINED);
|
||||
|
||||
if (show_cursor && !previously_shown) {
|
||||
window_id = get_window_at_screen_position(mouse_get_position());
|
||||
mouse_enter_window(window_id);
|
||||
}
|
||||
|
||||
if (wanted_mouse_mode == MOUSE_MODE_CAPTURED) {
|
||||
if (p_new_mode == MOUSE_MODE_CAPTURED) {
|
||||
// Apple Docs state that the display parameter is not used.
|
||||
// "This parameter is not used. By default, you may pass kCGDirectMainDisplay."
|
||||
// https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html
|
||||
|
|
@ -1253,17 +1235,17 @@ void DisplayServerMacOS::_mouse_update_mode() {
|
|||
NSPoint pointOnScreen = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin;
|
||||
CGPoint lMouseWarpPos = { pointOnScreen.x, CGDisplayBounds(CGMainDisplayID()).size.height - pointOnScreen.y };
|
||||
CGWarpMouseCursorPosition(lMouseWarpPos);
|
||||
} else if (wanted_mouse_mode == MOUSE_MODE_HIDDEN) {
|
||||
} else if (p_new_mode == MOUSE_MODE_HIDDEN) {
|
||||
if (previously_shown) {
|
||||
CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||
}
|
||||
[wd.window_object setMovable:YES];
|
||||
CGAssociateMouseAndMouseCursorPosition(true);
|
||||
} else if (wanted_mouse_mode == MOUSE_MODE_CONFINED) {
|
||||
} else if (p_new_mode == MOUSE_MODE_CONFINED) {
|
||||
CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||
[wd.window_object setMovable:NO];
|
||||
CGAssociateMouseAndMouseCursorPosition(false);
|
||||
} else if (wanted_mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
|
||||
} else if (p_new_mode == MOUSE_MODE_CONFINED_HIDDEN) {
|
||||
if (previously_shown) {
|
||||
CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||
}
|
||||
|
|
@ -1278,51 +1260,12 @@ void DisplayServerMacOS::_mouse_update_mode() {
|
|||
last_warp = [[NSProcessInfo processInfo] systemUptime];
|
||||
ignore_warp = true;
|
||||
warp_events.clear();
|
||||
mouse_mode = wanted_mouse_mode;
|
||||
|
||||
if (show_cursor) {
|
||||
cursor_update_shape();
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
|
||||
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
|
||||
if (p_mode == mouse_mode_base) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_base = p_mode;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
DisplayServer::MouseMode DisplayServerMacOS::mouse_get_mode() const {
|
||||
return mouse_mode;
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::mouse_set_mode_override(MouseMode p_mode) {
|
||||
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
|
||||
if (p_mode == mouse_mode_override) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_override = p_mode;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
DisplayServer::MouseMode DisplayServerMacOS::mouse_get_mode_override() const {
|
||||
return mouse_mode_override;
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::mouse_set_mode_override_enabled(bool p_override_enabled) {
|
||||
if (p_override_enabled == mouse_mode_override_enabled) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_override_enabled = p_override_enabled;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
bool DisplayServerMacOS::mouse_is_mode_override_enabled() const {
|
||||
return mouse_mode_override_enabled;
|
||||
}
|
||||
|
||||
bool DisplayServerMacOS::update_mouse_wrap(WindowData &p_wd, NSPoint &r_delta, NSPoint &r_mpos, NSTimeInterval p_timestamp) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -1460,10 +1403,6 @@ int DisplayServerMacOS::get_screen_count() const {
|
|||
return [screenArray count];
|
||||
}
|
||||
|
||||
int DisplayServerMacOS::get_primary_screen() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DisplayServerMacOS::get_keyboard_focus_screen() const {
|
||||
const NSUInteger index = [[NSScreen screens] indexOfObject:[NSScreen mainScreen]];
|
||||
return (index == NSNotFound) ? get_primary_screen() : index;
|
||||
|
|
@ -1509,11 +1448,12 @@ int DisplayServerMacOS::screen_get_dpi(int p_screen) const {
|
|||
|
||||
NSArray *screenArray = [NSScreen screens];
|
||||
if ((NSUInteger)p_screen < [screenArray count]) {
|
||||
NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription];
|
||||
NSScreen *screen = [screenArray objectAtIndex:p_screen];
|
||||
NSDictionary *description = [screen deviceDescription];
|
||||
|
||||
const NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
|
||||
const CGSize displayPhysicalSize = CGDisplayScreenSize([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
|
||||
float scale = [[screenArray objectAtIndex:p_screen] backingScaleFactor];
|
||||
const CGSize displayPhysicalSize = CGDisplayScreenSize(_get_display_id_for_screen(screen));
|
||||
float scale = [screen backingScaleFactor];
|
||||
|
||||
float den2 = (displayPhysicalSize.width / 25.4f) * (displayPhysicalSize.width / 25.4f) + (displayPhysicalSize.height / 25.4f) * (displayPhysicalSize.height / 25.4f);
|
||||
if (den2 > 0.0f) {
|
||||
|
|
@ -1711,42 +1651,6 @@ Ref<Image> DisplayServerMacOS::screen_get_image_rect(const Rect2i &p_rect) const
|
|||
return img;
|
||||
}
|
||||
|
||||
float DisplayServerMacOS::screen_get_refresh_rate(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
p_screen = _get_screen_index(p_screen);
|
||||
int screen_count = get_screen_count();
|
||||
ERR_FAIL_INDEX_V(p_screen, screen_count, SCREEN_REFRESH_RATE_FALLBACK);
|
||||
|
||||
NSArray *screenArray = [NSScreen screens];
|
||||
if ((NSUInteger)p_screen < [screenArray count]) {
|
||||
NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription];
|
||||
const CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
|
||||
const double displayRefreshRate = CGDisplayModeGetRefreshRate(displayMode);
|
||||
return (float)displayRefreshRate;
|
||||
}
|
||||
ERR_PRINT("An error occurred while trying to get the screen refresh rate.");
|
||||
return SCREEN_REFRESH_RATE_FALLBACK;
|
||||
}
|
||||
|
||||
bool DisplayServerMacOS::screen_is_kept_on() const {
|
||||
return (screen_keep_on_assertion);
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::screen_set_keep_on(bool p_enable) {
|
||||
if (screen_keep_on_assertion) {
|
||||
IOPMAssertionRelease(screen_keep_on_assertion);
|
||||
screen_keep_on_assertion = kIOPMNullAssertionID;
|
||||
}
|
||||
|
||||
if (p_enable) {
|
||||
String app_name_string = GLOBAL_GET("application/config/name");
|
||||
NSString *name = [NSString stringWithUTF8String:(app_name_string.is_empty() ? "Godot Engine" : app_name_string.utf8().get_data())];
|
||||
NSString *reason = @"Godot Engine running with display/window/energy_saving/keep_screen_on = true";
|
||||
IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep, (__bridge CFStringRef)name, (__bridge CFStringRef)reason, (__bridge CFStringRef)reason, nullptr, 0, nullptr, &screen_keep_on_assertion);
|
||||
}
|
||||
}
|
||||
|
||||
Vector<DisplayServer::WindowID> DisplayServerMacOS::get_window_list() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -1761,11 +1665,16 @@ DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode,
|
|||
_THREAD_SAFE_METHOD_
|
||||
|
||||
WindowID id = _create_window(p_mode, p_vsync_mode, p_rect);
|
||||
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
|
||||
if (p_flags & (1 << i)) {
|
||||
window_set_flag(WindowFlags(i), true, id);
|
||||
}
|
||||
|
||||
uint32_t set_flags = p_flags & ~(WINDOW_FLAG_MAX - 1); // Clear the flags that are not supported by the window.
|
||||
while (set_flags != 0) {
|
||||
// Find the index of the next set bit.
|
||||
uint32_t index = (uint32_t)__builtin_ctzll(set_flags);
|
||||
// Clear the set bit.
|
||||
set_flags &= (set_flags - 1);
|
||||
window_set_flag(WindowFlags(index), true, id);
|
||||
}
|
||||
|
||||
#ifdef RD_ENABLED
|
||||
if (rendering_device) {
|
||||
rendering_device->screen_create(id);
|
||||
|
|
@ -1975,6 +1884,8 @@ void DisplayServerMacOS::reparent_check(WindowID p_window) {
|
|||
WindowData &wd = windows[p_window];
|
||||
NSScreen *screen = [wd.window_object screen];
|
||||
|
||||
_update_hdr_output(p_window, wd.hdr_output);
|
||||
|
||||
_window_update_display_id(&wd);
|
||||
|
||||
if (wd.transient_parent != INVALID_WINDOW_ID) {
|
||||
|
|
@ -2925,28 +2836,49 @@ DisplayServer::VSyncMode DisplayServerMacOS::window_get_vsync_mode(WindowID p_wi
|
|||
return DisplayServer::VSYNC_ENABLED;
|
||||
}
|
||||
|
||||
int DisplayServerMacOS::accessibility_should_increase_contrast() const {
|
||||
return [(GodotApplicationDelegate *)[[NSApplication sharedApplication] delegate] getHighContrast];
|
||||
DisplayServerMacOSBase::HDROutput &DisplayServerMacOS::_get_hdr_output(WindowID p_window) {
|
||||
return windows.getptr(p_window)->hdr_output;
|
||||
}
|
||||
|
||||
int DisplayServerMacOS::accessibility_should_reduce_animation() const {
|
||||
return [(GodotApplicationDelegate *)[[NSApplication sharedApplication] delegate] getReduceMotion];
|
||||
const DisplayServerMacOSBase::HDROutput &DisplayServerMacOS::_get_hdr_output(WindowID p_window) const {
|
||||
return windows.getptr(p_window)->hdr_output;
|
||||
}
|
||||
|
||||
int DisplayServerMacOS::accessibility_should_reduce_transparency() const {
|
||||
return [(GodotApplicationDelegate *)[[NSApplication sharedApplication] delegate] getReduceTransparency];
|
||||
void DisplayServerMacOS::window_get_edr_values(WindowID p_window, CGFloat *r_max_potential_edr_value, CGFloat *r_max_edr_value) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const WindowData *wd = windows.getptr(p_window);
|
||||
ERR_FAIL_NULL(wd);
|
||||
|
||||
NSScreen *screen = wd->window_object.screen;
|
||||
#define SET_VAL(v, val) \
|
||||
if (v) { \
|
||||
*v = val; \
|
||||
}
|
||||
|
||||
if (@available(macOS 10.15, *)) {
|
||||
SET_VAL(r_max_potential_edr_value, screen.maximumPotentialExtendedDynamicRangeColorComponentValue);
|
||||
SET_VAL(r_max_edr_value, screen.maximumExtendedDynamicRangeColorComponentValue);
|
||||
} else {
|
||||
SET_VAL(r_max_potential_edr_value, 1.0);
|
||||
SET_VAL(r_max_edr_value, 1.0);
|
||||
}
|
||||
|
||||
#undef SET_VAL
|
||||
}
|
||||
|
||||
int DisplayServerMacOS::accessibility_screen_reader_active() const {
|
||||
return [(GodotApplicationDelegate *)[[NSApplication sharedApplication] delegate] getVoiceOver];
|
||||
}
|
||||
void DisplayServerMacOS::update_screen_parameters() {
|
||||
for (const KeyValue<WindowID, WindowData> &E : windows) {
|
||||
if (E.value.hdr_output.requested) {
|
||||
_update_hdr_output(E.key, E.value.hdr_output);
|
||||
}
|
||||
}
|
||||
|
||||
Point2i DisplayServerMacOS::ime_get_selection() const {
|
||||
return im_selection;
|
||||
}
|
||||
|
||||
String DisplayServerMacOS::ime_get_text() const {
|
||||
return im_text;
|
||||
#ifdef TOOLS_ENABLED
|
||||
for (KeyValue<OS::ProcessID, EmbeddedProcessData> &E : embedded_processes) {
|
||||
E.value.process->display_state_changed();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::cursor_update_shape() {
|
||||
|
|
@ -3031,10 +2963,6 @@ void DisplayServerMacOS::cursor_set_shape(CursorShape p_shape) {
|
|||
cursor_update_shape();
|
||||
}
|
||||
|
||||
DisplayServerMacOS::CursorShape DisplayServerMacOS::cursor_get_shape() const {
|
||||
return cursor_shape;
|
||||
}
|
||||
|
||||
void DisplayServerMacOS::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -3135,7 +3063,7 @@ uint32_t DisplayServerMacOS::window_get_display_id(WindowID p_window) const {
|
|||
|
||||
void DisplayServerMacOS::_window_update_display_id(WindowData *p_wd) {
|
||||
NSScreen *screen = [p_wd->window_object screen];
|
||||
CGDirectDisplayID display_id = [[screen deviceDescription][@"NSScreenNumber"] unsignedIntValue];
|
||||
CGDirectDisplayID display_id = _get_display_id_for_screen(screen);
|
||||
if (p_wd->display_id == display_id) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -3925,6 +3853,15 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
|
|||
}
|
||||
force_process_and_drop_events();
|
||||
|
||||
__block DisplayServerMacOS *self = this;
|
||||
screen_observer = [NSNotificationCenter.defaultCenter
|
||||
addObserverForName:NSApplicationDidChangeScreenParametersNotification
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification *_Nonnull note) {
|
||||
self->update_screen_parameters();
|
||||
}];
|
||||
|
||||
if (rendering_driver == "dummy") {
|
||||
RasterizerDummy::make_current();
|
||||
}
|
||||
|
|
@ -3946,16 +3883,9 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
|
|||
RendererCompositorRD::make_current();
|
||||
}
|
||||
#endif
|
||||
|
||||
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
|
||||
}
|
||||
|
||||
DisplayServerMacOS::~DisplayServerMacOS() {
|
||||
if (screen_keep_on_assertion) {
|
||||
IOPMAssertionRelease(screen_keep_on_assertion);
|
||||
screen_keep_on_assertion = kIOPMNullAssertionID;
|
||||
}
|
||||
|
||||
// Destroy all status indicators.
|
||||
for (HashMap<IndicatorID, IndicatorData>::Iterator E = indicators.begin(); E; ++E) {
|
||||
[[NSStatusBar systemStatusBar] removeStatusItem:E->value.item];
|
||||
|
|
@ -4002,6 +3932,8 @@ DisplayServerMacOS::~DisplayServerMacOS() {
|
|||
memdelete(accessibility_driver);
|
||||
}
|
||||
#endif
|
||||
[NSNotificationCenter.defaultCenter removeObserver:screen_observer];
|
||||
|
||||
CGDisplayRemoveReconfigurationCallback(_displays_arrangement_changed, nullptr);
|
||||
|
||||
cursors_cache.clear();
|
||||
|
|
|
|||
|
|
@ -35,13 +35,18 @@
|
|||
#define FontVariation __FontVariation
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <IOKit/pwr_mgt/IOPMLib.h>
|
||||
|
||||
#undef FontVariation
|
||||
|
||||
class RenderingContextDriver;
|
||||
class RenderingDevice;
|
||||
|
||||
class DisplayServerMacOSBase : public DisplayServer {
|
||||
GDSOFTCLASS(DisplayServerMacOSBase, DisplayServer)
|
||||
|
||||
id tts = nullptr;
|
||||
IOPMAssertionID screen_keep_on_assertion = kIOPMNullAssertionID;
|
||||
|
||||
struct LayoutInfo {
|
||||
String name;
|
||||
|
|
@ -53,21 +58,100 @@ class DisplayServerMacOSBase : public DisplayServer {
|
|||
|
||||
Callable system_theme_changed;
|
||||
|
||||
constexpr static CGFloat HARDWARE_REFERENCE_LUMINANCE_NITS = 100.0f;
|
||||
|
||||
public:
|
||||
struct HDROutput {
|
||||
static constexpr float AUTO_MAX_LUMINANCE = -1.0f;
|
||||
|
||||
bool requested = false;
|
||||
float max_luminance = AUTO_MAX_LUMINANCE;
|
||||
|
||||
bool is_auto_max_luminance() const { return max_luminance < 0.0f; }
|
||||
};
|
||||
|
||||
protected:
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
|
||||
MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE;
|
||||
MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
|
||||
bool mouse_mode_override_enabled = false;
|
||||
|
||||
void _mouse_update_mode();
|
||||
virtual void _mouse_apply_mode(MouseMode p_prev_mode, MouseMode p_new_mode) = 0;
|
||||
|
||||
String im_text;
|
||||
Point2i im_selection;
|
||||
|
||||
CursorShape cursor_shape = CURSOR_ARROW;
|
||||
|
||||
void initialize_tts() const;
|
||||
|
||||
static CGDirectDisplayID _get_display_id_for_screen(NSScreen *p_screen);
|
||||
|
||||
void _update_keyboard_layouts() const;
|
||||
static void _keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info);
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
RenderingContextDriver *rendering_context = nullptr;
|
||||
RenderingDevice *rendering_device = nullptr;
|
||||
#endif
|
||||
|
||||
virtual HDROutput &_get_hdr_output(WindowID p_window) = 0;
|
||||
virtual const HDROutput &_get_hdr_output(WindowID p_window) const = 0;
|
||||
|
||||
constexpr float _calculate_current_reference_luminance(CGFloat p_max_potential_edr_value, CGFloat p_max_edr_value) const;
|
||||
void _update_hdr_output(WindowID p_window, const HDROutput &p_hdr);
|
||||
|
||||
public:
|
||||
virtual bool tts_is_speaking() const override;
|
||||
virtual bool tts_is_paused() const override;
|
||||
virtual TypedArray<Dictionary> tts_get_voices() const override;
|
||||
|
||||
virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int64_t p_utterance_id = 0, bool p_interrupt = false) override;
|
||||
virtual void tts_pause() override;
|
||||
virtual void tts_resume() override;
|
||||
virtual void tts_stop() override;
|
||||
|
||||
void emit_system_theme_changed();
|
||||
virtual bool is_dark_mode_supported() const override;
|
||||
virtual bool is_dark_mode() const override;
|
||||
virtual Color get_accent_color() const override;
|
||||
virtual Color get_base_color() const override;
|
||||
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
|
||||
|
||||
virtual void mouse_set_mode(MouseMode p_mode) override;
|
||||
virtual MouseMode mouse_get_mode() const override;
|
||||
virtual void mouse_set_mode_override(MouseMode p_mode) override;
|
||||
virtual MouseMode mouse_get_mode_override() const override;
|
||||
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
|
||||
virtual bool mouse_is_mode_override_enabled() const override;
|
||||
|
||||
virtual void clipboard_set(const String &p_text) override;
|
||||
virtual String clipboard_get() const override;
|
||||
virtual Ref<Image> clipboard_get_image() const override;
|
||||
virtual bool clipboard_has() const override;
|
||||
virtual bool clipboard_has_image() const override;
|
||||
|
||||
virtual int get_primary_screen() const override;
|
||||
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual void screen_set_keep_on(bool p_enable) override;
|
||||
virtual bool screen_is_kept_on() const override;
|
||||
|
||||
virtual int accessibility_should_increase_contrast() const override;
|
||||
virtual int accessibility_should_reduce_animation() const override;
|
||||
virtual int accessibility_should_reduce_transparency() const override;
|
||||
virtual int accessibility_screen_reader_active() const override;
|
||||
|
||||
void update_im_text(const Point2i &p_selection, const String &p_text);
|
||||
virtual Point2i ime_get_selection() const override;
|
||||
virtual String ime_get_text() const override;
|
||||
|
||||
virtual CursorShape cursor_get_shape() const override;
|
||||
|
||||
virtual void beep() const override;
|
||||
|
||||
virtual int keyboard_get_layout_count() const override;
|
||||
virtual int keyboard_get_current_layout() const override;
|
||||
virtual void keyboard_set_current_layout(int p_index) override;
|
||||
|
|
@ -77,21 +161,21 @@ public:
|
|||
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
|
||||
virtual void show_emoji_and_symbol_picker() const override;
|
||||
|
||||
void emit_system_theme_changed();
|
||||
virtual bool is_dark_mode_supported() const override;
|
||||
virtual bool is_dark_mode() const override;
|
||||
virtual Color get_accent_color() const override;
|
||||
virtual Color get_base_color() const override;
|
||||
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
|
||||
virtual void window_get_edr_values(WindowID p_window, CGFloat *r_max_potential_edr_value = nullptr, CGFloat *r_max_edr_value = nullptr) const = 0;
|
||||
virtual bool window_is_hdr_output_supported(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
virtual void window_request_hdr_output(const bool p_enable, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual bool window_is_hdr_output_requested(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
virtual bool window_is_hdr_output_enabled(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
virtual bool tts_is_speaking() const override;
|
||||
virtual bool tts_is_paused() const override;
|
||||
virtual TypedArray<Dictionary> tts_get_voices() const override;
|
||||
virtual void window_set_hdr_output_reference_luminance(const float p_reference_luminance, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual float window_get_hdr_output_reference_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
virtual float window_get_hdr_output_current_reference_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int64_t p_utterance_id = 0, bool p_interrupt = false) override;
|
||||
virtual void tts_pause() override;
|
||||
virtual void tts_resume() override;
|
||||
virtual void tts_stop() override;
|
||||
virtual void window_set_hdr_output_max_luminance(const float p_max_luminance, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual float window_get_hdr_output_max_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
virtual float window_get_hdr_output_current_max_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
virtual float window_get_output_max_linear_value(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||
|
||||
DisplayServerMacOSBase();
|
||||
~DisplayServerMacOSBase();
|
||||
|
|
|
|||
|
|
@ -29,14 +29,73 @@
|
|||
/**************************************************************************/
|
||||
|
||||
#import "display_server_macos_base.h"
|
||||
#import "godot_application_delegate.h"
|
||||
#import "key_mapping_macos.h"
|
||||
#import "tts_macos.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/os/main_loop.h"
|
||||
#include "drivers/png/png_driver_common.h"
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
#include "servers/rendering/rendering_context_driver.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#endif
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
void DisplayServerMacOSBase::_mouse_update_mode() {
|
||||
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
|
||||
? mouse_mode_override
|
||||
: mouse_mode_base;
|
||||
|
||||
if (wanted_mouse_mode == mouse_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
MouseMode prev_mode = mouse_mode;
|
||||
mouse_mode = wanted_mouse_mode;
|
||||
_mouse_apply_mode(prev_mode, wanted_mouse_mode);
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::mouse_set_mode(MouseMode p_mode) {
|
||||
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
|
||||
if (p_mode == mouse_mode_base) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_base = p_mode;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
DisplayServer::MouseMode DisplayServerMacOSBase::mouse_get_mode() const {
|
||||
return mouse_mode;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::mouse_set_mode_override(MouseMode p_mode) {
|
||||
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
|
||||
if (p_mode == mouse_mode_override) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_override = p_mode;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
DisplayServer::MouseMode DisplayServerMacOSBase::mouse_get_mode_override() const {
|
||||
return mouse_mode_override;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::mouse_set_mode_override_enabled(bool p_override_enabled) {
|
||||
if (p_override_enabled == mouse_mode_override_enabled) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_override_enabled = p_override_enabled;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
bool DisplayServerMacOSBase::mouse_is_mode_override_enabled() const {
|
||||
return mouse_mode_override_enabled;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::clipboard_set(const String &p_text) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
|
|
@ -103,6 +162,14 @@ bool DisplayServerMacOSBase::clipboard_has_image() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
CGDirectDisplayID DisplayServerMacOSBase::_get_display_id_for_screen(NSScreen *p_screen) {
|
||||
if (@available(macOS 26.0, *)) {
|
||||
return [p_screen CGDirectDisplayID];
|
||||
} else {
|
||||
return [[p_screen deviceDescription][@"NSScreenNumber"] unsignedIntValue];
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::initialize_tts() const {
|
||||
const_cast<DisplayServerMacOSBase *>(this)->tts = [[TTS_MacOS alloc] init];
|
||||
}
|
||||
|
|
@ -384,6 +451,85 @@ void DisplayServerMacOSBase::set_system_theme_change_callback(const Callable &p_
|
|||
system_theme_changed = p_callable;
|
||||
}
|
||||
|
||||
bool DisplayServerMacOSBase::screen_is_kept_on() const {
|
||||
return (screen_keep_on_assertion);
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::screen_set_keep_on(bool p_enable) {
|
||||
if (screen_keep_on_assertion) {
|
||||
IOPMAssertionRelease(screen_keep_on_assertion);
|
||||
screen_keep_on_assertion = kIOPMNullAssertionID;
|
||||
}
|
||||
|
||||
if (p_enable) {
|
||||
String app_name_string = GLOBAL_GET("application/config/name");
|
||||
NSString *name = [NSString stringWithUTF8String:(app_name_string.is_empty() ? "Godot Engine" : app_name_string.utf8().get_data())];
|
||||
NSString *reason = @"Godot Engine running with display/window/energy_saving/keep_screen_on = true";
|
||||
IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep, (__bridge CFStringRef)name, (__bridge CFStringRef)reason, (__bridge CFStringRef)reason, nullptr, 0, nullptr, &screen_keep_on_assertion);
|
||||
}
|
||||
}
|
||||
|
||||
int DisplayServerMacOSBase::accessibility_should_increase_contrast() const {
|
||||
return [(GodotApplicationDelegate *)[[NSApplication sharedApplication] delegate] getHighContrast];
|
||||
}
|
||||
|
||||
int DisplayServerMacOSBase::accessibility_should_reduce_animation() const {
|
||||
return [(GodotApplicationDelegate *)[[NSApplication sharedApplication] delegate] getReduceMotion];
|
||||
}
|
||||
|
||||
int DisplayServerMacOSBase::accessibility_should_reduce_transparency() const {
|
||||
return [(GodotApplicationDelegate *)[[NSApplication sharedApplication] delegate] getReduceTransparency];
|
||||
}
|
||||
|
||||
int DisplayServerMacOSBase::accessibility_screen_reader_active() const {
|
||||
return [(GodotApplicationDelegate *)[[NSApplication sharedApplication] delegate] getVoiceOver];
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::update_im_text(const Point2i &p_selection, const String &p_text) {
|
||||
im_selection = p_selection;
|
||||
im_text = p_text;
|
||||
|
||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
|
||||
}
|
||||
|
||||
Point2i DisplayServerMacOSBase::ime_get_selection() const {
|
||||
return im_selection;
|
||||
}
|
||||
|
||||
String DisplayServerMacOSBase::ime_get_text() const {
|
||||
return im_text;
|
||||
}
|
||||
|
||||
DisplayServer::CursorShape DisplayServerMacOSBase::cursor_get_shape() const {
|
||||
return cursor_shape;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::beep() const {
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
int DisplayServerMacOSBase::get_primary_screen() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float DisplayServerMacOSBase::screen_get_refresh_rate(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
p_screen = _get_screen_index(p_screen);
|
||||
int screen_count = get_screen_count();
|
||||
ERR_FAIL_INDEX_V(p_screen, screen_count, SCREEN_REFRESH_RATE_FALLBACK);
|
||||
|
||||
NSArray *screenArray = [NSScreen screens];
|
||||
if ((NSUInteger)p_screen < [screenArray count]) {
|
||||
NSScreen *screen = [screenArray objectAtIndex:p_screen];
|
||||
const CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode(_get_display_id_for_screen(screen));
|
||||
const double displayRefreshRate = CGDisplayModeGetRefreshRate(displayMode);
|
||||
return (float)displayRefreshRate;
|
||||
}
|
||||
ERR_PRINT("An error occurred while trying to get the screen refresh rate.");
|
||||
return SCREEN_REFRESH_RATE_FALLBACK;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::emit_system_theme_changed() {
|
||||
if (system_theme_changed.is_valid()) {
|
||||
Variant ret;
|
||||
|
|
@ -395,6 +541,138 @@ void DisplayServerMacOSBase::emit_system_theme_changed() {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - HDR / EDR
|
||||
|
||||
void DisplayServerMacOSBase::_update_hdr_output(WindowID p_window, const HDROutput &p_hdr) {
|
||||
#ifdef RD_ENABLED
|
||||
if (!rendering_context) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGFloat max_potential_edr, max_edr;
|
||||
window_get_edr_values(p_window, &max_potential_edr, &max_edr);
|
||||
bool desired_hdr_enabled = p_hdr.requested && max_potential_edr > 1.0f;
|
||||
bool current_hdr_enabled = rendering_context->window_get_hdr_output_enabled(p_window);
|
||||
if (current_hdr_enabled != desired_hdr_enabled) {
|
||||
rendering_context->window_set_hdr_output_enabled(p_window, desired_hdr_enabled);
|
||||
}
|
||||
|
||||
float reference_luminance = _calculate_current_reference_luminance(max_potential_edr, max_edr);
|
||||
rendering_context->window_set_hdr_output_reference_luminance(p_window, reference_luminance);
|
||||
|
||||
float max_luminance = p_hdr.is_auto_max_luminance() ? max_potential_edr * HARDWARE_REFERENCE_LUMINANCE_NITS : p_hdr.max_luminance;
|
||||
rendering_context->window_set_hdr_output_max_luminance(p_window, max_luminance);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DisplayServerMacOSBase::window_is_hdr_output_supported(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_device && !rendering_device->has_feature(RenderingDevice::Features::SUPPORTS_HDR_OUTPUT)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
CGFloat max_potential_edr;
|
||||
window_get_edr_values(p_window, &max_potential_edr, nullptr);
|
||||
return max_potential_edr > 1.0f;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::window_request_hdr_output(const bool p_enabled, WindowID p_window) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
ERR_FAIL_COND_MSG(p_enabled && rendering_device && !rendering_device->has_feature(RenderingDevice::Features::SUPPORTS_HDR_OUTPUT), "HDR output is not supported by the rendering device.");
|
||||
#endif
|
||||
|
||||
HDROutput &hdr = _get_hdr_output(p_window);
|
||||
hdr.requested = p_enabled;
|
||||
_update_hdr_output(p_window, hdr);
|
||||
}
|
||||
|
||||
bool DisplayServerMacOSBase::window_is_hdr_output_requested(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return _get_hdr_output(p_window).requested;
|
||||
}
|
||||
|
||||
bool DisplayServerMacOSBase::window_is_hdr_output_enabled(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
return rendering_context->window_get_hdr_output_enabled(p_window);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::window_set_hdr_output_reference_luminance(const float p_reference_luminance, WindowID p_window) {
|
||||
ERR_PRINT_ONCE("Manually setting reference white luminance is not supported on Apple devices, as they provide a user-facing brightness setting that directly controls reference white luminance.");
|
||||
}
|
||||
|
||||
float DisplayServerMacOSBase::window_get_hdr_output_reference_luminance(WindowID p_window) const {
|
||||
return -1.0f; // Always auto-adjusted by the OS on Apple platforms.
|
||||
}
|
||||
|
||||
constexpr float DisplayServerMacOSBase::_calculate_current_reference_luminance(CGFloat p_max_potential_edr_value, CGFloat p_max_edr_value) const {
|
||||
return (p_max_potential_edr_value * HARDWARE_REFERENCE_LUMINANCE_NITS) / p_max_edr_value;
|
||||
}
|
||||
|
||||
float DisplayServerMacOSBase::window_get_hdr_output_current_reference_luminance(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
return rendering_context->window_get_hdr_output_reference_luminance(p_window);
|
||||
}
|
||||
#endif
|
||||
return 200.0f;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSBase::window_set_hdr_output_max_luminance(const float p_max_luminance, WindowID p_window) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
HDROutput &hdr = _get_hdr_output(p_window);
|
||||
|
||||
if (hdr.max_luminance == p_max_luminance) {
|
||||
return;
|
||||
}
|
||||
hdr.max_luminance = p_max_luminance;
|
||||
_update_hdr_output(p_window, hdr);
|
||||
}
|
||||
|
||||
float DisplayServerMacOSBase::window_get_hdr_output_max_luminance(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
return _get_hdr_output(p_window).max_luminance;
|
||||
}
|
||||
|
||||
float DisplayServerMacOSBase::window_get_hdr_output_current_max_luminance(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const HDROutput &hdr = _get_hdr_output(p_window);
|
||||
if (hdr.is_auto_max_luminance()) {
|
||||
CGFloat max_potential_edr;
|
||||
window_get_edr_values(p_window, &max_potential_edr, nullptr);
|
||||
return max_potential_edr * HARDWARE_REFERENCE_LUMINANCE_NITS;
|
||||
}
|
||||
return hdr.max_luminance;
|
||||
}
|
||||
|
||||
float DisplayServerMacOSBase::window_get_output_max_linear_value(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
return rendering_context->window_get_output_max_linear_value(p_window);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1.0f; // SDR
|
||||
}
|
||||
|
||||
DisplayServerMacOSBase::DisplayServerMacOSBase() {
|
||||
KeyMappingMacOS::initialize();
|
||||
|
||||
|
|
@ -404,6 +682,8 @@ DisplayServerMacOSBase::DisplayServerMacOSBase() {
|
|||
initialize_tts();
|
||||
}
|
||||
|
||||
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
|
||||
|
||||
// Register to be notified on keyboard layout changes.
|
||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
|
||||
nullptr, _keyboard_layout_changed,
|
||||
|
|
@ -412,5 +692,10 @@ DisplayServerMacOSBase::DisplayServerMacOSBase() {
|
|||
}
|
||||
|
||||
DisplayServerMacOSBase::~DisplayServerMacOSBase() {
|
||||
if (screen_keep_on_assertion) {
|
||||
IOPMAssertionRelease(screen_keep_on_assertion);
|
||||
screen_keep_on_assertion = kIOPMNullAssertionID;
|
||||
}
|
||||
|
||||
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), nullptr, kTISNotifySelectedKeyboardInputSourceChanged, nullptr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/**************************************************************************/
|
||||
/* display_server_embedded.h */
|
||||
/* display_server_macos_embedded.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
|
|
@ -40,7 +40,7 @@ class NativeMenu;
|
|||
class RenderingContextDriver;
|
||||
class RenderingDevice;
|
||||
|
||||
struct DisplayServerEmbeddedState {
|
||||
struct DisplayServerMacOSEmbeddedState {
|
||||
/*! Default to a scale of 2.0, which is the most common. */
|
||||
float screen_max_scale = 2.0f;
|
||||
float screen_dpi = 96.0f;
|
||||
|
|
@ -49,18 +49,24 @@ struct DisplayServerEmbeddedState {
|
|||
/*! The display ID of the window which is displaying the embedded process content. */
|
||||
uint32_t display_id = -1;
|
||||
|
||||
/*! The current maximum EDR value for the display. */
|
||||
double screen_max_edr = 1.0;
|
||||
/*! The maximum possible EDR value for the display. */
|
||||
double screen_max_potential_edr = 1.0;
|
||||
|
||||
void serialize(PackedByteArray &r_data);
|
||||
Error deserialize(const PackedByteArray &p_data);
|
||||
|
||||
_FORCE_INLINE_ bool operator==(const DisplayServerEmbeddedState &p_other) const {
|
||||
return screen_max_scale == p_other.screen_max_scale && screen_dpi == p_other.screen_dpi && display_id == p_other.display_id;
|
||||
_FORCE_INLINE_ bool operator==(const DisplayServerMacOSEmbeddedState &p_other) const {
|
||||
return screen_max_scale == p_other.screen_max_scale && screen_dpi == p_other.screen_dpi && screen_window_scale == p_other.screen_window_scale && display_id == p_other.display_id && screen_max_edr == p_other.screen_max_edr && screen_max_potential_edr == p_other.screen_max_potential_edr;
|
||||
}
|
||||
};
|
||||
|
||||
class DisplayServerEmbedded : public DisplayServerMacOSBase {
|
||||
GDSOFTCLASS(DisplayServerEmbedded, DisplayServerMacOSBase)
|
||||
/// "Embedded" as in "Embedded in the Godot editor window".
|
||||
class DisplayServerMacOSEmbedded : public DisplayServerMacOSBase {
|
||||
GDSOFTCLASS(DisplayServerMacOSEmbedded, DisplayServerMacOSBase)
|
||||
|
||||
DisplayServerEmbeddedState state;
|
||||
DisplayServerMacOSEmbeddedState state;
|
||||
|
||||
NativeMenu *native_menu = nullptr;
|
||||
|
||||
|
|
@ -82,24 +88,16 @@ class DisplayServerEmbedded : public DisplayServerMacOSBase {
|
|||
GLManagerEmbedded *gl_manager = nullptr;
|
||||
#endif
|
||||
|
||||
#if defined(RD_ENABLED)
|
||||
RenderingContextDriver *rendering_context = nullptr;
|
||||
RenderingDevice *rendering_device = nullptr;
|
||||
#endif
|
||||
|
||||
String rendering_driver;
|
||||
|
||||
HDROutput hdr_output;
|
||||
|
||||
HDROutput &_get_hdr_output(WindowID p_window) override;
|
||||
const HDROutput &_get_hdr_output(WindowID p_window) const override;
|
||||
|
||||
Point2i ime_last_position;
|
||||
Point2i im_selection;
|
||||
String im_text;
|
||||
|
||||
MouseMode mouse_mode = MOUSE_MODE_VISIBLE;
|
||||
MouseMode mouse_mode_base = MOUSE_MODE_VISIBLE;
|
||||
MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE;
|
||||
bool mouse_mode_override_enabled = false;
|
||||
void _mouse_update_mode();
|
||||
|
||||
CursorShape cursor_shape = CURSOR_ARROW;
|
||||
void _mouse_apply_mode(MouseMode p_prev_mode, MouseMode p_new_mode) override;
|
||||
|
||||
struct Joy {
|
||||
String name;
|
||||
|
|
@ -134,16 +132,7 @@ public:
|
|||
void send_window_event(DisplayServer::WindowEvent p_event, DisplayServer::WindowID p_id = MAIN_WINDOW_ID) const;
|
||||
void _window_callback(const Callable &p_callable, const Variant &p_arg) const;
|
||||
|
||||
virtual void beep() const override;
|
||||
|
||||
// MARK: - Mouse
|
||||
virtual void mouse_set_mode(MouseMode p_mode) override;
|
||||
virtual MouseMode mouse_get_mode() const override;
|
||||
virtual void mouse_set_mode_override(MouseMode p_mode) override;
|
||||
virtual MouseMode mouse_get_mode_override() const override;
|
||||
virtual void mouse_set_mode_override_enabled(bool p_override_enabled) override;
|
||||
virtual bool mouse_is_mode_override_enabled() const override;
|
||||
|
||||
virtual void warp_mouse(const Point2i &p_position) override;
|
||||
virtual Point2i mouse_get_position() const override;
|
||||
virtual BitField<MouseButtonMask> mouse_get_button_state() const override;
|
||||
|
|
@ -154,14 +143,11 @@ public:
|
|||
virtual String get_name() const override;
|
||||
|
||||
virtual int get_screen_count() const override;
|
||||
virtual int get_primary_screen() const override;
|
||||
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
|
||||
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
|
||||
|
||||
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
|
||||
|
|
@ -216,17 +202,15 @@ public:
|
|||
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
|
||||
|
||||
void update_im_text(const Point2i &p_selection, const String &p_text);
|
||||
virtual Point2i ime_get_selection() const override;
|
||||
virtual String ime_get_text() const override;
|
||||
|
||||
virtual void cursor_set_shape(CursorShape p_shape) override;
|
||||
virtual CursorShape cursor_get_shape() const override;
|
||||
virtual void cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) override;
|
||||
|
||||
void set_state(const DisplayServerEmbeddedState &p_state);
|
||||
void window_get_edr_values(WindowID p_window, CGFloat *r_max_potential_edr_value, CGFloat *r_max_edr_value) const override;
|
||||
void update_screen_parameters();
|
||||
|
||||
void set_state(const DisplayServerMacOSEmbeddedState &p_state);
|
||||
virtual void swap_buffers() override;
|
||||
|
||||
DisplayServerEmbedded(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error);
|
||||
~DisplayServerEmbedded();
|
||||
DisplayServerMacOSEmbedded(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error);
|
||||
~DisplayServerMacOSEmbedded();
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/**************************************************************************/
|
||||
/* display_server_embedded.mm */
|
||||
/* display_server_macos_embedded.mm */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#import "display_server_embedded.h"
|
||||
#import "display_server_macos_embedded.h"
|
||||
|
||||
#if defined(GLES3_ENABLED)
|
||||
#import "embedded_gl_manager.h"
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
#import "core/os/main_loop.h"
|
||||
#import "servers/display/native_menu.h"
|
||||
|
||||
DisplayServerEmbedded::DisplayServerEmbedded(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
|
||||
DisplayServerMacOSEmbedded::DisplayServerMacOSEmbedded(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
|
||||
EmbeddedDebugger::initialize(this);
|
||||
|
||||
r_error = OK; // default to OK
|
||||
|
|
@ -215,7 +215,7 @@ DisplayServerEmbedded::DisplayServerEmbedded(const String &p_rendering_driver, W
|
|||
}
|
||||
}
|
||||
|
||||
DisplayServerEmbedded::~DisplayServerEmbedded() {
|
||||
DisplayServerMacOSEmbedded::~DisplayServerMacOSEmbedded() {
|
||||
if (native_menu) {
|
||||
memdelete(native_menu);
|
||||
native_menu = nullptr;
|
||||
|
|
@ -243,11 +243,11 @@ DisplayServerEmbedded::~DisplayServerEmbedded() {
|
|||
#endif
|
||||
}
|
||||
|
||||
DisplayServer *DisplayServerEmbedded::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t /* p_parent_window */, Error &r_error) {
|
||||
return memnew(DisplayServerEmbedded(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error));
|
||||
DisplayServer *DisplayServerMacOSEmbedded::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t /* p_parent_window */, Error &r_error) {
|
||||
return memnew(DisplayServerMacOSEmbedded(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error));
|
||||
}
|
||||
|
||||
Vector<String> DisplayServerEmbedded::get_rendering_drivers_func() {
|
||||
Vector<String> DisplayServerMacOSEmbedded::get_rendering_drivers_func() {
|
||||
Vector<String> drivers;
|
||||
|
||||
#if defined(VULKAN_ENABLED)
|
||||
|
|
@ -263,74 +263,23 @@ Vector<String> DisplayServerEmbedded::get_rendering_drivers_func() {
|
|||
return drivers;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::register_embedded_driver() {
|
||||
void DisplayServerMacOSEmbedded::register_embedded_driver() {
|
||||
register_create_function("embedded", create_func, get_rendering_drivers_func);
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::beep() const {
|
||||
NSBeep();
|
||||
}
|
||||
|
||||
// MARK: - Mouse
|
||||
|
||||
void DisplayServerEmbedded::_mouse_update_mode() {
|
||||
MouseMode wanted_mouse_mode = mouse_mode_override_enabled
|
||||
? mouse_mode_override
|
||||
: mouse_mode_base;
|
||||
|
||||
if (wanted_mouse_mode == mouse_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
EngineDebugger::get_singleton()->send_message("game_view:mouse_set_mode", { wanted_mouse_mode });
|
||||
|
||||
mouse_mode = wanted_mouse_mode;
|
||||
void DisplayServerMacOSEmbedded::_mouse_apply_mode(MouseMode p_prev_mode, MouseMode p_new_mode) {
|
||||
EngineDebugger::get_singleton()->send_message("game_view:mouse_set_mode", { p_new_mode });
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::mouse_set_mode(MouseMode p_mode) {
|
||||
if (p_mode == mouse_mode_base) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_base = p_mode;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
DisplayServerEmbedded::MouseMode DisplayServerEmbedded::mouse_get_mode() const {
|
||||
return mouse_mode;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::mouse_set_mode_override(MouseMode p_mode) {
|
||||
ERR_FAIL_INDEX(p_mode, MouseMode::MOUSE_MODE_MAX);
|
||||
if (p_mode == mouse_mode_override) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_override = p_mode;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
DisplayServer::MouseMode DisplayServerEmbedded::mouse_get_mode_override() const {
|
||||
return mouse_mode_override;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::mouse_set_mode_override_enabled(bool p_override_enabled) {
|
||||
if (p_override_enabled == mouse_mode_override_enabled) {
|
||||
return;
|
||||
}
|
||||
mouse_mode_override_enabled = p_override_enabled;
|
||||
_mouse_update_mode();
|
||||
}
|
||||
|
||||
bool DisplayServerEmbedded::mouse_is_mode_override_enabled() const {
|
||||
return mouse_mode_override_enabled;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::warp_mouse(const Point2i &p_position) {
|
||||
void DisplayServerMacOSEmbedded::warp_mouse(const Point2i &p_position) {
|
||||
_THREAD_SAFE_METHOD_
|
||||
Input::get_singleton()->set_mouse_position(p_position);
|
||||
EngineDebugger::get_singleton()->send_message("game_view:warp_mouse", { p_position });
|
||||
}
|
||||
|
||||
Point2i DisplayServerEmbedded::mouse_get_position() const {
|
||||
Point2i DisplayServerMacOSEmbedded::mouse_get_position() const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
const NSPoint mouse_pos = [NSEvent mouseLocation];
|
||||
|
|
@ -350,7 +299,7 @@ Point2i DisplayServerEmbedded::mouse_get_position() const {
|
|||
return Vector2i();
|
||||
}
|
||||
|
||||
BitField<MouseButtonMask> DisplayServerEmbedded::mouse_get_button_state() const {
|
||||
BitField<MouseButtonMask> DisplayServerMacOSEmbedded::mouse_get_button_state() const {
|
||||
BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
|
||||
|
||||
NSUInteger buttons = [NSEvent pressedMouseButtons];
|
||||
|
|
@ -374,41 +323,41 @@ BitField<MouseButtonMask> DisplayServerEmbedded::mouse_get_button_state() const
|
|||
|
||||
// MARK: Events
|
||||
|
||||
void DisplayServerEmbedded::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
|
||||
window_resize_callbacks[p_window] = p_callable;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
|
||||
window_event_callbacks[p_window] = p_callable;
|
||||
}
|
||||
void DisplayServerEmbedded::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
|
||||
input_event_callbacks[p_window] = p_callable;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
|
||||
input_text_callbacks[p_window] = p_callable;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::process_events() {
|
||||
void DisplayServerMacOSEmbedded::process_events() {
|
||||
Input *input = Input::get_singleton();
|
||||
input->flush_buffered_events();
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::_dispatch_input_events(const Ref<InputEvent> &p_event) {
|
||||
void DisplayServerMacOSEmbedded::_dispatch_input_events(const Ref<InputEvent> &p_event) {
|
||||
Ref<InputEventFromWindow> event_from_window = p_event;
|
||||
WindowID window_id = INVALID_WINDOW_ID;
|
||||
if (event_from_window.is_valid()) {
|
||||
window_id = event_from_window->get_window_id();
|
||||
}
|
||||
DisplayServerEmbedded *ds = (DisplayServerEmbedded *)DisplayServer::get_singleton();
|
||||
DisplayServerMacOSEmbedded *ds = (DisplayServerMacOSEmbedded *)DisplayServer::get_singleton();
|
||||
ds->send_input_event(p_event, window_id);
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::send_input_event(const Ref<InputEvent> &p_event, WindowID p_id) const {
|
||||
void DisplayServerMacOSEmbedded::send_input_event(const Ref<InputEvent> &p_event, WindowID p_id) const {
|
||||
if (p_id != INVALID_WINDOW_ID) {
|
||||
const Callable *cb = input_event_callbacks.getptr(p_id);
|
||||
if (cb) {
|
||||
|
|
@ -421,21 +370,21 @@ void DisplayServerEmbedded::send_input_event(const Ref<InputEvent> &p_event, Win
|
|||
}
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::send_input_text(const String &p_text, WindowID p_id) const {
|
||||
void DisplayServerMacOSEmbedded::send_input_text(const String &p_text, WindowID p_id) const {
|
||||
const Callable *cb = input_text_callbacks.getptr(p_id);
|
||||
if (cb) {
|
||||
_window_callback(*cb, p_text);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::send_window_event(DisplayServer::WindowEvent p_event, WindowID p_id) const {
|
||||
void DisplayServerMacOSEmbedded::send_window_event(DisplayServer::WindowEvent p_event, WindowID p_id) const {
|
||||
const Callable *cb = window_event_callbacks.getptr(p_id);
|
||||
if (cb) {
|
||||
_window_callback(*cb, int(p_event));
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
|
||||
void DisplayServerMacOSEmbedded::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
|
||||
if (p_callable.is_valid()) {
|
||||
p_callable.call(p_arg);
|
||||
}
|
||||
|
|
@ -443,7 +392,7 @@ void DisplayServerEmbedded::_window_callback(const Callable &p_callable, const V
|
|||
|
||||
// MARK: -
|
||||
|
||||
bool DisplayServerEmbedded::has_feature(Feature p_feature) const {
|
||||
bool DisplayServerMacOSEmbedded::has_feature(Feature p_feature) const {
|
||||
switch (p_feature) {
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
case FEATURE_GLOBAL_MENU: {
|
||||
|
|
@ -456,6 +405,7 @@ bool DisplayServerEmbedded::has_feature(Feature p_feature) const {
|
|||
// case FEATURE_HIDPI:
|
||||
// case FEATURE_ICON:
|
||||
// case FEATURE_MOUSE:
|
||||
case FEATURE_HDR_OUTPUT:
|
||||
case FEATURE_MOUSE_WARP:
|
||||
// case FEATURE_NATIVE_DIALOG:
|
||||
// case FEATURE_NATIVE_ICON:
|
||||
|
|
@ -472,19 +422,15 @@ bool DisplayServerEmbedded::has_feature(Feature p_feature) const {
|
|||
}
|
||||
}
|
||||
|
||||
String DisplayServerEmbedded::get_name() const {
|
||||
String DisplayServerMacOSEmbedded::get_name() const {
|
||||
return "embedded";
|
||||
}
|
||||
|
||||
int DisplayServerEmbedded::get_screen_count() const {
|
||||
int DisplayServerMacOSEmbedded::get_screen_count() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DisplayServerEmbedded::get_primary_screen() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Point2i DisplayServerEmbedded::screen_get_position(int p_screen) const {
|
||||
Point2i DisplayServerMacOSEmbedded::screen_get_position(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
p_screen = _get_screen_index(p_screen);
|
||||
|
|
@ -494,7 +440,7 @@ Point2i DisplayServerEmbedded::screen_get_position(int p_screen) const {
|
|||
return Point2i(0, 0);
|
||||
}
|
||||
|
||||
Size2i DisplayServerEmbedded::screen_get_size(int p_screen) const {
|
||||
Size2i DisplayServerMacOSEmbedded::screen_get_size(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
p_screen = _get_screen_index(p_screen);
|
||||
|
|
@ -504,7 +450,7 @@ Size2i DisplayServerEmbedded::screen_get_size(int p_screen) const {
|
|||
return window_get_size(MAIN_WINDOW_ID);
|
||||
}
|
||||
|
||||
Rect2i DisplayServerEmbedded::screen_get_usable_rect(int p_screen) const {
|
||||
Rect2i DisplayServerMacOSEmbedded::screen_get_usable_rect(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
p_screen = _get_screen_index(p_screen);
|
||||
|
|
@ -514,7 +460,7 @@ Rect2i DisplayServerEmbedded::screen_get_usable_rect(int p_screen) const {
|
|||
return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
|
||||
}
|
||||
|
||||
int DisplayServerEmbedded::screen_get_dpi(int p_screen) const {
|
||||
int DisplayServerMacOSEmbedded::screen_get_dpi(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
p_screen = _get_screen_index(p_screen);
|
||||
|
|
@ -524,7 +470,7 @@ int DisplayServerEmbedded::screen_get_dpi(int p_screen) const {
|
|||
return 96;
|
||||
}
|
||||
|
||||
float DisplayServerEmbedded::screen_get_scale(int p_screen) const {
|
||||
float DisplayServerMacOSEmbedded::screen_get_scale(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
switch (p_screen) {
|
||||
|
|
@ -539,95 +485,76 @@ float DisplayServerEmbedded::screen_get_scale(int p_screen) const {
|
|||
}
|
||||
}
|
||||
|
||||
float DisplayServerEmbedded::screen_get_refresh_rate(int p_screen) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
p_screen = _get_screen_index(p_screen);
|
||||
int screen_count = get_screen_count();
|
||||
ERR_FAIL_INDEX_V(p_screen, screen_count, SCREEN_REFRESH_RATE_FALLBACK);
|
||||
|
||||
p_screen = _get_screen_index(p_screen);
|
||||
NSArray *screenArray = [NSScreen screens];
|
||||
if ((NSUInteger)p_screen < [screenArray count]) {
|
||||
NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription];
|
||||
const CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode([[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
|
||||
const double displayRefreshRate = CGDisplayModeGetRefreshRate(displayMode);
|
||||
return (float)displayRefreshRate;
|
||||
}
|
||||
ERR_PRINT("An error occurred while trying to get the screen refresh rate.");
|
||||
return SCREEN_REFRESH_RATE_FALLBACK;
|
||||
}
|
||||
|
||||
Vector<DisplayServer::WindowID> DisplayServerEmbedded::get_window_list() const {
|
||||
Vector<DisplayServer::WindowID> DisplayServerMacOSEmbedded::get_window_list() const {
|
||||
Vector<DisplayServer::WindowID> list;
|
||||
list.push_back(MAIN_WINDOW_ID);
|
||||
return list;
|
||||
}
|
||||
|
||||
DisplayServer::WindowID DisplayServerEmbedded::get_window_at_screen_position(const Point2i &p_position) const {
|
||||
DisplayServer::WindowID DisplayServerMacOSEmbedded::get_window_at_screen_position(const Point2i &p_position) const {
|
||||
return MAIN_WINDOW_ID;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
|
||||
window_attached_instance_id[p_window] = p_instance;
|
||||
}
|
||||
|
||||
ObjectID DisplayServerEmbedded::window_get_attached_instance_id(WindowID p_window) const {
|
||||
ObjectID DisplayServerMacOSEmbedded::window_get_attached_instance_id(WindowID p_window) const {
|
||||
return window_attached_instance_id[p_window];
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_title(const String &p_title, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_title(const String &p_title, WindowID p_window) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
int DisplayServerEmbedded::window_get_current_screen(WindowID p_window) const {
|
||||
int DisplayServerMacOSEmbedded::window_get_current_screen(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, INVALID_SCREEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_current_screen(int p_screen, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_current_screen(int p_screen, WindowID p_window) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
Point2i DisplayServerEmbedded::window_get_position(WindowID p_window) const {
|
||||
Point2i DisplayServerMacOSEmbedded::window_get_position(WindowID p_window) const {
|
||||
return Point2i();
|
||||
}
|
||||
|
||||
Point2i DisplayServerEmbedded::window_get_position_with_decorations(WindowID p_window) const {
|
||||
Point2i DisplayServerMacOSEmbedded::window_get_position_with_decorations(WindowID p_window) const {
|
||||
return Point2i();
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_position(const Point2i &p_position, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_position(const Point2i &p_position, WindowID p_window) {
|
||||
// Probably not supported for single window iOS app
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_transient(WindowID p_window, WindowID p_parent) {
|
||||
void DisplayServerMacOSEmbedded::window_set_transient(WindowID p_window, WindowID p_parent) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_max_size(const Size2i p_size, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_max_size(const Size2i p_size, WindowID p_window) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
Size2i DisplayServerEmbedded::window_get_max_size(WindowID p_window) const {
|
||||
Size2i DisplayServerMacOSEmbedded::window_get_max_size(WindowID p_window) const {
|
||||
return Size2i();
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_min_size(const Size2i p_size, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_min_size(const Size2i p_size, WindowID p_window) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
Size2i DisplayServerEmbedded::window_get_min_size(WindowID p_window) const {
|
||||
Size2i DisplayServerMacOSEmbedded::window_get_min_size(WindowID p_window) const {
|
||||
return Size2i();
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_size(const Size2i p_size, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_size(const Size2i p_size, WindowID p_window) {
|
||||
print_line("Embedded window can't be resized.");
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::_window_set_size(const Size2i p_size, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::_window_set_size(const Size2i p_size, WindowID p_window) {
|
||||
[CATransaction begin];
|
||||
[CATransaction setDisableActions:YES];
|
||||
|
||||
|
|
@ -656,7 +583,7 @@ void DisplayServerEmbedded::_window_set_size(const Size2i p_size, WindowID p_win
|
|||
}
|
||||
}
|
||||
|
||||
Size2i DisplayServerEmbedded::window_get_size(WindowID p_window) const {
|
||||
Size2i DisplayServerMacOSEmbedded::window_get_size(WindowID p_window) const {
|
||||
#if defined(RD_ENABLED)
|
||||
if (rendering_context) {
|
||||
RenderingContextDriver::SurfaceID surface = rendering_context->surface_get_from_window(p_window);
|
||||
|
|
@ -674,73 +601,73 @@ Size2i DisplayServerEmbedded::window_get_size(WindowID p_window) const {
|
|||
return Size2i();
|
||||
}
|
||||
|
||||
Size2i DisplayServerEmbedded::window_get_size_with_decorations(WindowID p_window) const {
|
||||
Size2i DisplayServerMacOSEmbedded::window_get_size_with_decorations(WindowID p_window) const {
|
||||
return window_get_size(p_window);
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_mode(WindowMode p_mode, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_mode(WindowMode p_mode, WindowID p_window) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
DisplayServer::WindowMode DisplayServerEmbedded::window_get_mode(WindowID p_window) const {
|
||||
DisplayServer::WindowMode DisplayServerMacOSEmbedded::window_get_mode(WindowID p_window) const {
|
||||
return WindowMode::WINDOW_MODE_WINDOWED;
|
||||
}
|
||||
|
||||
bool DisplayServerEmbedded::window_is_maximize_allowed(WindowID p_window) const {
|
||||
bool DisplayServerMacOSEmbedded::window_is_maximize_allowed(WindowID p_window) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
|
||||
if (p_flag == WINDOW_FLAG_TRANSPARENT && p_window == MAIN_WINDOW_ID) {
|
||||
transparent = p_enabled;
|
||||
layer.opaque = !(OS::get_singleton()->is_layered_allowed() && transparent);
|
||||
}
|
||||
}
|
||||
|
||||
bool DisplayServerEmbedded::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
|
||||
bool DisplayServerMacOSEmbedded::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
|
||||
if (p_flag == WINDOW_FLAG_TRANSPARENT && p_window == MAIN_WINDOW_ID) {
|
||||
return transparent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_request_attention(WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_request_attention(WindowID p_window) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_taskbar_progress_value(float p_value, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_taskbar_progress_value(float p_value, WindowID p_window) {
|
||||
// Not supported.
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_taskbar_progress_state(ProgressState p_state, WindowID p_window) {
|
||||
// Not supported.
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_move_to_foreground(WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_move_to_foreground(WindowID p_window) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
bool DisplayServerEmbedded::window_is_focused(WindowID p_window) const {
|
||||
bool DisplayServerMacOSEmbedded::window_is_focused(WindowID p_window) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
float DisplayServerEmbedded::screen_get_max_scale() const {
|
||||
float DisplayServerMacOSEmbedded::screen_get_max_scale() const {
|
||||
return state.screen_max_scale;
|
||||
}
|
||||
|
||||
bool DisplayServerEmbedded::window_can_draw(WindowID p_window) const {
|
||||
bool DisplayServerMacOSEmbedded::window_can_draw(WindowID p_window) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DisplayServerEmbedded::can_any_window_draw() const {
|
||||
bool DisplayServerMacOSEmbedded::can_any_window_draw() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_ime_active(const bool p_active, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_ime_active(const bool p_active, WindowID p_window) {
|
||||
EngineDebugger::get_singleton()->send_message("game_view:window_set_ime_active", { p_active });
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
|
||||
if (p_pos == ime_last_position) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -748,7 +675,40 @@ void DisplayServerEmbedded::window_set_ime_position(const Point2i &p_pos, Window
|
|||
ime_last_position = p_pos;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::set_state(const DisplayServerEmbeddedState &p_state) {
|
||||
DisplayServerMacOSBase::HDROutput &DisplayServerMacOSEmbedded::_get_hdr_output(WindowID p_window) {
|
||||
return hdr_output;
|
||||
}
|
||||
|
||||
const DisplayServerMacOSBase::HDROutput &DisplayServerMacOSEmbedded::_get_hdr_output(WindowID p_window) const {
|
||||
return hdr_output;
|
||||
}
|
||||
|
||||
void DisplayServerMacOSEmbedded::window_get_edr_values(WindowID p_window, CGFloat *r_max_potential_edr_value, CGFloat *r_max_edr_value) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
|
||||
#define SET_VAL(v, val) \
|
||||
if (v) { \
|
||||
*v = val; \
|
||||
}
|
||||
|
||||
if (@available(macOS 10.15, *)) {
|
||||
SET_VAL(r_max_potential_edr_value, state.screen_max_edr);
|
||||
SET_VAL(r_max_edr_value, state.screen_max_potential_edr);
|
||||
} else {
|
||||
SET_VAL(r_max_potential_edr_value, 1.0);
|
||||
SET_VAL(r_max_edr_value, 1.0);
|
||||
}
|
||||
|
||||
#undef SET_VAL
|
||||
}
|
||||
|
||||
void DisplayServerMacOSEmbedded::update_screen_parameters() {
|
||||
if (hdr_output.requested) {
|
||||
_update_hdr_output(MAIN_WINDOW_ID, hdr_output);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerMacOSEmbedded::set_state(const DisplayServerMacOSEmbeddedState &p_state) {
|
||||
if (state == p_state) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -764,9 +724,12 @@ void DisplayServerEmbedded::set_state(const DisplayServerEmbeddedState &p_state)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
if (hdr_output.requested) {
|
||||
_update_hdr_output(MAIN_WINDOW_ID, hdr_output);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
||||
void DisplayServerMacOSEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
||||
#if defined(GLES3_ENABLED)
|
||||
if (gl_manager) {
|
||||
gl_manager->set_vsync_enabled(p_vsync_mode != DisplayServer::VSYNC_DISABLED);
|
||||
|
|
@ -780,7 +743,7 @@ void DisplayServerEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsy
|
|||
#endif
|
||||
}
|
||||
|
||||
DisplayServer::VSyncMode DisplayServerEmbedded::window_get_vsync_mode(WindowID p_window) const {
|
||||
DisplayServer::VSyncMode DisplayServerMacOSEmbedded::window_get_vsync_mode(WindowID p_window) const {
|
||||
_THREAD_SAFE_METHOD_
|
||||
#if defined(GLES3_ENABLED)
|
||||
if (gl_manager) {
|
||||
|
|
@ -795,31 +758,12 @@ DisplayServer::VSyncMode DisplayServerEmbedded::window_get_vsync_mode(WindowID p
|
|||
return DisplayServer::VSYNC_ENABLED;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::update_im_text(const Point2i &p_selection, const String &p_text) {
|
||||
im_selection = p_selection;
|
||||
im_text = p_text;
|
||||
|
||||
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_IME_UPDATE);
|
||||
}
|
||||
|
||||
Point2i DisplayServerEmbedded::ime_get_selection() const {
|
||||
return im_selection;
|
||||
}
|
||||
|
||||
String DisplayServerEmbedded::ime_get_text() const {
|
||||
return im_text;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::cursor_set_shape(CursorShape p_shape) {
|
||||
void DisplayServerMacOSEmbedded::cursor_set_shape(CursorShape p_shape) {
|
||||
cursor_shape = p_shape;
|
||||
EngineDebugger::get_singleton()->send_message("game_view:cursor_set_shape", { p_shape });
|
||||
}
|
||||
|
||||
DisplayServer::CursorShape DisplayServerEmbedded::cursor_get_shape() const {
|
||||
return cursor_shape;
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
void DisplayServerMacOSEmbedded::cursor_set_custom_image(const Ref<Resource> &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
PackedByteArray data;
|
||||
if (p_cursor.is_valid()) {
|
||||
Ref<Image> image = _get_cursor_image_from_resource(p_cursor, p_hotspot);
|
||||
|
|
@ -830,7 +774,7 @@ void DisplayServerEmbedded::cursor_set_custom_image(const Ref<Resource> &p_curso
|
|||
EngineDebugger::get_singleton()->send_message("game_view:cursor_set_custom_image", { data, p_shape, p_hotspot });
|
||||
}
|
||||
|
||||
void DisplayServerEmbedded::swap_buffers() {
|
||||
void DisplayServerMacOSEmbedded::swap_buffers() {
|
||||
#ifdef GLES3_ENABLED
|
||||
if (gl_manager) {
|
||||
gl_manager->swap_buffers();
|
||||
|
|
@ -838,20 +782,22 @@ void DisplayServerEmbedded::swap_buffers() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void DisplayServerEmbeddedState::serialize(PackedByteArray &r_data) {
|
||||
r_data.resize(16);
|
||||
void DisplayServerMacOSEmbeddedState::serialize(PackedByteArray &r_data) {
|
||||
r_data.resize(32);
|
||||
|
||||
uint8_t *data = r_data.ptrw();
|
||||
data += encode_float(screen_max_scale, data);
|
||||
data += encode_float(screen_dpi, data);
|
||||
data += encode_float(screen_window_scale, data);
|
||||
data += encode_uint32(display_id, data);
|
||||
data += encode_double(screen_max_edr, data);
|
||||
data += encode_double(screen_max_potential_edr, data);
|
||||
|
||||
// Assert we had enough space.
|
||||
DEV_ASSERT(r_data.size() >= (data - r_data.ptrw()));
|
||||
}
|
||||
|
||||
Error DisplayServerEmbeddedState::deserialize(const PackedByteArray &p_data) {
|
||||
Error DisplayServerMacOSEmbeddedState::deserialize(const PackedByteArray &p_data) {
|
||||
const uint8_t *data = p_data.ptr();
|
||||
|
||||
screen_max_scale = decode_float(data);
|
||||
|
|
@ -861,6 +807,10 @@ Error DisplayServerEmbeddedState::deserialize(const PackedByteArray &p_data) {
|
|||
screen_window_scale = decode_float(data);
|
||||
data += sizeof(float);
|
||||
display_id = decode_uint32(data);
|
||||
data += sizeof(uint32_t);
|
||||
screen_max_edr = decode_double(data);
|
||||
data += sizeof(double);
|
||||
screen_max_potential_edr = decode_double(data);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
#include "embedded_process_macos.h"
|
||||
|
||||
#include "platform/macos/display_server_embedded.h"
|
||||
#include "platform/macos/display_server_macos.h"
|
||||
#include "platform/macos/display_server_macos_embedded.h"
|
||||
|
||||
#include "core/input/input_event_codec.h"
|
||||
#include "core/os/main_loop.h"
|
||||
|
|
@ -127,13 +127,18 @@ void EmbeddedProcessMacOS::request_close() {
|
|||
}
|
||||
|
||||
void EmbeddedProcessMacOS::display_state_changed() {
|
||||
DisplayServerEmbeddedState state;
|
||||
DisplayServerMacOSEmbeddedState state;
|
||||
state.screen_max_scale = ds->screen_get_max_scale();
|
||||
state.screen_dpi = ds->screen_get_dpi();
|
||||
DisplayServer::WindowID wid = window->get_window_id();
|
||||
state.screen_window_scale = ds->screen_get_scale(ds->window_get_current_screen(wid));
|
||||
state.display_id = ds->window_get_display_id(wid);
|
||||
|
||||
CGFloat max_edr, max_potential_edr;
|
||||
ds->window_get_edr_values(wid, &max_edr, &max_potential_edr);
|
||||
state.screen_max_edr = max_edr;
|
||||
state.screen_max_potential_edr = max_potential_edr;
|
||||
|
||||
PackedByteArray data;
|
||||
state.serialize(data);
|
||||
script_debugger->send_message("embed:ds_state", { data });
|
||||
|
|
|
|||
|
|
@ -33,23 +33,23 @@
|
|||
#include "core/templates/hash_map.h"
|
||||
#include "core/variant/array.h"
|
||||
|
||||
class DisplayServerEmbedded;
|
||||
class DisplayServerMacOSEmbedded;
|
||||
|
||||
/// @brief Singleton class to process embedded debugging message in the child process.
|
||||
class EmbeddedDebugger {
|
||||
inline static EmbeddedDebugger *singleton = nullptr;
|
||||
|
||||
EmbeddedDebugger(DisplayServerEmbedded *p_ds);
|
||||
EmbeddedDebugger(DisplayServerMacOSEmbedded *p_ds);
|
||||
|
||||
public:
|
||||
static void initialize(DisplayServerEmbedded *p_ds);
|
||||
static void initialize(DisplayServerMacOSEmbedded *p_ds);
|
||||
static void deinitialize();
|
||||
|
||||
~EmbeddedDebugger();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
private:
|
||||
DisplayServerEmbedded *ds;
|
||||
DisplayServerMacOSEmbedded *ds;
|
||||
|
||||
/// Message handler function for parse_message.
|
||||
typedef Error (EmbeddedDebugger::*ParseMessageFunc)(const Array &p_args);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "embedded_debugger.h"
|
||||
|
||||
#include "display_server_embedded.h"
|
||||
#include "display_server_macos_embedded.h"
|
||||
|
||||
#include "core/debugger/engine_debugger.h"
|
||||
#include "core/input/input.h"
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
HashMap<String, EmbeddedDebugger::ParseMessageFunc> EmbeddedDebugger::parse_message_handlers;
|
||||
#endif
|
||||
|
||||
EmbeddedDebugger::EmbeddedDebugger(DisplayServerEmbedded *p_ds) {
|
||||
EmbeddedDebugger::EmbeddedDebugger(DisplayServerMacOSEmbedded *p_ds) {
|
||||
singleton = this;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
|
@ -58,7 +58,7 @@ EmbeddedDebugger::~EmbeddedDebugger() {
|
|||
singleton = nullptr;
|
||||
}
|
||||
|
||||
void EmbeddedDebugger::initialize(DisplayServerEmbedded *p_ds) {
|
||||
void EmbeddedDebugger::initialize(DisplayServerMacOSEmbedded *p_ds) {
|
||||
if (EngineDebugger::is_active()) {
|
||||
memnew(EmbeddedDebugger(p_ds));
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ Error EmbeddedDebugger::_msg_notification(const Array &p_args) {
|
|||
Error EmbeddedDebugger::_msg_ds_state(const Array &p_args) {
|
||||
ERR_FAIL_COND_V_MSG(p_args.size() != 1, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'ds_state' message.");
|
||||
PackedByteArray data = p_args[0];
|
||||
DisplayServerEmbeddedState state;
|
||||
DisplayServerMacOSEmbeddedState state;
|
||||
state.deserialize(data);
|
||||
ds->set_state(state);
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#import "dir_access_macos.h"
|
||||
#ifdef TOOLS_ENABLED
|
||||
#import "display_server_embedded.h"
|
||||
#import "display_server_macos_embedded.h"
|
||||
#endif
|
||||
#import "display_server_macos.h"
|
||||
#import "godot_application.h"
|
||||
|
|
@ -1282,9 +1282,9 @@ void OS_MacOS_Embedded::run() {
|
|||
ret = Main::start();
|
||||
}
|
||||
|
||||
DisplayServerEmbedded *ds = Object::cast_to<DisplayServerEmbedded>(DisplayServer::get_singleton());
|
||||
DisplayServerMacOSEmbedded *ds = Object::cast_to<DisplayServerMacOSEmbedded>(DisplayServer::get_singleton());
|
||||
if (!ds) {
|
||||
ERR_FAIL_MSG("DisplayServerEmbedded is not initialized.");
|
||||
ERR_FAIL_MSG("DisplayServerMacOSEmbedded is not initialized.");
|
||||
}
|
||||
|
||||
if (ds && ret == EXIT_SUCCESS && main_loop) {
|
||||
|
|
@ -1324,7 +1324,7 @@ void OS_MacOS_Embedded::run() {
|
|||
|
||||
OS_MacOS_Embedded::OS_MacOS_Embedded(const char *p_execpath, int p_argc, char **p_argv) :
|
||||
OS_MacOS(p_execpath, p_argc, p_argv) {
|
||||
DisplayServerEmbedded::register_embedded_driver();
|
||||
DisplayServerMacOSEmbedded::register_embedded_driver();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -51,4 +51,9 @@ public:
|
|||
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||
|
||||
protected:
|
||||
virtual bool _screen_hdr_is_supported() const override;
|
||||
virtual float _screen_potential_edr_headroom() const override;
|
||||
virtual float _screen_current_edr_headroom() const override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -77,3 +77,19 @@ float DisplayServerVisionOS::screen_get_scale(int p_screen) const {
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool DisplayServerVisionOS::_screen_hdr_is_supported() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
float DisplayServerVisionOS::_screen_potential_edr_headroom() const {
|
||||
// Current Apple Vision Pro hardware supports an EDR headroom of 2.0 (two times the SDR range).
|
||||
// See https://developer.apple.com/videos/play/wwdc2023/10089?time=603
|
||||
return 2.0f;
|
||||
}
|
||||
|
||||
float DisplayServerVisionOS::_screen_current_edr_headroom() const {
|
||||
// Current Apple Vision Pro hardware supports an EDR headroom of 2.0 (two times the SDR range).
|
||||
// See https://developer.apple.com/videos/play/wwdc2023/10089?time=603
|
||||
return 2.0f;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue