Merge pull request #44340 from lawnjelly/ninepatch_zerosize

Batching - Protection against zero and small sized ninepatches
This commit is contained in:
Rémi Verschelde 2020-12-20 19:50:01 +01:00 committed by GitHub
commit 542acc8580
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1357,6 +1357,22 @@ template <bool SEND_LIGHT_ANGLES>
bool C_PREAMBLE::_prefill_ninepatch(RasterizerCanvas::Item::CommandNinePatch *p_np, FillState &r_fill_state, int &r_command_start, int command_num, int command_count, RasterizerCanvas::Item *p_item, bool multiply_final_modulate) { bool C_PREAMBLE::_prefill_ninepatch(RasterizerCanvas::Item::CommandNinePatch *p_np, FillState &r_fill_state, int &r_command_start, int command_num, int command_count, RasterizerCanvas::Item *p_item, bool multiply_final_modulate) {
typename T_STORAGE::Texture *tex = get_storage()->texture_owner.getornull(p_np->texture); typename T_STORAGE::Texture *tex = get_storage()->texture_owner.getornull(p_np->texture);
if (!tex) {
// FIXME: Handle textureless ninepatch gracefully
WARN_PRINT("NinePatch without texture not supported yet, skipping.");
return false;
}
if (tex->width == 0 || tex->height == 0) {
WARN_PRINT("Cannot set empty texture to NinePatch.");
return false;
}
// cope with ninepatch of zero area. These cannot be created by the user interface or gdscript, but can
// be created programmatically from c++, e.g. by the Godot UI for sliders. We will just not draw these.
if ((p_np->rect.size.x * p_np->rect.size.y) <= 0.0f) {
return false;
}
// conditions for creating a new batch // conditions for creating a new batch
if (r_fill_state.curr_batch->type != RasterizerStorageCommon::BT_RECT) { if (r_fill_state.curr_batch->type != RasterizerStorageCommon::BT_RECT) {
@ -1368,16 +1384,6 @@ bool C_PREAMBLE::_prefill_ninepatch(RasterizerCanvas::Item::CommandNinePatch *p_
} }
} }
if (!tex) {
// FIXME: Handle textureless ninepatch gracefully
WARN_PRINT("NinePatch without texture not supported yet in GLES2 backend, skipping.");
return false;
}
if (tex->width == 0 || tex->height == 0) {
WARN_PRINT("Cannot set empty texture to NinePatch.");
return false;
}
// first check there are enough verts for this to complete successfully // first check there are enough verts for this to complete successfully
if (bdata.vertices.size() + (4 * 9) > bdata.vertices.max_size()) { if (bdata.vertices.size() + (4 * 9) > bdata.vertices.max_size()) {
// return where we got to // return where we got to
@ -1446,6 +1452,17 @@ bool C_PREAMBLE::_prefill_ninepatch(RasterizerCanvas::Item::CommandNinePatch *p_
v[3] = v[0] + source.size.y; v[3] = v[0] + source.size.y;
v[2] = v[3] - tex_margin_bottom; v[2] = v[3] - tex_margin_bottom;
// Some protection for the use of ninepatches with rect size smaller than margin size.
// Note these cannot be produced by the UI, only programmatically, and the results
// are somewhat undefined, because the margins overlap.
// Ninepatch get_minimum_size() forces minimum size to be the sum of the margins.
// So this should occur very rarely if ever. Consider commenting these 4 lines out for higher speed
// in ninepatches.
x[1] = MIN(x[1], x[3]);
x[2] = MIN(x[2], x[3]);
y[1] = MIN(y[1], y[3]);
y[2] = MIN(y[2], y[3]);
// temporarily override to prevent single rect fallback // temporarily override to prevent single rect fallback
bool single_rect_fallback = bdata.settings_use_single_rect_fallback; bool single_rect_fallback = bdata.settings_use_single_rect_fallback;
bdata.settings_use_single_rect_fallback = false; bdata.settings_use_single_rect_fallback = false;