| 1478 | } |
| 1479 | |
| 1480 | static void UpdateScope(InternalNode* node, StencilScope& scope, StencilScope& child_scope, const StencilScope* parent_scope, uint16_t index, uint16_t non_inv_clipper_count, uint16_t inv_clipper_count, uint16_t bit_field_offset) { |
| 1481 | int bit_range = CalcBitRange(non_inv_clipper_count); |
| 1482 | // state used for drawing the clipper |
| 1483 | scope.m_WriteMask = 0xff; |
| 1484 | scope.m_TestMask = 0; |
| 1485 | if (parent_scope != 0x0) { |
| 1486 | scope.m_TestMask = parent_scope->m_TestMask; |
| 1487 | } |
| 1488 | bool inverted = node->m_Node.m_ClippingInverted; |
| 1489 | if (!inverted) { |
| 1490 | scope.m_RefVal = (index + 1) << bit_field_offset; |
| 1491 | if (parent_scope != 0x0) { |
| 1492 | scope.m_RefVal |= parent_scope->m_RefVal; |
| 1493 | } |
| 1494 | } else { |
| 1495 | if (index >= 8) |
| 1496 | { |
| 1497 | dmLogOnceError("Stencil buffer exceeded for inverted clipping node, clipping will not work as expected."); |
| 1498 | // Match the previous backend behavior without relying on undefined shifting. |
| 1499 | scope.m_RefVal = 0; |
| 1500 | } |
| 1501 | else |
| 1502 | { |
| 1503 | scope.m_RefVal = 1u << (7 - index); |
| 1504 | if (parent_scope != 0x0) { |
| 1505 | scope.m_RefVal |= (CalcMask(bit_field_offset) & parent_scope->m_RefVal); |
| 1506 | } |
| 1507 | } |
| 1508 | } |
| 1509 | if (inverted && node->m_Node.m_ClippingVisible) { |
| 1510 | scope.m_ColorMask = 0xf; |
| 1511 | } else { |
| 1512 | scope.m_ColorMask = 0; |
| 1513 | } |
| 1514 | // state used for drawing any sub non-clippers |
| 1515 | child_scope.m_WriteMask = 0; |
| 1516 | if (!inverted) { |
| 1517 | child_scope.m_RefVal = scope.m_RefVal; |
| 1518 | child_scope.m_TestMask = (CalcMask(bit_range) << bit_field_offset) | scope.m_TestMask; |
| 1519 | } else { |
| 1520 | child_scope.m_RefVal = 0; |
| 1521 | child_scope.m_TestMask = scope.m_RefVal; |
| 1522 | if (parent_scope != 0x0) { |
| 1523 | child_scope.m_RefVal |= parent_scope->m_RefVal; |
| 1524 | child_scope.m_TestMask |= parent_scope->m_TestMask; |
| 1525 | } |
| 1526 | } |
| 1527 | child_scope.m_ColorMask = 0xf; |
| 1528 | // Check for overflow |
| 1529 | int inverted_count = 0; |
| 1530 | if (inverted) { |
| 1531 | inverted_count = index + 1; |
| 1532 | } else { |
| 1533 | inverted_count = inv_clipper_count; |
| 1534 | } |
| 1535 | int bit_count = inverted_count + bit_field_offset + bit_range; |
| 1536 | if (bit_count > 8) { |
| 1537 | dmLogWarning("Stencil buffer exceeded, clipping will not work as expected."); |
no test coverage detected