You've already forked godot
							
							
				mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-04 12:00:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			561 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			561 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**************************************************************************/
 | 
						|
/*  renderer_canvas_render.h                                              */
 | 
						|
/**************************************************************************/
 | 
						|
/*                         This file is part of:                          */
 | 
						|
/*                             GODOT ENGINE                               */
 | 
						|
/*                        https://godotengine.org                         */
 | 
						|
/**************************************************************************/
 | 
						|
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
 | 
						|
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
 | 
						|
/*                                                                        */
 | 
						|
/* 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.                 */
 | 
						|
/**************************************************************************/
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include "servers/rendering/rendering_method.h"
 | 
						|
#include "servers/rendering/rendering_server.h"
 | 
						|
 | 
						|
class RendererCanvasRender {
 | 
						|
public:
 | 
						|
	static RendererCanvasRender *singleton;
 | 
						|
 | 
						|
	enum CanvasRectFlags {
 | 
						|
		CANVAS_RECT_REGION = 1,
 | 
						|
		CANVAS_RECT_TILE = 2,
 | 
						|
		CANVAS_RECT_FLIP_H = 4,
 | 
						|
		CANVAS_RECT_FLIP_V = 8,
 | 
						|
		CANVAS_RECT_TRANSPOSE = 16,
 | 
						|
		CANVAS_RECT_CLIP_UV = 32,
 | 
						|
		CANVAS_RECT_IS_GROUP = 64,
 | 
						|
		CANVAS_RECT_MSDF = 128,
 | 
						|
		CANVAS_RECT_LCD = 256,
 | 
						|
	};
 | 
						|
 | 
						|
	struct Light {
 | 
						|
		bool enabled : 1;
 | 
						|
		bool on_interpolate_transform_list : 1;
 | 
						|
		bool interpolated : 1;
 | 
						|
		Color color;
 | 
						|
		Transform2D xform_curr;
 | 
						|
		Transform2D xform_prev;
 | 
						|
		float height;
 | 
						|
		float energy;
 | 
						|
		float scale;
 | 
						|
		int z_min;
 | 
						|
		int z_max;
 | 
						|
		int layer_min;
 | 
						|
		int layer_max;
 | 
						|
		int item_mask;
 | 
						|
		int item_shadow_mask;
 | 
						|
		float directional_distance;
 | 
						|
		RS::CanvasLightMode mode;
 | 
						|
		RS::CanvasLightBlendMode blend_mode;
 | 
						|
		RID texture;
 | 
						|
		Vector2 texture_offset;
 | 
						|
		RID canvas;
 | 
						|
		bool use_shadow;
 | 
						|
		int shadow_buffer_size;
 | 
						|
		RS::CanvasLightShadowFilter shadow_filter;
 | 
						|
		Color shadow_color;
 | 
						|
		float shadow_smooth;
 | 
						|
 | 
						|
		//void *texture_cache; // implementation dependent
 | 
						|
		Rect2 rect_cache;
 | 
						|
		Transform2D xform_cache;
 | 
						|
		float radius_cache; //used for shadow far plane
 | 
						|
		//Projection shadow_matrix_cache;
 | 
						|
 | 
						|
		Transform2D light_shader_xform;
 | 
						|
		//Vector2 light_shader_pos;
 | 
						|
 | 
						|
		Light *shadows_next_ptr = nullptr;
 | 
						|
		Light *filter_next_ptr = nullptr;
 | 
						|
		Light *next_ptr = nullptr;
 | 
						|
		Light *directional_next_ptr = nullptr;
 | 
						|
 | 
						|
		RID light_internal;
 | 
						|
		uint64_t version;
 | 
						|
 | 
						|
		int32_t render_index_cache;
 | 
						|
 | 
						|
		Light() {
 | 
						|
			version = 0;
 | 
						|
			enabled = true;
 | 
						|
			on_interpolate_transform_list = false;
 | 
						|
			interpolated = true;
 | 
						|
			color = Color(1, 1, 1);
 | 
						|
			shadow_color = Color(0, 0, 0, 0);
 | 
						|
			height = 0;
 | 
						|
			z_min = -1024;
 | 
						|
			z_max = 1024;
 | 
						|
			layer_min = 0;
 | 
						|
			layer_max = 0;
 | 
						|
			item_mask = 1;
 | 
						|
			scale = 1.0;
 | 
						|
			energy = 1.0;
 | 
						|
			item_shadow_mask = 1;
 | 
						|
			mode = RS::CANVAS_LIGHT_MODE_POINT;
 | 
						|
			blend_mode = RS::CANVAS_LIGHT_BLEND_MODE_ADD;
 | 
						|
			//			texture_cache = nullptr;
 | 
						|
			next_ptr = nullptr;
 | 
						|
			directional_next_ptr = nullptr;
 | 
						|
			filter_next_ptr = nullptr;
 | 
						|
			use_shadow = false;
 | 
						|
			shadow_buffer_size = 2048;
 | 
						|
			shadow_filter = RS::CANVAS_LIGHT_FILTER_NONE;
 | 
						|
			shadow_smooth = 0.0;
 | 
						|
			render_index_cache = -1;
 | 
						|
			directional_distance = 10000.0;
 | 
						|
		}
 | 
						|
	};
 | 
						|
 | 
						|
	//easier wrap to avoid mistakes
 | 
						|
 | 
						|
	typedef uint64_t PolygonID;
 | 
						|
	virtual PolygonID request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), int p_count = -1) = 0;
 | 
						|
	virtual void free_polygon(PolygonID p_polygon) = 0;
 | 
						|
 | 
						|
	//also easier to wrap to avoid mistakes
 | 
						|
	struct Polygon {
 | 
						|
		PolygonID polygon_id;
 | 
						|
		Rect2 rect_cache;
 | 
						|
 | 
						|
		_FORCE_INLINE_ void create(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), const Vector<int> &p_bones = Vector<int>(), const Vector<float> &p_weights = Vector<float>(), int p_count = -1) {
 | 
						|
			ERR_FAIL_COND(polygon_id != 0);
 | 
						|
			int count = p_count < 0 ? p_indices.size() : p_count * 3;
 | 
						|
			ERR_FAIL_COND(count > p_indices.size());
 | 
						|
			{
 | 
						|
				uint32_t pc = p_points.size();
 | 
						|
				const Vector2 *v2 = p_points.ptr();
 | 
						|
				rect_cache.position = *v2;
 | 
						|
				for (uint32_t i = 1; i < pc; i++) {
 | 
						|
					rect_cache.expand_to(v2[i]);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			polygon_id = singleton->request_polygon(p_indices, p_points, p_colors, p_uvs, p_bones, p_weights, count);
 | 
						|
		}
 | 
						|
 | 
						|
		_FORCE_INLINE_ Polygon() { polygon_id = 0; }
 | 
						|
		_FORCE_INLINE_ ~Polygon() {
 | 
						|
			if (polygon_id) {
 | 
						|
				singleton->free_polygon(polygon_id);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	};
 | 
						|
 | 
						|
	//item
 | 
						|
 | 
						|
	struct Item {
 | 
						|
		//commands are allocated in blocks of 4k to improve performance
 | 
						|
		//and cache coherence.
 | 
						|
		//blocks always grow but never shrink.
 | 
						|
 | 
						|
		struct CommandBlock {
 | 
						|
			enum {
 | 
						|
				MAX_SIZE = 4096
 | 
						|
			};
 | 
						|
			uint32_t usage;
 | 
						|
			uint8_t *memory = nullptr;
 | 
						|
		};
 | 
						|
 | 
						|
		struct Command {
 | 
						|
			enum Type {
 | 
						|
				TYPE_RECT,
 | 
						|
				TYPE_NINEPATCH,
 | 
						|
				TYPE_POLYGON,
 | 
						|
				TYPE_PRIMITIVE,
 | 
						|
				TYPE_MESH,
 | 
						|
				TYPE_MULTIMESH,
 | 
						|
				TYPE_PARTICLES,
 | 
						|
				TYPE_TRANSFORM,
 | 
						|
				TYPE_CLIP_IGNORE,
 | 
						|
				TYPE_ANIMATION_SLICE,
 | 
						|
			};
 | 
						|
 | 
						|
			Command *next = nullptr;
 | 
						|
			Type type;
 | 
						|
			virtual ~Command() {}
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandRect : public Command {
 | 
						|
			Rect2 rect;
 | 
						|
			Color modulate;
 | 
						|
			Rect2 source;
 | 
						|
			uint16_t flags;
 | 
						|
			float outline;
 | 
						|
			float px_range;
 | 
						|
 | 
						|
			RID texture;
 | 
						|
 | 
						|
			CommandRect() {
 | 
						|
				flags = 0;
 | 
						|
				outline = 0;
 | 
						|
				px_range = 1;
 | 
						|
				type = TYPE_RECT;
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandNinePatch : public Command {
 | 
						|
			Rect2 rect;
 | 
						|
			Rect2 source;
 | 
						|
			float margin[4];
 | 
						|
			bool draw_center;
 | 
						|
			Color color;
 | 
						|
			RS::NinePatchAxisMode axis_x;
 | 
						|
			RS::NinePatchAxisMode axis_y;
 | 
						|
 | 
						|
			RID texture;
 | 
						|
 | 
						|
			CommandNinePatch() {
 | 
						|
				draw_center = true;
 | 
						|
				type = TYPE_NINEPATCH;
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandPolygon : public Command {
 | 
						|
			RS::PrimitiveType primitive;
 | 
						|
			Polygon polygon;
 | 
						|
 | 
						|
			RID texture;
 | 
						|
 | 
						|
			CommandPolygon() {
 | 
						|
				type = TYPE_POLYGON;
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandPrimitive : public Command {
 | 
						|
			uint32_t point_count;
 | 
						|
			Vector2 points[4];
 | 
						|
			Vector2 uvs[4];
 | 
						|
			Color colors[4];
 | 
						|
 | 
						|
			RID texture;
 | 
						|
 | 
						|
			CommandPrimitive() {
 | 
						|
				type = TYPE_PRIMITIVE;
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandMesh : public Command {
 | 
						|
			RID mesh;
 | 
						|
			Transform2D transform;
 | 
						|
			Color modulate;
 | 
						|
			RID mesh_instance;
 | 
						|
 | 
						|
			RID texture;
 | 
						|
 | 
						|
			CommandMesh() { type = TYPE_MESH; }
 | 
						|
			~CommandMesh();
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandMultiMesh : public Command {
 | 
						|
			RID multimesh;
 | 
						|
 | 
						|
			RID texture;
 | 
						|
 | 
						|
			CommandMultiMesh() { type = TYPE_MULTIMESH; }
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandParticles : public Command {
 | 
						|
			RID particles;
 | 
						|
			RID texture;
 | 
						|
 | 
						|
			CommandParticles() { type = TYPE_PARTICLES; }
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandTransform : public Command {
 | 
						|
			Transform2D xform;
 | 
						|
			CommandTransform() { type = TYPE_TRANSFORM; }
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandClipIgnore : public Command {
 | 
						|
			bool ignore;
 | 
						|
			CommandClipIgnore() {
 | 
						|
				type = TYPE_CLIP_IGNORE;
 | 
						|
				ignore = false;
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		struct CommandAnimationSlice : public Command {
 | 
						|
			double animation_length = 0;
 | 
						|
			double slice_begin = 0;
 | 
						|
			double slice_end = 0;
 | 
						|
			double offset = 0;
 | 
						|
 | 
						|
			CommandAnimationSlice() {
 | 
						|
				type = TYPE_ANIMATION_SLICE;
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		struct ViewportRender {
 | 
						|
			RenderingServer *owner = nullptr;
 | 
						|
			void *udata = nullptr;
 | 
						|
			Rect2 rect;
 | 
						|
		};
 | 
						|
 | 
						|
		// For interpolation we store the current local xform,
 | 
						|
		// and the previous xform from the previous tick.
 | 
						|
		Transform2D xform_curr;
 | 
						|
		Transform2D xform_prev;
 | 
						|
 | 
						|
		bool clip : 1;
 | 
						|
		bool visible : 1;
 | 
						|
		bool behind : 1;
 | 
						|
		bool update_when_visible : 1;
 | 
						|
		bool on_interpolate_transform_list : 1;
 | 
						|
		bool interpolated : 1;
 | 
						|
		bool use_identity_transform : 1;
 | 
						|
 | 
						|
		struct CanvasGroup {
 | 
						|
			RS::CanvasGroupMode mode;
 | 
						|
			bool fit_empty;
 | 
						|
			float fit_margin;
 | 
						|
			bool blur_mipmaps;
 | 
						|
			float clear_margin;
 | 
						|
		};
 | 
						|
 | 
						|
		CanvasGroup *canvas_group = nullptr;
 | 
						|
		bool use_canvas_group = false;
 | 
						|
		int light_mask;
 | 
						|
		int z_final;
 | 
						|
 | 
						|
		mutable bool custom_rect;
 | 
						|
		mutable bool rect_dirty;
 | 
						|
		mutable Rect2 rect;
 | 
						|
		RID material;
 | 
						|
		RID skeleton;
 | 
						|
 | 
						|
		int32_t instance_allocated_shader_uniforms_offset = -1;
 | 
						|
 | 
						|
		Item *next = nullptr;
 | 
						|
 | 
						|
		struct CopyBackBuffer {
 | 
						|
			Rect2 rect;
 | 
						|
			Rect2 screen_rect;
 | 
						|
			bool full;
 | 
						|
		};
 | 
						|
		CopyBackBuffer *copy_back_buffer = nullptr;
 | 
						|
 | 
						|
		Color final_modulate;
 | 
						|
		Transform2D final_transform;
 | 
						|
		Rect2 final_clip_rect;
 | 
						|
		Item *final_clip_owner = nullptr;
 | 
						|
		Item *material_owner = nullptr;
 | 
						|
		Item *canvas_group_owner = nullptr;
 | 
						|
		ViewportRender *vp_render = nullptr;
 | 
						|
		bool distance_field;
 | 
						|
		bool light_masked;
 | 
						|
		bool repeat_source;
 | 
						|
		Point2 repeat_size;
 | 
						|
		int repeat_times = 1;
 | 
						|
		Item *repeat_source_item = nullptr;
 | 
						|
 | 
						|
		Rect2 global_rect_cache;
 | 
						|
 | 
						|
		const Rect2 &get_rect() const;
 | 
						|
 | 
						|
		Command *commands = nullptr;
 | 
						|
		Command *last_command = nullptr;
 | 
						|
		Vector<CommandBlock> blocks;
 | 
						|
		uint32_t current_block;
 | 
						|
#ifdef DEBUG_ENABLED
 | 
						|
		mutable double debug_redraw_time = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
		template <typename T>
 | 
						|
		T *alloc_command() {
 | 
						|
			T *command = nullptr;
 | 
						|
			if (commands == nullptr) {
 | 
						|
				// As the most common use case of canvas items is to
 | 
						|
				// use only one command, the first is done with it's
 | 
						|
				// own allocation. The rest of them use blocks.
 | 
						|
				command = memnew(T);
 | 
						|
				command->next = nullptr;
 | 
						|
				commands = command;
 | 
						|
				last_command = command;
 | 
						|
			} else {
 | 
						|
				//Subsequent commands go into a block.
 | 
						|
 | 
						|
				while (true) {
 | 
						|
					if (unlikely(current_block == (uint32_t)blocks.size())) {
 | 
						|
						// If we need more blocks, we allocate them
 | 
						|
						// (they won't be freed until this CanvasItem is
 | 
						|
						// deleted, though).
 | 
						|
						CommandBlock cb;
 | 
						|
						cb.memory = (uint8_t *)memalloc(CommandBlock::MAX_SIZE);
 | 
						|
						cb.usage = 0;
 | 
						|
						blocks.push_back(cb);
 | 
						|
					}
 | 
						|
 | 
						|
					CommandBlock *c = &blocks.write[current_block];
 | 
						|
					size_t space_left = CommandBlock::MAX_SIZE - c->usage;
 | 
						|
					if (space_left < sizeof(T)) {
 | 
						|
						current_block++;
 | 
						|
						continue;
 | 
						|
					}
 | 
						|
 | 
						|
					//allocate block and add to the linked list
 | 
						|
					void *memory = c->memory + c->usage;
 | 
						|
					command = memnew_placement(memory, T);
 | 
						|
					command->next = nullptr;
 | 
						|
					last_command->next = command;
 | 
						|
					last_command = command;
 | 
						|
					c->usage += sizeof(T);
 | 
						|
					break;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			rect_dirty = true;
 | 
						|
			return command;
 | 
						|
		}
 | 
						|
 | 
						|
		void clear() {
 | 
						|
			// The first one is always allocated on heap
 | 
						|
			// the rest go in the blocks
 | 
						|
			Command *c = commands;
 | 
						|
			while (c) {
 | 
						|
				Command *n = c->next;
 | 
						|
				if (c == commands) {
 | 
						|
					memdelete(commands);
 | 
						|
					commands = nullptr;
 | 
						|
				} else {
 | 
						|
					c->~Command();
 | 
						|
				}
 | 
						|
				c = n;
 | 
						|
			}
 | 
						|
			{
 | 
						|
				uint32_t cbc = MIN((current_block + 1), (uint32_t)blocks.size());
 | 
						|
				CommandBlock *blockptr = blocks.ptrw();
 | 
						|
				for (uint32_t i = 0; i < cbc; i++) {
 | 
						|
					blockptr[i].usage = 0;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			last_command = nullptr;
 | 
						|
			commands = nullptr;
 | 
						|
			current_block = 0;
 | 
						|
			clip = false;
 | 
						|
			rect_dirty = true;
 | 
						|
			final_clip_owner = nullptr;
 | 
						|
			material_owner = nullptr;
 | 
						|
			light_masked = false;
 | 
						|
		}
 | 
						|
 | 
						|
		RS::CanvasItemTextureFilter texture_filter;
 | 
						|
		RS::CanvasItemTextureRepeat texture_repeat;
 | 
						|
 | 
						|
		Item() {
 | 
						|
			commands = nullptr;
 | 
						|
			last_command = nullptr;
 | 
						|
			current_block = 0;
 | 
						|
			light_mask = 1;
 | 
						|
			vp_render = nullptr;
 | 
						|
			next = nullptr;
 | 
						|
			final_clip_owner = nullptr;
 | 
						|
			canvas_group_owner = nullptr;
 | 
						|
			clip = false;
 | 
						|
			final_modulate = Color(1, 1, 1, 1);
 | 
						|
			visible = true;
 | 
						|
			rect_dirty = true;
 | 
						|
			custom_rect = false;
 | 
						|
			behind = false;
 | 
						|
			material_owner = nullptr;
 | 
						|
			copy_back_buffer = nullptr;
 | 
						|
			distance_field = false;
 | 
						|
			light_masked = false;
 | 
						|
			update_when_visible = false;
 | 
						|
			z_final = 0;
 | 
						|
			texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
 | 
						|
			texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
 | 
						|
			repeat_source = false;
 | 
						|
			on_interpolate_transform_list = false;
 | 
						|
			interpolated = true;
 | 
						|
			use_identity_transform = false;
 | 
						|
		}
 | 
						|
		virtual ~Item() {
 | 
						|
			clear();
 | 
						|
			for (int i = 0; i < blocks.size(); i++) {
 | 
						|
				memfree(blocks[i].memory);
 | 
						|
			}
 | 
						|
			if (copy_back_buffer) {
 | 
						|
				memdelete(copy_back_buffer);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	};
 | 
						|
 | 
						|
	virtual void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0;
 | 
						|
 | 
						|
	struct LightOccluderInstance {
 | 
						|
		bool enabled : 1;
 | 
						|
		bool on_interpolate_transform_list : 1;
 | 
						|
		bool interpolated : 1;
 | 
						|
		RID canvas;
 | 
						|
		RID polygon;
 | 
						|
		RID occluder;
 | 
						|
		Rect2 aabb_cache;
 | 
						|
		Transform2D xform_curr;
 | 
						|
		Transform2D xform_prev;
 | 
						|
		Transform2D xform_cache;
 | 
						|
		int light_mask;
 | 
						|
		bool sdf_collision;
 | 
						|
		RS::CanvasOccluderPolygonCullMode cull_cache;
 | 
						|
 | 
						|
		LightOccluderInstance *next = nullptr;
 | 
						|
 | 
						|
		LightOccluderInstance() {
 | 
						|
			enabled = true;
 | 
						|
			on_interpolate_transform_list = false;
 | 
						|
			interpolated = false;
 | 
						|
			sdf_collision = false;
 | 
						|
			next = nullptr;
 | 
						|
			light_mask = 1;
 | 
						|
			cull_cache = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
 | 
						|
		}
 | 
						|
	};
 | 
						|
 | 
						|
	virtual RID light_create() = 0;
 | 
						|
	virtual void light_set_texture(RID p_rid, RID p_texture) = 0;
 | 
						|
	virtual void light_set_use_shadow(RID p_rid, bool p_enable) = 0;
 | 
						|
	virtual void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, const Rect2 &p_light_rect) = 0;
 | 
						|
	virtual void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) = 0;
 | 
						|
 | 
						|
	virtual void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) = 0;
 | 
						|
 | 
						|
	virtual RID occluder_polygon_create() = 0;
 | 
						|
	virtual void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) = 0;
 | 
						|
	virtual void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) = 0;
 | 
						|
	virtual void set_shadow_texture_size(int p_size) = 0;
 | 
						|
 | 
						|
	virtual bool free(RID p_rid) = 0;
 | 
						|
	virtual void update() = 0;
 | 
						|
 | 
						|
	virtual void set_debug_redraw(bool p_enabled, double p_time, const Color &p_color) = 0;
 | 
						|
	virtual uint32_t get_pipeline_compilations(RS::PipelineSource p_source) = 0;
 | 
						|
 | 
						|
	RendererCanvasRender() {
 | 
						|
		ERR_FAIL_COND_MSG(singleton != nullptr, "A RendererCanvasRender singleton already exists.");
 | 
						|
		singleton = this;
 | 
						|
	}
 | 
						|
	virtual ~RendererCanvasRender() {
 | 
						|
		singleton = nullptr;
 | 
						|
	}
 | 
						|
};
 |