summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--servers/visual/rasterizer/rasterizer.h120
-rw-r--r--servers/visual/rasterizer/rasterizer_canvas_rd.cpp9
-rw-r--r--servers/visual/visual_server_canvas.cpp79
3 files changed, 126 insertions, 82 deletions
diff --git a/servers/visual/rasterizer/rasterizer.h b/servers/visual/rasterizer/rasterizer.h
index 5f92ffe515..853d02f7c3 100644
--- a/servers/visual/rasterizer/rasterizer.h
+++ b/servers/visual/rasterizer/rasterizer.h
@@ -742,6 +742,18 @@ public:
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;
+ };
+
struct Command {
enum Type {
@@ -757,6 +769,7 @@ public:
TYPE_CLIP_IGNORE,
};
+ Command *next;
Type type;
virtual ~Command() {}
};
@@ -873,7 +886,7 @@ public:
//VS::MaterialBlendMode blend_mode;
int light_mask;
int z_final;
- Vector<Command *> commands;
+
mutable bool custom_rect;
mutable bool rect_dirty;
mutable Rect2 rect;
@@ -905,8 +918,8 @@ public:
return rect;
//must update rect
- int s = commands.size();
- if (s == 0) {
+
+ if (commands == NULL) {
rect = Rect2();
rect_dirty = false;
@@ -917,11 +930,10 @@ public:
bool found_xform = false;
bool first = true;
- const Item::Command *const *cmd = &commands[0];
+ const Item::Command *c = commands;
- for (int i = 0; i < s; i++) {
+ while (c) {
- const Item::Command *c = cmd[i];
Rect2 r;
switch (c->type) {
@@ -983,12 +995,12 @@ public:
const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
xf = transform->xform;
found_xform = true;
- continue;
- } break;
-
- case Item::Command::TYPE_CLIP_IGNORE: {
- } break;
+ } //passthrough
+ default: {
+ c = c->next;
+ continue;
+ }
}
if (found_xform) {
@@ -999,18 +1011,90 @@ public:
if (first) {
rect = r;
first = false;
- } else
+ } else {
rect = rect.merge(r);
+ }
+ c = c->next;
}
rect_dirty = false;
return rect;
}
+ Command *commands;
+ Command *last_command;
+ Vector<CommandBlock> blocks;
+ uint32_t current_block;
+
+ template <class T>
+ T *alloc_command() {
+ T *command;
+ if (commands == NULL) {
+ // 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 = NULL;
+ 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 = NULL;
+ last_command->next = command;
+ last_command = command;
+ c->usage += sizeof(T);
+ break;
+ }
+ }
+
+ rect_dirty = true;
+ return command;
+ }
+
void clear() {
- for (int i = 0; i < commands.size(); i++)
- memdelete(commands[i]);
- commands.clear();
+ Command *c = commands;
+ while (c) {
+ Command *n = c->next;
+ if (c == commands) {
+ memdelete(commands);
+ } else {
+ c->~Command();
+ }
+ c = n;
+ }
+ {
+ uint32_t cbc = MIN((current_block + 1), blocks.size());
+ CommandBlock *blockptr = blocks.ptrw();
+ for (uint32_t i = 0; i < cbc; i++) {
+ blockptr[i].usage = 0;
+ }
+ }
+
+ last_command = NULL;
+ commands = NULL;
+ current_block = 0;
clip = false;
rect_dirty = true;
final_clip_owner = NULL;
@@ -1018,6 +1102,9 @@ public:
light_masked = false;
}
Item() {
+ commands = NULL;
+ last_command = NULL;
+ current_block = 0;
light_mask = 1;
vp_render = NULL;
next = NULL;
@@ -1037,6 +1124,9 @@ public:
}
virtual ~Item() {
clear();
+ for (int i = 0; i < blocks.size(); i++) {
+ memfree(blocks[i].memory);
+ }
if (copy_back_buffer) memdelete(copy_back_buffer);
}
};
diff --git a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
index 4d6910af32..d72be70677 100644
--- a/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
+++ b/servers/visual/rasterizer/rasterizer_canvas_rd.cpp
@@ -495,9 +495,6 @@ Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD:
////////////////////
void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RenderTargetFormat p_render_target_format, RD::TextureSamples p_samples, const Color &p_modulate, const Transform2D &p_canvas_transform_inverse, Item *&current_clip) {
- int cc = p_item->commands.size();
- const Item::Command *const *commands = p_item->commands.ptr();
-
//create an empty push constant
PushConstant push_constant;
Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
@@ -521,9 +518,9 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
bool reclip = false;
- for (int i = 0; i < cc; i++) {
+ const Item::Command *c = p_item->commands;
+ while (c) {
- const Item::Command *c = commands[i];
push_constant.flags = 0; //reset on each command for sanity
switch (c->type) {
@@ -1100,6 +1097,8 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
} break;
}
+
+ c = c->next;
}
if (current_clip && reclip) {
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 95118138dd..6701f12351 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -184,7 +184,7 @@ void VisualServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2
VisualServerRaster::redraw_request();
}
- if ((!ci->commands.empty() && p_clip_rect.intersects_touch(global_rect)) || ci->vp_render || ci->copy_back_buffer) {
+ if ((ci->commands != NULL && p_clip_rect.intersects_touch(global_rect)) || ci->vp_render || ci->copy_back_buffer) {
//something to draw?
ci->final_transform = xform;
ci->final_modulate = Color(modulate.r * ci->self_modulate.r, modulate.g * ci->self_modulate.g, modulate.b * ci->self_modulate.b, modulate.a * ci->self_modulate.a);
@@ -487,7 +487,7 @@ void VisualServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from,
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandPrimitive *line = memnew(Item::CommandPrimitive);
+ Item::CommandPrimitive *line = canvas_item->alloc_command<Item::CommandPrimitive>();
ERR_FAIL_COND(!line);
if (p_width > 1.001) {
@@ -506,9 +506,6 @@ void VisualServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from,
line->colors[i] = p_color;
}
line->specular_shininess = Color(1, 1, 1, 1);
-
- canvas_item->rect_dirty = true;
- canvas_item->commands.push_back(line);
}
void VisualServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
@@ -517,7 +514,7 @@ void VisualServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandPolygon *pline = memnew(Item::CommandPolygon);
+ Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline);
pline->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, RID(), RID(), RID(), VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, RID());
@@ -601,8 +598,6 @@ void VisualServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point
}
#endif
}
- canvas_item->rect_dirty = true;
- canvas_item->commands.push_back(pline);
}
void VisualServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
@@ -611,7 +606,7 @@ void VisualServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Poin
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandPolygon *pline = memnew(Item::CommandPolygon);
+ Item::CommandPolygon *pline = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!pline);
pline->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, RID(), RID(), RID(), VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, RID());
@@ -624,9 +619,6 @@ void VisualServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Poin
pline->polygon.create(Vector<int>(), p_points, p_colors);
} else {
}
-
- canvas_item->rect_dirty = true;
- canvas_item->commands.push_back(pline);
}
void VisualServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) {
@@ -634,13 +626,10 @@ void VisualServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, c
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandRect *rect = memnew(Item::CommandRect);
+ Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>();
ERR_FAIL_COND(!rect);
rect->modulate = p_color;
rect->rect = p_rect;
- canvas_item->rect_dirty = true;
-
- canvas_item->commands.push_back(rect);
}
void VisualServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) {
@@ -648,7 +637,7 @@ void VisualServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos,
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandPolygon *circle = memnew(Item::CommandPolygon);
+ Item::CommandPolygon *circle = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!circle);
circle->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, RID(), RID(), RID(), VS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, VS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED, RID());
@@ -679,9 +668,6 @@ void VisualServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos,
Vector<Color> color;
color.push_back(p_color);
circle->polygon.create(indices, points, color);
-
- canvas_item->rect_dirty = true;
- canvas_item->commands.push_back(circle);
}
void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
@@ -689,7 +675,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandRect *rect = memnew(Item::CommandRect);
+ Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>();
ERR_FAIL_COND(!rect);
rect->modulate = p_modulate;
rect->rect = p_rect;
@@ -716,8 +702,6 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
}
rect->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
rect->specular_shininess = p_specular_color_shininess;
- canvas_item->rect_dirty = true;
- canvas_item->commands.push_back(rect);
}
void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
@@ -725,7 +709,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const R
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandRect *rect = memnew(Item::CommandRect);
+ Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>();
ERR_FAIL_COND(!rect);
rect->modulate = p_modulate;
rect->rect = p_rect;
@@ -763,10 +747,6 @@ void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const R
if (p_clip_uv) {
rect->flags |= RasterizerCanvas::CANVAS_RECT_CLIP_UV;
}
-
- canvas_item->rect_dirty = true;
-
- canvas_item->commands.push_back(rect);
}
void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode, VS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
@@ -774,7 +754,7 @@ void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_r
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandNinePatch *style = memnew(Item::CommandNinePatch);
+ Item::CommandNinePatch *style = canvas_item->alloc_command<Item::CommandNinePatch>();
ERR_FAIL_COND(!style);
style->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
style->specular_shininess = p_specular_color_shininess;
@@ -788,9 +768,6 @@ void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_r
style->margin[MARGIN_BOTTOM] = p_bottomright.y;
style->axis_x = p_x_axis_mode;
style->axis_y = p_y_axis_mode;
- canvas_item->rect_dirty = true;
-
- canvas_item->commands.push_back(style);
}
void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
@@ -800,7 +777,7 @@ void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Poin
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandPrimitive *prim = memnew(Item::CommandPrimitive);
+ Item::CommandPrimitive *prim = canvas_item->alloc_command<Item::CommandPrimitive>();
ERR_FAIL_COND(!prim);
for (int i = 0; i < p_points.size(); i++) {
@@ -821,9 +798,6 @@ void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Poin
prim->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
prim->specular_shininess = p_specular_color_shininess;
- canvas_item->rect_dirty = true;
-
- canvas_item->commands.push_back(prim);
}
void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
@@ -841,16 +815,12 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2
Vector<int> indices = Geometry::triangulate_polygon(p_points);
ERR_FAIL_COND_MSG(indices.empty(), "Invalid polygon data, triangulation failed.");
- Item::CommandPolygon *polygon = memnew(Item::CommandPolygon);
+ Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!polygon);
polygon->primitive = VS::PRIMITIVE_TRIANGLES;
polygon->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
polygon->specular_shininess = p_specular_color_shininess;
polygon->polygon.create(indices, p_points, p_colors, p_uvs);
-
- canvas_item->rect_dirty = true;
-
- canvas_item->commands.push_back(polygon);
}
void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
@@ -867,16 +837,13 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector
const Vector<int> &indices = p_indices;
- Item::CommandPolygon *polygon = memnew(Item::CommandPolygon);
+ Item::CommandPolygon *polygon = canvas_item->alloc_command<Item::CommandPolygon>();
ERR_FAIL_COND(!polygon);
polygon->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
polygon->specular_shininess = p_specular_color_shininess;
polygon->polygon.create(indices, p_points, p_colors, p_uvs, p_bones, p_weights);
polygon->primitive = VS::PRIMITIVE_TRIANGLES;
- canvas_item->rect_dirty = true;
-
- canvas_item->commands.push_back(polygon);
}
void VisualServerCanvas::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) {
@@ -884,11 +851,9 @@ void VisualServerCanvas::canvas_item_add_set_transform(RID p_item, const Transfo
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandTransform *tr = memnew(Item::CommandTransform);
+ Item::CommandTransform *tr = canvas_item->alloc_command<Item::CommandTransform>();
ERR_FAIL_COND(!tr);
tr->xform = p_transform;
-
- canvas_item->commands.push_back(tr);
}
void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
@@ -896,22 +861,20 @@ void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, con
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandMesh *m = memnew(Item::CommandMesh);
+ Item::CommandMesh *m = canvas_item->alloc_command<Item::CommandMesh>();
ERR_FAIL_COND(!m);
m->mesh = p_mesh;
m->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
m->specular_shininess = p_specular_color_shininess;
m->transform = p_transform;
m->modulate = p_modulate;
-
- canvas_item->commands.push_back(m);
}
void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandParticles *part = memnew(Item::CommandParticles);
+ Item::CommandParticles *part = canvas_item->alloc_command<Item::CommandParticles>();
ERR_FAIL_COND(!part);
part->particles = p_particles;
part->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, RID());
@@ -919,9 +882,6 @@ void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles,
//take the chance and request processing for them, at least once until they become visible again
VSG::storage->particles_request_process(p_particles);
-
- canvas_item->rect_dirty = true;
- canvas_item->commands.push_back(part);
}
void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, VisualServer::CanvasItemTextureFilter p_filter, VisualServer::CanvasItemTextureRepeat p_repeat) {
@@ -929,14 +889,11 @@ void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandMultiMesh *mm = memnew(Item::CommandMultiMesh);
+ Item::CommandMultiMesh *mm = canvas_item->alloc_command<Item::CommandMultiMesh>();
ERR_FAIL_COND(!mm);
mm->multimesh = p_mesh;
mm->texture_binding.create(canvas_item->texture_filter, canvas_item->texture_repeat, p_texture, p_normal_map, p_specular_map, p_filter, p_repeat, mm->multimesh);
mm->specular_shininess = p_specular_color_shininess;
-
- canvas_item->rect_dirty = true;
- canvas_item->commands.push_back(mm);
}
void VisualServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) {
@@ -944,11 +901,9 @@ void VisualServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore)
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
- Item::CommandClipIgnore *ci = memnew(Item::CommandClipIgnore);
+ Item::CommandClipIgnore *ci = canvas_item->alloc_command<Item::CommandClipIgnore>();
ERR_FAIL_COND(!ci);
ci->ignore = p_ignore;
-
- canvas_item->commands.push_back(ci);
}
void VisualServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {