From d05967b69ae3627db29ab5aa64c41986e1874d8c Mon Sep 17 00:00:00 2001 From: codetypes Date: Wed, 20 Nov 2019 11:03:59 +0800 Subject: [PATCH] fix setScissorRect crash (#20348) When part of scissorRect is out of render target viewport, it crash on mac. Error message like this: -[MTLDebugRenderCommandEncoder setScissorRect:]:2703: failed assertion `(rect.y(568) + rect.height(447))(1015) must be <= render pass height(1000)' --- .../backend/metal/CommandBufferMTL.mm | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cocos/renderer/backend/metal/CommandBufferMTL.mm b/cocos/renderer/backend/metal/CommandBufferMTL.mm index 6bbe598265..e43760b8b4 100644 --- a/cocos/renderer/backend/metal/CommandBufferMTL.mm +++ b/cocos/renderer/backend/metal/CommandBufferMTL.mm @@ -205,6 +205,10 @@ namespace return nil; } } + + inline int clamp(int value, int min, int max) { + return std::min(max, std::max(min, value)); + } } CommandBufferMTL::CommandBufferMTL(DeviceMTL* deviceMTL) @@ -484,10 +488,19 @@ void CommandBufferMTL::setScissorRect(bool isEnabled, float x, float y, float wi MTLScissorRect scissorRect; if(isEnabled) { - scissorRect.x = x; - scissorRect.y = _renderTargetHeight - height - y; - scissorRect.width = width; - scissorRect.height = height; + y = _renderTargetHeight - height - y; + int minX = clamp((int)x, 0, (int)_renderTargetWidth); + int minY = clamp((int)y, 0, (int)_renderTargetHeight); + int maxX = clamp((int)(x + width), 0, (int)_renderTargetWidth); + int maxY = clamp((int)(y + height), 0, (int)_renderTargetHeight); + scissorRect.x = minX; + scissorRect.y = minY; + scissorRect.width = maxX - minX; + scissorRect.height = maxY - minY; + if (scissorRect.width == 0 || scissorRect.height == 0) { + scissorRect.width = 0; + scissorRect.height = 0; + } } else {