 @available(OSX 10.13, iOS 11.0, *)
 extension MetalRenderer.Encoder {
     
-    private func render_triangle(width: Int, height: Int, bound: Rect, buffer: MappedBuffer<(GPPoint, GPPoint, GPPoint)>, output: MTLBuffer) throws {
-        
-        guard buffer.count != 0 else { return }
+    private func render_stencil<T>(width: Int, height: Int, pipeline: String, bound: Rect?, buffer: MappedBuffer<T>, output: MTLBuffer) throws {
+        
+        guard let bound = bound, buffer.count != 0 else { return }
         
         let offset_x = max(0, min(width - 1, Int(floor(bound.x))))
         let offset_y = max(0, min(height - 1, Int(floor(bound.y))))

                    let q2 = p2 * transform
                    
                    cubic_render_buffer.append((GPPoint(q0), GPPoint(q1), GPPoint(q2), GPVector(v0), GPVector(v1), GPVector(v2)))
                    cubic_bound = cubic_bound?.union(Rect.bound([q0, q1, q2])) ?? Rect.bound([q0, q1, q2])
                    
                    if cubic_render_buffer.count >= stencil_buffer_limit {
                        try render_cubic(width: width, height: height, bound: cubic_bound ?? Rect(), buffer: cubic_render_buffer, output: output)
                        cubic_render_buffer = []
                    }
                }
            }
        }
        
        try render_triangle(width: width, height: height, bound: triangle_bound ?? Rect(), buffer: triangle_render_buffer, output: output)
        try render_quadratic(width: width, height: height, bound: quadratic_bound ?? Rect(), buffer: quadratic_render_buffer, output: output)
        try render_cubic(width: width, height: height, bound: cubic_bound ?? Rect(), buffer: cubic_render_buffer, output: output)
        
        var _bound: Rect?
        
        if let triangle_bound = triangle_bound {
            _bound = _bound?.union(triangle_bound) ?? triangle_bound
        }
        if let quadratic_bound = quadratic_bound {
            _bound = _bound?.union(quadratic_bound) ?? quadratic_bound
        }
        if let cubic_bound = cubic_bound {
            _bound = _bound?.union(cubic_bound) ?? cubic_bound
        }
        
        return _bound
    }

        let encoder = try self.makeComputeCommandEncoder()
        guard let _buffer = device.makeBuffer(buffer) else { throw MetalRenderer.Error(description: "MTLDevice.makeBuffer failed.") }
        
        let pipeline = try renderer.request_pipeline(pipeline)
        encoder.setComputePipelineState(pipeline)
        
        encoder.setValues(UInt32(offset_x), UInt32(offset_y), UInt32(width), index: 0)
