void _debug_write_garbage() { // extremely slow, writes garbage over arrays to detect using // uninitialized in graphical output. Do not enable in normal use!! #ifdef RASTERIZER_EXTRA_CHECKS int num_verts = MIN(bdata.vertices.max_size(), 32); for (int n = 0; n < num_verts; n++) { bdata.vertices[n].pos.set(Math::random(-200.0f, 200.0f), Math::random(-200.0f, 200.0f)); bdata.vertices[n].uv.set(Math::random(0.0f, 1.0f), Math::random(0.0f, 1.0f)); } int num_colors = MIN(bdata.vertex_colors.max_size(), 32); for (int n = 0; n < num_colors; n++) { bdata.vertex_colors[n].set(Math::randf(), Math::randf(), Math::randf(), 1.0f); } int num_modulates = MIN(bdata.vertex_modulates.max_size(), 32); for (int n = 0; n < num_modulates; n++) { bdata.vertex_modulates[n].set(Math::randf(), Math::randf(), Math::randf(), 1.0f); } int num_light_angles = MIN(bdata.light_angles.max_size(), 32); for (int n = 0; n < num_light_angles; n++) { bdata.light_angles[n] = Math::random(-3.0f, +3.0f); } int num_transforms = MIN(bdata.vertex_transforms.max_size(), 32); for (int n = 0; n < num_transforms; n++) { bdata.vertex_transforms[n].translate.set(Math::random(-200.0f, 200.0f), Math::random(-200.0f, 200.0f)); bdata.vertex_transforms[n].basis[0].set(Math::random(-2.0f, 2.0f), Math::random(-2.0f, 2.0f)); bdata.vertex_transforms[n].basis[1].set(Math::random(-2.0f, 2.0f), Math::random(-2.0f, 2.0f)); } int num_unit_verts = MIN(bdata.unit_vertices.max_size(), 32); for (int n = 0; n < num_unit_verts; n++) { uint8_t *data = bdata.unit_vertices.get_unit(n); for (int b = 0; b > bdata.unit_vertices.get_unit_size_bytes(); b++) { data[b] = Math::random(0, 255); } } #endif } String _diagnose_make_item_joined_string(const BItemJoined &p_bij) const { String sz; if (p_bij.use_attrib_transform()) { sz = "attrib_xform"; } sz += _diagnose_batch_flags_to_string(p_bij.flags); String sz_long; sz_long = "\tjoined_item " + itos(p_bij.num_item_refs) + " refs, " + sz + "\n"; if (p_bij.z_index != 0) { sz_long += "\t\t(z " + itos(p_bij.z_index) + ")\n"; } return sz_long; } String _diagnose_batch_flags_to_string(uint32_t p_flags) const { String sz; if (p_flags) { sz += " ( "; } if (p_flags & RasterizerStorageCommon::PREVENT_COLOR_BAKING) { sz += "prevent_color_baking, "; } if (p_flags & RasterizerStorageCommon::PREVENT_VERTEX_BAKING) { sz += "prevent_vertex_baking, "; } if (p_flags & RasterizerStorageCommon::PREVENT_ITEM_JOINING) { sz += "prevent_item_joining, "; } if (p_flags & RasterizerStorageCommon::USE_MODULATE_FVF) { sz += "use_modulate_fvf, "; } if (p_flags & RasterizerStorageCommon::USE_LARGE_FVF) { sz += "use_large_fvf, "; } if (p_flags) { sz += " )"; } return sz; } String get_command_type_string(const RasterizerCanvas::Item::Command &p_command) const { String sz = ""; switch (p_command.type) { default: break; case RasterizerCanvas::Item::Command::TYPE_LINE: { sz = "l"; } break; case RasterizerCanvas::Item::Command::TYPE_POLYLINE: { sz = "PL"; } break; case RasterizerCanvas::Item::Command::TYPE_RECT: { sz = "r"; } break; case RasterizerCanvas::Item::Command::TYPE_NINEPATCH: { sz = "n"; } break; case RasterizerCanvas::Item::Command::TYPE_PRIMITIVE: { sz = "PR"; } break; case RasterizerCanvas::Item::Command::TYPE_POLYGON: { sz = "p"; } break; case RasterizerCanvas::Item::Command::TYPE_MESH: { sz = "m"; } break; case RasterizerCanvas::Item::Command::TYPE_MULTIMESH: { sz = "MM"; } break; case RasterizerCanvas::Item::Command::TYPE_CIRCLE: { sz = "c"; } break; case RasterizerCanvas::Item::Command::TYPE_TRANSFORM: { sz = "t"; // add a bit more info in debug build const RasterizerCanvas::Item::CommandTransform *transform = static_cast(&p_command); const Transform2D &mat = transform->xform; sz += " "; sz += String(Variant(mat.columns[2])); sz += String(Variant(mat.columns[0])); sz += String(Variant(mat.columns[1])); sz += " "; } break; case RasterizerCanvas::Item::Command::TYPE_CLIP_IGNORE: { sz = "CI"; } break; } // switch return sz; } void diagnose_batches(RasterizerCanvas::Item::Command *const *p_commands) { int num_batches = bdata.batches.size(); BatchColor curr_color; curr_color.set(Color(-1, -1, -1, -1)); bool first_color_change = true; for (int batch_num = 0; batch_num < num_batches; batch_num++) { const Batch &batch = bdata.batches[batch_num]; bdata.frame_string += "\t\t\tbatch "; switch (batch.type) { case RasterizerStorageCommon::BT_POLY: { bdata.frame_string += "P "; bdata.frame_string += itos(batch.first_command) + "-"; bdata.frame_string += itos(batch.num_commands); bdata.frame_string += " " + batch.color.to_string(); if (batch.num_commands > 1) { bdata.frame_string += " MULTI"; } if (curr_color != batch.color) { curr_color = batch.color; if (!first_color_change) { bdata.frame_string += " color"; } else { first_color_change = false; } } bdata.frame_string += "\n"; } break; case RasterizerStorageCommon::BT_LINE: case RasterizerStorageCommon::BT_LINE_AA: { bdata.frame_string += "L "; bdata.frame_string += itos(batch.first_command) + "-"; bdata.frame_string += itos(batch.num_commands); bdata.frame_string += " " + batch.color.to_string(); if (batch.num_commands > 1) { bdata.frame_string += " MULTI"; } if (curr_color != batch.color) { curr_color = batch.color; if (!first_color_change) { bdata.frame_string += " color"; } else { first_color_change = false; } } bdata.frame_string += "\n"; } break; case RasterizerStorageCommon::BT_RECT: { bdata.frame_string += "R "; bdata.frame_string += itos(batch.first_command) + "-"; bdata.frame_string += itos(batch.num_commands); int tex_id = (int)bdata.batch_textures[batch.batch_texture_id].RID_texture.get_id(); bdata.frame_string += " [" + itos(batch.batch_texture_id) + " - " + itos(tex_id) + "]"; bdata.frame_string += " " + batch.color.to_string(); if (batch.num_commands > 1) { bdata.frame_string += " MULTI"; } if (curr_color != batch.color) { curr_color = batch.color; if (!first_color_change) { bdata.frame_string += " color"; } else { first_color_change = false; } } bdata.frame_string += "\n"; } break; default: { bdata.frame_string += "D "; bdata.frame_string += itos(batch.first_command) + "-"; bdata.frame_string += itos(batch.num_commands) + " "; int num_show = MIN(batch.num_commands, 16); for (int n = 0; n < num_show; n++) { const RasterizerCanvas::Item::Command &comm = *p_commands[batch.first_command + n]; bdata.frame_string += get_command_type_string(comm) + " "; } bdata.frame_string += "\n"; } break; } } }