2014-02-10 01:10:30 +00:00
/*************************************************************************/
2020-12-03 21:09:47 +00:00
/* rendering_server_default.cpp */
2014-02-10 01:10:30 +00:00
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 12:16:55 +00:00
/* https://godotengine.org */
2014-02-10 01:10:30 +00:00
/*************************************************************************/
2022-01-03 20:27:34 +00:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 01:10:30 +00:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-04 23:50:27 +00:00
2020-12-03 21:09:47 +00:00
# include "rendering_server_default.h"
2017-08-27 19:07:15 +00:00
2020-11-07 22:33:38 +00:00
# include "core/config/project_settings.h"
2018-09-11 16:13:45 +00:00
# include "core/io/marshalls.h"
# include "core/os/os.h"
2020-11-07 22:33:38 +00:00
# include "core/templates/sort_array.h"
2020-12-04 18:26:24 +00:00
# include "renderer_canvas_cull.h"
# include "renderer_scene_cull.h"
2020-03-27 18:21:27 +00:00
# include "rendering_server_globals.h"
2016-10-03 19:33:42 +00:00
2021-10-07 13:46:55 +00:00
// careful, these may run in different threads than the rendering server
2014-02-10 01:10:30 +00:00
2020-12-03 21:09:47 +00:00
int RenderingServerDefault : : changes = 0 ;
2017-04-07 02:36:37 +00:00
2016-10-03 19:33:42 +00:00
/* FREE */
2021-02-09 16:19:03 +00:00
void RenderingServerDefault : : _free ( RID p_rid ) {
2021-09-29 08:59:46 +00:00
if ( unlikely ( p_rid . is_null ( ) ) ) {
return ;
}
2022-06-21 00:08:33 +00:00
if ( RSG : : utilities - > free ( p_rid ) ) {
2016-10-03 19:33:42 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
if ( RSG : : canvas - > free ( p_rid ) ) {
2016-10-03 19:33:42 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
if ( RSG : : viewport - > free ( p_rid ) ) {
2016-10-03 19:33:42 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
if ( RSG : : scene - > free ( p_rid ) ) {
2016-10-19 14:14:41 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2016-10-03 19:33:42 +00:00
}
/* EVENT QUEUING */
2021-11-05 05:59:38 +00:00
void RenderingServerDefault : : request_frame_drawn_callback ( const Callable & p_callable ) {
frame_drawn_callbacks . push_back ( p_callable ) ;
2017-06-09 03:23:50 +00:00
}
2021-02-09 16:19:03 +00:00
void RenderingServerDefault : : _draw ( bool p_swap_buffers , double frame_step ) {
2018-07-16 14:43:26 +00:00
//needs to be done before changes is reset to 0, to not force the editor to redraw
2021-07-17 21:22:52 +00:00
RS : : get_singleton ( ) - > emit_signal ( SNAME ( " frame_pre_draw " ) ) ;
2018-07-06 23:21:13 +00:00
2018-07-16 14:43:26 +00:00
changes = 0 ;
2020-03-27 18:21:27 +00:00
RSG : : rasterizer - > begin_frame ( frame_step ) ;
2016-12-20 03:21:07 +00:00
2019-10-03 23:15:38 +00:00
TIMESTAMP_BEGIN ( )
2019-09-20 20:58:06 +00:00
2020-12-24 03:13:52 +00:00
uint64_t time_usec = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
2020-12-03 21:09:47 +00:00
RSG : : scene - > update ( ) ; //update scenes stuff before updating instances
2019-08-26 20:43:58 +00:00
2020-12-24 03:13:52 +00:00
frame_setup_time = double ( OS : : get_singleton ( ) - > get_ticks_usec ( ) - time_usec ) / 1000.0 ;
2022-04-12 11:41:50 +00:00
RSG : : particles_storage - > update_particles ( ) ; //need to be done after instances are updated (colliders and particle transforms), and colliders are rendered
2020-10-08 00:29:49 +00:00
2020-03-27 18:21:27 +00:00
RSG : : scene - > render_probes ( ) ;
2020-12-24 03:13:52 +00:00
2020-03-27 18:21:27 +00:00
RSG : : viewport - > draw_viewports ( ) ;
RSG : : canvas_render - > update ( ) ;
2019-06-16 02:45:24 +00:00
2020-03-27 18:21:27 +00:00
RSG : : rasterizer - > end_frame ( p_swap_buffers ) ;
2017-06-09 03:23:50 +00:00
2022-01-26 01:25:20 +00:00
XRServer * xr_server = XRServer : : get_singleton ( ) ;
if ( xr_server ! = nullptr ) {
// let our XR server know we're done so we can get our frame timing
xr_server - > end_frame ( ) ;
}
2021-06-15 20:33:24 +00:00
RSG : : canvas - > update_visibility_notifiers ( ) ;
2021-06-16 18:43:02 +00:00
RSG : : scene - > update_visibility_notifiers ( ) ;
2021-06-15 20:33:24 +00:00
2017-06-09 03:23:50 +00:00
while ( frame_drawn_callbacks . front ( ) ) {
2021-11-05 05:59:38 +00:00
Callable c = frame_drawn_callbacks . front ( ) - > get ( ) ;
Variant result ;
Callable : : CallError ce ;
2022-07-28 20:56:41 +00:00
c . callp ( nullptr , 0 , result , ce ) ;
2021-11-05 05:59:38 +00:00
if ( ce . error ! = Callable : : CallError : : CALL_OK ) {
String err = Variant : : get_callable_error_text ( c , nullptr , 0 , ce ) ;
ERR_PRINT ( " Error calling frame drawn function: " + err ) ;
2017-06-09 03:23:50 +00:00
}
frame_drawn_callbacks . pop_front ( ) ;
}
2021-07-17 21:22:52 +00:00
RS : : get_singleton ( ) - > emit_signal ( SNAME ( " frame_post_draw " ) ) ;
2019-09-20 20:58:06 +00:00
2022-06-21 00:08:33 +00:00
if ( RSG : : utilities - > get_captured_timestamps_count ( ) ) {
2019-09-20 20:58:06 +00:00
Vector < FrameProfileArea > new_profile ;
2022-06-21 00:08:33 +00:00
if ( RSG : : utilities - > capturing_timestamps ) {
new_profile . resize ( RSG : : utilities - > get_captured_timestamps_count ( ) ) ;
2020-04-10 17:18:42 +00:00
}
2019-09-20 20:58:06 +00:00
2022-06-21 00:08:33 +00:00
uint64_t base_cpu = RSG : : utilities - > get_captured_timestamp_cpu_time ( 0 ) ;
uint64_t base_gpu = RSG : : utilities - > get_captured_timestamp_gpu_time ( 0 ) ;
for ( uint32_t i = 0 ; i < RSG : : utilities - > get_captured_timestamps_count ( ) ; i + + ) {
uint64_t time_cpu = RSG : : utilities - > get_captured_timestamp_cpu_time ( i ) ;
uint64_t time_gpu = RSG : : utilities - > get_captured_timestamp_gpu_time ( i ) ;
2020-04-10 17:18:42 +00:00
2022-06-21 00:08:33 +00:00
String name = RSG : : utilities - > get_captured_timestamp_name ( i ) ;
2020-04-10 17:18:42 +00:00
if ( name . begins_with ( " vp_ " ) ) {
RSG : : viewport - > handle_timestamp ( name , time_cpu , time_gpu ) ;
}
2022-06-21 00:08:33 +00:00
if ( RSG : : utilities - > capturing_timestamps ) {
2021-02-02 02:16:37 +00:00
new_profile . write [ i ] . gpu_msec = double ( ( time_gpu - base_gpu ) / 1000 ) / 1000.0 ;
new_profile . write [ i ] . cpu_msec = double ( time_cpu - base_cpu ) / 1000.0 ;
2022-06-21 00:08:33 +00:00
new_profile . write [ i ] . name = RSG : : utilities - > get_captured_timestamp_name ( i ) ;
2020-04-10 17:18:42 +00:00
}
2019-09-20 20:58:06 +00:00
}
frame_profile = new_profile ;
}
2022-06-21 00:08:33 +00:00
frame_profile_frame = RSG : : utilities - > get_captured_timestamps_frame ( ) ;
2021-01-22 23:50:24 +00:00
if ( print_gpu_profile ) {
if ( print_frame_profile_ticks_from = = 0 ) {
print_frame_profile_ticks_from = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
}
2021-02-02 02:16:37 +00:00
double total_time = 0.0 ;
2021-01-22 23:50:24 +00:00
for ( int i = 0 ; i < frame_profile . size ( ) - 1 ; i + + ) {
String name = frame_profile [ i ] . name ;
if ( name [ 0 ] = = ' < ' | | name [ 0 ] = = ' > ' ) {
continue ;
}
2021-02-02 02:16:37 +00:00
double time = frame_profile [ i + 1 ] . gpu_msec - frame_profile [ i ] . gpu_msec ;
2021-01-22 23:50:24 +00:00
if ( name [ 0 ] ! = ' < ' & & name [ 0 ] ! = ' > ' ) {
if ( print_gpu_profile_task_time . has ( name ) ) {
print_gpu_profile_task_time [ name ] + = time ;
} else {
print_gpu_profile_task_time [ name ] = time ;
}
}
}
if ( frame_profile . size ( ) ) {
total_time = frame_profile [ frame_profile . size ( ) - 1 ] . gpu_msec ;
}
uint64_t ticks_elapsed = OS : : get_singleton ( ) - > get_ticks_usec ( ) - print_frame_profile_ticks_from ;
print_frame_profile_frame_count + + ;
if ( ticks_elapsed > 1000000 ) {
print_line ( " GPU PROFILE (total " + rtos ( total_time ) + " ms): " ) ;
float print_threshold = 0.01 ;
2022-05-08 08:09:19 +00:00
for ( const KeyValue < String , float > & E : print_gpu_profile_task_time ) {
double time = E . value / double ( print_frame_profile_frame_count ) ;
2021-01-22 23:50:24 +00:00
if ( time > print_threshold ) {
2022-05-08 08:09:19 +00:00
print_line ( " \t - " + E . key + " : " + rtos ( time ) + " ms " ) ;
2021-01-22 23:50:24 +00:00
}
}
print_gpu_profile_task_time . clear ( ) ;
print_frame_profile_ticks_from = OS : : get_singleton ( ) - > get_ticks_usec ( ) ;
print_frame_profile_frame_count = 0 ;
}
}
2021-07-02 23:14:19 +00:00
2022-06-21 00:08:33 +00:00
RSG : : utilities - > update_memory_info ( ) ;
2016-10-03 19:33:42 +00:00
}
2020-05-14 12:29:06 +00:00
2021-02-02 02:16:37 +00:00
double RenderingServerDefault : : get_frame_setup_time_cpu ( ) const {
2020-12-24 03:13:52 +00:00
return frame_setup_time ;
}
2020-12-03 21:09:47 +00:00
bool RenderingServerDefault : : has_changed ( ) const {
2016-10-04 02:46:24 +00:00
return changes > 0 ;
2016-10-03 19:33:42 +00:00
}
2020-05-14 12:29:06 +00:00
2021-02-09 16:19:03 +00:00
void RenderingServerDefault : : _init ( ) {
2020-03-27 18:21:27 +00:00
RSG : : rasterizer - > initialize ( ) ;
2016-10-03 19:33:42 +00:00
}
2020-05-14 12:29:06 +00:00
2021-02-09 16:19:03 +00:00
void RenderingServerDefault : : _finish ( ) {
2016-10-03 19:33:42 +00:00
if ( test_cube . is_valid ( ) ) {
free ( test_cube ) ;
}
2020-03-27 18:21:27 +00:00
RSG : : rasterizer - > finalize ( ) ;
2016-10-03 19:33:42 +00:00
}
2021-02-09 16:19:03 +00:00
void RenderingServerDefault : : init ( ) {
if ( create_thread ) {
print_verbose ( " RenderingServerWrapMT: Creating render thread " ) ;
DisplayServer : : get_singleton ( ) - > release_rendering_thread ( ) ;
if ( create_thread ) {
thread . start ( _thread_callback , this ) ;
print_verbose ( " RenderingServerWrapMT: Starting render thread " ) ;
}
2021-02-10 18:22:13 +00:00
while ( ! draw_thread_up . is_set ( ) ) {
2021-02-09 16:19:03 +00:00
OS : : get_singleton ( ) - > delay_usec ( 1000 ) ;
}
print_verbose ( " RenderingServerWrapMT: Finished render thread " ) ;
} else {
_init ( ) ;
}
}
void RenderingServerDefault : : finish ( ) {
if ( create_thread ) {
command_queue . push ( this , & RenderingServerDefault : : _thread_exit ) ;
thread . wait_to_finish ( ) ;
} else {
_finish ( ) ;
}
}
2016-10-03 19:33:42 +00:00
/* STATUS INFORMATION */
2021-07-02 23:14:19 +00:00
uint64_t RenderingServerDefault : : get_rendering_info ( RenderingInfo p_info ) {
if ( p_info = = RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME ) {
return RSG : : viewport - > get_total_objects_drawn ( ) ;
} else if ( p_info = = RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME ) {
return RSG : : viewport - > get_total_vertices_drawn ( ) ;
} else if ( p_info = = RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME ) {
return RSG : : viewport - > get_total_draw_calls_used ( ) ;
}
2022-06-21 00:08:33 +00:00
return RSG : : utilities - > get_rendering_info ( p_info ) ;
2016-10-03 19:33:42 +00:00
}
2020-12-03 21:09:47 +00:00
String RenderingServerDefault : : get_video_adapter_name ( ) const {
2022-06-21 00:08:33 +00:00
return RSG : : utilities - > get_video_adapter_name ( ) ;
2019-09-13 18:08:05 +00:00
}
2020-12-03 21:09:47 +00:00
String RenderingServerDefault : : get_video_adapter_vendor ( ) const {
2022-06-21 00:08:33 +00:00
return RSG : : utilities - > get_video_adapter_vendor ( ) ;
2019-09-13 18:08:05 +00:00
}
2021-12-10 16:01:51 +00:00
RenderingDevice : : DeviceType RenderingServerDefault : : get_video_adapter_type ( ) const {
2022-06-21 00:08:33 +00:00
return RSG : : utilities - > get_video_adapter_type ( ) ;
2021-12-10 16:01:51 +00:00
}
2021-07-31 13:39:46 +00:00
String RenderingServerDefault : : get_video_adapter_api_version ( ) const {
2022-06-21 00:08:33 +00:00
return RSG : : utilities - > get_video_adapter_api_version ( ) ;
2021-07-31 13:39:46 +00:00
}
2020-12-03 21:09:47 +00:00
void RenderingServerDefault : : set_frame_profiling_enabled ( bool p_enable ) {
2022-06-21 00:08:33 +00:00
RSG : : utilities - > capturing_timestamps = p_enable ;
2019-09-20 20:58:06 +00:00
}
2020-12-03 21:09:47 +00:00
uint64_t RenderingServerDefault : : get_frame_profile_frame ( ) {
2019-09-20 20:58:06 +00:00
return frame_profile_frame ;
}
2020-12-03 21:09:47 +00:00
Vector < RenderingServer : : FrameProfileArea > RenderingServerDefault : : get_frame_profile ( ) {
2019-09-20 20:58:06 +00:00
return frame_profile ;
}
2016-10-03 19:33:42 +00:00
/* TESTING */
2022-01-19 15:09:52 +00:00
void RenderingServerDefault : : set_boot_image ( const Ref < Image > & p_image , const Color & p_color , bool p_scale , bool p_use_filter ) {
2017-04-09 23:40:48 +00:00
redraw_request ( ) ;
2022-01-19 15:09:52 +00:00
RSG : : rasterizer - > set_boot_image ( p_image , p_color , p_scale , p_use_filter ) ;
2016-10-03 19:33:42 +00:00
}
2020-05-14 12:29:06 +00:00
2020-12-03 21:09:47 +00:00
void RenderingServerDefault : : set_default_clear_color ( const Color & p_color ) {
2020-03-27 18:21:27 +00:00
RSG : : viewport - > set_default_clear_color ( p_color ) ;
2016-10-03 19:33:42 +00:00
}
2020-12-03 21:09:47 +00:00
bool RenderingServerDefault : : has_feature ( Features p_feature ) const {
2016-10-03 19:33:42 +00:00
return false ;
}
2020-12-03 21:09:47 +00:00
void RenderingServerDefault : : sdfgi_set_debug_probe_select ( const Vector3 & p_position , const Vector3 & p_dir ) {
RSG : : scene - > sdfgi_set_debug_probe_select ( p_position , p_dir ) ;
2020-06-25 13:33:28 +00:00
}
2021-01-22 23:50:24 +00:00
void RenderingServerDefault : : set_print_gpu_profile ( bool p_enable ) {
2022-06-21 00:08:33 +00:00
RSG : : utilities - > capturing_timestamps = p_enable ;
2021-01-22 23:50:24 +00:00
print_gpu_profile = p_enable ;
}
2020-12-03 21:09:47 +00:00
RID RenderingServerDefault : : get_test_cube ( ) {
2016-10-03 19:33:42 +00:00
if ( ! test_cube . is_valid ( ) ) {
test_cube = _make_test_cube ( ) ;
}
return test_cube ;
}
2020-12-03 21:09:47 +00:00
bool RenderingServerDefault : : has_os_feature ( const String & p_feature ) const {
2022-06-21 00:08:33 +00:00
if ( RSG : : utilities ) {
return RSG : : utilities - > has_os_feature ( p_feature ) ;
2022-05-28 11:09:23 +00:00
} else {
return false ;
}
2017-02-06 03:38:39 +00:00
}
2020-12-03 21:09:47 +00:00
void RenderingServerDefault : : set_debug_generate_wireframes ( bool p_generate ) {
2022-06-21 00:08:33 +00:00
RSG : : utilities - > set_debug_generate_wireframes ( p_generate ) ;
2017-06-11 18:52:03 +00:00
}
2020-12-03 21:09:47 +00:00
bool RenderingServerDefault : : is_low_end ( ) const {
2022-04-29 22:34:01 +00:00
return RendererCompositor : : is_low_end ( ) ;
2018-09-28 23:32:40 +00:00
}
2020-05-14 12:29:06 +00:00
2021-02-09 16:19:03 +00:00
void RenderingServerDefault : : _thread_exit ( ) {
2021-02-10 18:22:13 +00:00
exit . set ( ) ;
2021-02-09 16:19:03 +00:00
}
void RenderingServerDefault : : _thread_draw ( bool p_swap_buffers , double frame_step ) {
2020-01-30 21:22:36 +00:00
_draw ( p_swap_buffers , frame_step ) ;
2021-02-09 16:19:03 +00:00
}
void RenderingServerDefault : : _thread_flush ( ) {
}
void RenderingServerDefault : : _thread_callback ( void * _instance ) {
RenderingServerDefault * vsmt = reinterpret_cast < RenderingServerDefault * > ( _instance ) ;
vsmt - > _thread_loop ( ) ;
}
void RenderingServerDefault : : _thread_loop ( ) {
server_thread = Thread : : get_caller_id ( ) ;
DisplayServer : : get_singleton ( ) - > make_rendering_thread ( ) ;
_init ( ) ;
2021-02-10 18:22:13 +00:00
draw_thread_up . set ( ) ;
while ( ! exit . is_set ( ) ) {
2021-02-09 16:19:03 +00:00
// flush commands one by one, until exit is requested
2021-06-09 15:09:31 +00:00
command_queue . wait_and_flush ( ) ;
2021-02-09 16:19:03 +00:00
}
command_queue . flush_all ( ) ; // flush all
_finish ( ) ;
}
/* EVENT QUEUING */
void RenderingServerDefault : : sync ( ) {
if ( create_thread ) {
command_queue . push_and_sync ( this , & RenderingServerDefault : : _thread_flush ) ;
} else {
command_queue . flush_all ( ) ; //flush all pending from other threads
}
}
void RenderingServerDefault : : draw ( bool p_swap_buffers , double frame_step ) {
if ( create_thread ) {
command_queue . push ( this , & RenderingServerDefault : : _thread_draw , p_swap_buffers , frame_step ) ;
} else {
_draw ( p_swap_buffers , frame_step ) ;
}
}
RenderingServerDefault : : RenderingServerDefault ( bool p_create_thread ) :
command_queue ( p_create_thread ) {
2022-05-28 11:09:23 +00:00
RenderingServer : : init ( ) ;
2021-02-09 16:19:03 +00:00
create_thread = p_create_thread ;
if ( ! p_create_thread ) {
server_thread = Thread : : get_caller_id ( ) ;
} else {
server_thread = 0 ;
}
2021-06-15 20:33:24 +00:00
RSG : : threaded = p_create_thread ;
2020-12-04 18:26:24 +00:00
RSG : : canvas = memnew ( RendererCanvasCull ) ;
RSG : : viewport = memnew ( RendererViewport ) ;
RendererSceneCull * sr = memnew ( RendererSceneCull ) ;
2022-07-31 23:20:24 +00:00
RSG : : camera_attributes = memnew ( RendererCameraAttributes ) ;
2020-12-03 21:09:47 +00:00
RSG : : scene = sr ;
2020-12-04 18:26:24 +00:00
RSG : : rasterizer = RendererCompositor : : create ( ) ;
2022-06-21 00:08:33 +00:00
RSG : : utilities = RSG : : rasterizer - > get_utilities ( ) ;
2022-04-09 09:34:31 +00:00
RSG : : light_storage = RSG : : rasterizer - > get_light_storage ( ) ;
2022-03-21 11:25:25 +00:00
RSG : : material_storage = RSG : : rasterizer - > get_material_storage ( ) ;
2022-04-02 05:29:04 +00:00
RSG : : mesh_storage = RSG : : rasterizer - > get_mesh_storage ( ) ;
2022-04-12 11:41:50 +00:00
RSG : : particles_storage = RSG : : rasterizer - > get_particles_storage ( ) ;
2022-03-12 11:19:59 +00:00
RSG : : texture_storage = RSG : : rasterizer - > get_texture_storage ( ) ;
2022-05-20 02:52:19 +00:00
RSG : : gi = RSG : : rasterizer - > get_gi ( ) ;
2022-06-21 00:08:33 +00:00
RSG : : fog = RSG : : rasterizer - > get_fog ( ) ;
2020-03-27 18:21:27 +00:00
RSG : : canvas_render = RSG : : rasterizer - > get_canvas ( ) ;
2020-12-31 12:42:56 +00:00
sr - > set_scene_render ( RSG : : rasterizer - > get_scene ( ) ) ;
2017-08-07 21:06:57 +00:00
2019-09-20 20:58:06 +00:00
frame_profile_frame = 0 ;
2016-10-03 19:33:42 +00:00
}
2020-12-03 21:09:47 +00:00
RenderingServerDefault : : ~ RenderingServerDefault ( ) {
2020-03-27 18:21:27 +00:00
memdelete ( RSG : : canvas ) ;
memdelete ( RSG : : viewport ) ;
memdelete ( RSG : : rasterizer ) ;
memdelete ( RSG : : scene ) ;
2022-07-31 23:20:24 +00:00
memdelete ( RSG : : camera_attributes ) ;
2016-10-03 19:33:42 +00:00
}