blob: a9c265748186bf3dcd1f954ab0f287b32ec120c8 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/metal_util/test_shader.h"
#include <CommonCrypto/CommonDigest.h>
#import <Metal/Metal.h>
#include "base/bind.h"
#include "base/command_line.h"
#include "base/mac/scoped_dispatch_object.h"
#include "base/mac/scoped_nsobject.h"
#include "base/memory/ref_counted.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "components/crash/core/common/crash_key.h"
#include "components/metal_util/device.h"
#include "components/metal_util/switches.h"
namespace metal {
namespace {
const char* kTestShaderSource =
""
"#include <metal_stdlib>\n"
"#include <simd/simd.h>\n"
"typedef struct {\n"
" float4 clipSpacePosition [[position]];\n"
" float4 color;\n"
"} RasterizerData;\n"
"\n"
"vertex RasterizerData vertexShader(\n"
" uint vertexID [[vertex_id]],\n"
" constant vector_float2 *positions[[buffer(0)]],\n"
" constant vector_float4 *colors[[buffer(1)]]) {\n"
" RasterizerData out;\n"
" out.clipSpacePosition = vector_float4(0.0, 0.0, 0.0, 1.0);\n"
" out.clipSpacePosition.xy = positions[vertexID].xy;\n"
" out.color = colors[vertexID];\n"
" return out;\n"
"}\n"
"\n"
"fragment float4 fragmentShader(RasterizerData in [[stage_in]]) {\n"
" return %f * in.color;\n"
"}\n"
"";
} // namesspace
const size_t kTestLibSize = 0x1766;
namespace {
uint8_t kTestLibData[] = {
0x4d, 0x54, 0x4c, 0x42, 0x01, 0x80, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x86, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00,
0x4e, 0x41, 0x4d, 0x45, 0x0d, 0x00, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78,
0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01,
0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0xea, 0x53, 0xd8, 0xad,
0xe9, 0x9f, 0x43, 0x22, 0x4b, 0x14, 0xd8, 0xeb, 0x05, 0x3a, 0xb8, 0x30,
0x10, 0xfc, 0x77, 0xf9, 0x58, 0x77, 0x59, 0xad, 0xff, 0x76, 0x2f, 0x92,
0x8e, 0x39, 0xe8, 0xeb, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x90, 0x0b,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00,
0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x84, 0x00, 0x00, 0x00, 0x4e, 0x41,
0x4d, 0x45, 0x0f, 0x00, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74,
0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01,
0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x03, 0xe2, 0x3a, 0x4c,
0xf7, 0x70, 0x1a, 0x18, 0xe3, 0x6a, 0x5d, 0x63, 0x59, 0x7f, 0x36, 0x18,
0xd1, 0x28, 0x2c, 0x83, 0x2a, 0x88, 0x7f, 0x29, 0xda, 0x25, 0xb5, 0x15,
0x6b, 0x43, 0xfd, 0xce, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x50, 0x0a,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x90, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00,
0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00,
0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e,
0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00,
0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x78, 0x0b, 0x00, 0x00, 0xff, 0xff,
0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00,
0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00,
0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xa6, 0x02, 0x00, 0x00, 0x0b, 0x02,
0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81,
0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01,
0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10,
0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08,
0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46,
0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x22,
0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21,
0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x1b, 0xfa,
0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0x03, 0x40, 0x02, 0x2a,
0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8,
0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca,
0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca,
0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0,
0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07,
0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07,
0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87,
0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2,
0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6,
0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca,
0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87,
0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03,
0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87,
0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87,
0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc,
0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda,
0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda,
0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc,
0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde,
0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0,
0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87,
0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87,
0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87,
0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc,
0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc,
0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07,
0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87,
0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07,
0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87,
0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00,
0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0,
0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0,
0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87,
0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87,
0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07,
0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87,
0x72, 0x00, 0xf0, 0x00, 0x20, 0xe8, 0x21, 0x1c, 0xe4, 0xe1, 0x1c, 0xca,
0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xca, 0x21, 0x1c, 0xe8, 0xa1, 0x1e, 0xe4,
0xa1, 0x1c, 0xe6, 0x01, 0x68, 0x03, 0x73, 0x80, 0x87, 0x38, 0xb0, 0x03,
0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03,
0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8,
0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda,
0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde,
0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07,
0x60, 0x03, 0x22, 0x08, 0x40, 0x02, 0x2c, 0x40, 0xb5, 0x01, 0x19, 0x06,
0x20, 0x01, 0x16, 0xa0, 0x02, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00,
0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20,
0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64,
0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1,
0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x34,
0x33, 0x00, 0xc3, 0x08, 0x04, 0x70, 0x95, 0x34, 0x45, 0x94, 0x30, 0xf9,
0x2b, 0x20, 0x4d, 0x44, 0x84, 0x64, 0x44, 0xd4, 0x01, 0x13, 0x80, 0x84,
0x88, 0x39, 0x02, 0x30, 0x18, 0x46, 0x10, 0x80, 0x41, 0x04, 0x42, 0x18,
0x44, 0x08, 0x84, 0x42, 0xc8, 0x94, 0xd1, 0x0d, 0x04, 0xcc, 0x11, 0x80,
0xc2, 0x30, 0x02, 0x31, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xb2,
0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07,
0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87,
0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x03, 0x3a, 0x70, 0x03,
0x38, 0xd8, 0xf0, 0x1e, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40,
0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90,
0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80,
0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60,
0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90,
0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20,
0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0,
0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30,
0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40,
0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60,
0x0e, 0x78, 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10,
0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10,
0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40,
0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60,
0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20,
0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0,
0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60,
0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60,
0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80,
0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20,
0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10,
0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20,
0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0,
0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0,
0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20,
0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00,
0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0,
0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x78, 0x00,
0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80,
0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30,
0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x4c, 0x45, 0x44, 0x13, 0x71, 0xb1,
0x07, 0x30, 0x10, 0xd1, 0x90, 0x08, 0x60, 0x0e, 0x00, 0x00, 0x02, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, 0x20, 0x50, 0x14, 0x55,
0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e,
0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04,
0x43, 0x9a, 0x12, 0x28, 0x84, 0x22, 0x18, 0x01, 0x28, 0x88, 0x02, 0x21,
0x1d, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x6d, 0x00,
0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01,
0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78,
0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4,
0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c,
0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03,
0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70,
0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70,
0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec,
0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0,
0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d,
0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43,
0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0,
0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68,
0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28,
0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08,
0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee,
0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62,
0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c,
0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06,
0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43,
0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3,
0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3,
0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68,
0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce,
0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3,
0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d,
0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e,
0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51,
0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60,
0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98,
0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e,
0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e,
0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83,
0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2,
0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a,
0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28,
0x07, 0x72, 0x00, 0x00, 0x00, 0x00, 0x79, 0x20, 0x00, 0x00, 0xb4, 0x00,
0x00, 0x00, 0x62, 0x1e, 0x48, 0x20, 0x43, 0x88, 0x0c, 0x19, 0x39, 0x19,
0x24, 0x90, 0x91, 0x40, 0xc6, 0xc8, 0xc8, 0x68, 0x22, 0x50, 0x08, 0x14,
0x32, 0x9e, 0x18, 0x19, 0x21, 0x47, 0xc8, 0x90, 0x51, 0xd4, 0xb0, 0xba,
0x01, 0x00, 0xca, 0x1a, 0x14, 0x1b, 0x57, 0x06, 0x61, 0xc0, 0x44, 0x06,
0x13, 0x45, 0x56, 0xd1, 0x10, 0x88, 0x22, 0x21, 0xd1, 0x65, 0x24, 0x06,
0x00, 0x00, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65,
0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x39, 0x30, 0x32, 0x2e, 0x31,
0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x39, 0x30,
0x32, 0x2e, 0x31, 0x2e, 0x34, 0x39, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c,
0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e,
0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69,
0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68,
0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63,
0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65,
0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68,
0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e,
0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x6e, 0x61, 0x74, 0x69,
0x76, 0x65, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x69,
0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67,
0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c,
0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f,
0x6e, 0x61, 0x6d, 0x65, 0x63, 0x6c, 0x69, 0x70, 0x53, 0x70, 0x61, 0x63,
0x65, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72,
0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x70,
0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28,
0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29,
0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72,
0x74, 0x65, 0x78, 0x5f, 0x69, 0x64, 0x75, 0x69, 0x6e, 0x74, 0x76, 0x65,
0x72, 0x74, 0x65, 0x78, 0x49, 0x44, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75,
0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69,
0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72,
0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61,
0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f,
0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c,
0x6f, 0x61, 0x74, 0x32, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x00, 0x00, 0x00, 0x23, 0x08,
0x43, 0x30, 0x82, 0x30, 0x08, 0x23, 0x08, 0xc3, 0x30, 0x82, 0x30, 0x10,
0x23, 0x08, 0x08, 0x30, 0x82, 0x30, 0x14, 0x23, 0x08, 0x83, 0x31, 0xc3,
0xb0, 0x05, 0xdc, 0x0c, 0x81, 0x30, 0xc3, 0xd0, 0x6d, 0xde, 0x0c, 0xc4,
0xd0, 0x6d, 0xde, 0x0c, 0x01, 0x31, 0x43, 0x50, 0xcc, 0x10, 0x18, 0x33,
0x04, 0xc7, 0x0c, 0x05, 0x92, 0x28, 0x0b, 0x33, 0x83, 0xd1, 0x38, 0x89,
0xb2, 0x3c, 0x33, 0x08, 0x6a, 0xb0, 0x06, 0x33, 0x18, 0x1e, 0x94, 0x44,
0x8b, 0x34, 0x83, 0xb3, 0x4d, 0x94, 0xb7, 0x55, 0x16, 0x18, 0x5c, 0x60,
0x90, 0x60, 0x4b, 0x36, 0x83, 0xd3, 0x4d, 0xd4, 0xb6, 0x55, 0x56, 0x18,
0x5c, 0x61, 0x90, 0x28, 0x8b, 0x36, 0xc3, 0xd0, 0x06, 0x6e, 0xf0, 0x06,
0x33, 0x0c, 0x1f, 0x1b, 0xc0, 0x81, 0x8c, 0x04, 0x26, 0x28, 0x23, 0x36,
0x36, 0xbb, 0x36, 0x97, 0xb6, 0x37, 0xb2, 0x3a, 0xb6, 0x32, 0x17, 0x33,
0xb6, 0xb0, 0xb3, 0xb9, 0x51, 0x82, 0x30, 0x48, 0x85, 0x8d, 0xcd, 0xae,
0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x40, 0x0c, 0x72, 0x09,
0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25,
0x18, 0x83, 0xa4, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea,
0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46,
0x09, 0xc8, 0x20, 0xa7, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8,
0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51,
0x88, 0x32, 0x30, 0x83, 0x33, 0x40, 0x83, 0x54, 0xc2, 0xd2, 0xe4, 0x5c,
0xec, 0xca, 0xe4, 0xe8, 0xca, 0xf0, 0x46, 0x09, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a,
0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d,
0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6,
0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8,
0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00,
0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94,
0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00,
0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x13, 0x04,
0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x34, 0x33,
0x00, 0xb4, 0x73, 0x10, 0x44, 0xb0, 0x2c, 0x63, 0x11, 0x44, 0x21, 0x0c,
0x04, 0x33, 0x00, 0x23, 0x00, 0x63, 0x04, 0x20, 0x08, 0x82, 0xf8, 0x47,
0x31, 0x07, 0xe1, 0x38, 0x0f, 0x44, 0x32, 0x03, 0x40, 0x34, 0x03, 0x00,
0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47,
0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03,
0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74,
0x20, 0x63, 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20,
0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04,
0xe5, 0xd8, 0x10, 0xcc, 0xc1, 0x86, 0x41, 0x0e, 0xea, 0x80, 0x0e, 0x36,
0x0c, 0x76, 0x60, 0x07, 0x74, 0x00, 0xc7, 0x68, 0x6c, 0x12, 0x98, 0x80,
0x02, 0x22, 0x83, 0x0c, 0x01, 0xb1, 0x0c, 0x32, 0x1c, 0xc1, 0xb2, 0x43,
0x78, 0x0a, 0x0a, 0xa2, 0xcc, 0x36, 0x24, 0x03, 0x30, 0xdb, 0x10, 0x08,
0x41, 0x06, 0x01, 0x31, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06,
0x23, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00,
0xf9, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c,
0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x12, 0x03,
0x94, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78,
0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x39, 0x30, 0x32, 0x2e, 0x31, 0x2e,
0x34, 0x39, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c,
0x65, 0x2d, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x78, 0x31, 0x30, 0x2e, 0x31,
0x34, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
0x00, 0x00, 0x38, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43,
0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c,
0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c,
0x00, 0x00, 0x56, 0x02, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00,
0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8,
0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05,
0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92,
0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32,
0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19,
0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51,
0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, 0x51, 0x18,
0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x1b, 0xfa, 0x25, 0xf8, 0xff, 0xff,
0xff, 0xff, 0x01, 0x80, 0x03, 0x40, 0x02, 0x28, 0x62, 0x1c, 0xde, 0x41,
0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40,
0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80,
0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21,
0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21,
0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72,
0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72,
0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70,
0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1,
0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41,
0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01,
0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79,
0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70,
0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a,
0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80,
0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0,
0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21,
0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21,
0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1,
0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1,
0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21,
0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80,
0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36,
0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21,
0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0,
0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0,
0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72,
0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77,
0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79,
0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74,
0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1,
0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1,
0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79,
0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75,
0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a,
0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72,
0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00,
0x20, 0xe8, 0x21, 0x1c, 0xe4, 0xe1, 0x1c, 0xca, 0x81, 0x1e, 0xda, 0xc0,
0x1c, 0xca, 0x21, 0x1c, 0xe8, 0xa1, 0x1e, 0xe4, 0xa1, 0x1c, 0xe6, 0x01,
0x68, 0x03, 0x73, 0x80, 0x87, 0x38, 0xb0, 0x03, 0x80, 0xa8, 0x07, 0x77,
0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36,
0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1,
0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1,
0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01,
0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x00, 0x00, 0x49, 0x18,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x82, 0x00, 0x00, 0x89, 0x20,
0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64,
0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1,
0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x20,
0x33, 0x00, 0xc3, 0x08, 0x04, 0x50, 0x86, 0x88, 0x20, 0x19, 0x08, 0x98,
0x23, 0x00, 0x83, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, 0x00, 0x13, 0xb2,
0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07,
0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87,
0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x03, 0x3a, 0x70, 0x03,
0x38, 0xd8, 0xf0, 0x1e, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40,
0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90,
0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80,
0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60,
0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90,
0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20,
0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0,
0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30,
0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40,
0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60,
0x0e, 0x78, 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10,
0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10,
0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40,
0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60,
0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20,
0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0,
0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60,
0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60,
0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80,
0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20,
0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10,
0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20,
0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0,
0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0,
0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20,
0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00,
0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0,
0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x78, 0x00,
0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80,
0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30,
0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x4e, 0x11, 0x01, 0x06, 0x43, 0x34,
0x13, 0x7b, 0x00, 0x03, 0x11, 0x0d, 0x89, 0x00, 0x47, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x02, 0x45,
0xb1, 0x04, 0x00, 0x00, 0xb2, 0x40, 0x06, 0x00, 0x00, 0x00, 0x32, 0x1e,
0x98, 0x0c, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04,
0x43, 0xaa, 0x12, 0x28, 0x84, 0x22, 0x18, 0x01, 0x00, 0x00, 0xb1, 0x18,
0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1,
0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42,
0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f,
0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1,
0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84,
0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc,
0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70,
0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19,
0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f,
0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21,
0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc,
0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84,
0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37,
0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70,
0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77,
0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79,
0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e,
0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1,
0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81,
0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98,
0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88,
0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4,
0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72,
0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74,
0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e,
0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e,
0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21,
0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01,
0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc,
0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77,
0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e,
0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1,
0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61,
0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0,
0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0,
0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74,
0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x00, 0x00, 0x00, 0x00, 0x79, 0x20,
0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x62, 0x1e, 0x48, 0x20, 0x43, 0x88,
0x0c, 0x19, 0x39, 0x19, 0x24, 0x90, 0x91, 0x40, 0xc6, 0xc8, 0xc8, 0x68,
0x22, 0x50, 0x08, 0x14, 0x32, 0x9e, 0x18, 0x19, 0x21, 0x47, 0xc8, 0x90,
0x51, 0x9c, 0x28, 0x7a, 0x01, 0x00, 0xca, 0x1a, 0x14, 0x1b, 0x57, 0x06,
0x61, 0x10, 0x45, 0x06, 0xa3, 0x48, 0x4c, 0x24, 0x59, 0x4f, 0x01, 0x00,
0x00, 0x00, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65,
0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x39, 0x30, 0x32, 0x2e, 0x31,
0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x39, 0x30,
0x32, 0x2e, 0x31, 0x2e, 0x34, 0x39, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c,
0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e,
0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69,
0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68,
0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63,
0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65,
0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68,
0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e,
0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x6e, 0x61, 0x74, 0x69,
0x76, 0x65, 0x5f, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x69,
0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e,
0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69,
0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e,
0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72,
0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72,
0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e,
0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76,
0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d,
0x65, 0x63, 0x6c, 0x69, 0x70, 0x53, 0x70, 0x61, 0x63, 0x65, 0x50, 0x6f,
0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72,
0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74,
0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63,
0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69,
0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76,
0x65, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x23, 0x08, 0x45, 0x30, 0x82, 0x50,
0x08, 0x23, 0x08, 0xc5, 0x30, 0x82, 0x50, 0x10, 0x23, 0x08, 0x03, 0x30,
0xc3, 0x40, 0x05, 0xd5, 0x0c, 0x81, 0x30, 0xc3, 0x60, 0x51, 0xd7, 0x0c,
0xc4, 0x60, 0x51, 0xd7, 0x0c, 0x01, 0x31, 0x43, 0x50, 0xcc, 0x10, 0x18,
0x33, 0x04, 0xc7, 0x0c, 0x05, 0x72, 0x5d, 0x89, 0x32, 0x43, 0x10, 0x06,
0x33, 0x20, 0xd7, 0xc2, 0x34, 0x89, 0xe2, 0x3c, 0x33, 0x24, 0x14, 0x14,
0x31, 0x52, 0xa2, 0x38, 0xd3, 0x0c, 0xc2, 0x18, 0x90, 0xc1, 0x0c, 0x03,
0x26, 0x06, 0x65, 0x20, 0x23, 0x81, 0x09, 0xca, 0x88, 0x8d, 0xcd, 0xae,
0xcd, 0xa5, 0xed, 0x8d, 0xac, 0x8e, 0xad, 0xcc, 0xc5, 0x8c, 0x2d, 0xec,
0x6c, 0x6e, 0x94, 0x00, 0x4b, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d,
0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x20, 0xcb, 0x25, 0x2c, 0x4d, 0xce, 0xc5,
0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0x40, 0x4b, 0x2a, 0x2c,
0x4d, 0xce, 0x85, 0x2d, 0xcc, 0xed, 0xac, 0x2e, 0xec, 0xac, 0xec, 0xcb,
0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x94, 0x60, 0xcb, 0x29, 0x2c,
0x4d, 0xce, 0x65, 0xec, 0xad, 0x0d, 0x2e, 0x8d, 0xad, 0xec, 0xeb, 0x0d,
0x8e, 0x2e, 0xed, 0xcd, 0x6d, 0x6e, 0x14, 0x82, 0xeb, 0xbc, 0x2f, 0x99,
0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba,
0x51, 0x82, 0x32, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00,
0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58,
0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3,
0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d,
0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10,
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b,
0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38,
0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00,
0x00, 0x00, 0x64, 0x23, 0x00, 0x04, 0x63, 0x04, 0x20, 0x08, 0x82, 0xf0,
0x07, 0x00, 0x73, 0x0c, 0x43, 0x20, 0x64, 0x00, 0x00, 0x00, 0x71, 0x20,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00,
0xce, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c,
0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,
0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x12, 0x03,
0x94, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65,
0x6e, 0x74, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x39, 0x30, 0x32, 0x2e,
0x31, 0x2e, 0x34, 0x39, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70,
0x70, 0x6c, 0x65, 0x2d, 0x6d, 0x61, 0x63, 0x6f, 0x73, 0x78, 0x31, 0x30,
0x2e, 0x31, 0x34, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00};
} // namespace
// There exists a 4-byte literal at this offset, which can be changed to any
// value in kValidLiteral to defeat caching.
const size_t kLiteralOffset = 0x167c;
const size_t kLiteralSize = 0x4;
namespace {
const uint8_t kValidLiteralValues[] = {
0xef, 0x4c, 0x9a, 0x68, 0xef, 0x4c, 0x9a, 0x70, 0x66, 0x6f, 0xa6, 0x74,
0xef, 0x4c, 0x9a, 0x78, 0x2a, 0x5e, 0x9f, 0x7a, 0x66, 0x6f, 0xa6, 0x7c,
0xa2, 0x88, 0xab, 0x7e, 0xef, 0x4c, 0x9a, 0xa0, 0x7c, 0xd9, 0x9b, 0xa1,
0x2a, 0x5e, 0x9f, 0xa2, 0xb8, 0xea, 0xa2, 0xa3, 0x66, 0x6f, 0xa6, 0xa4,
0xf4, 0xfb, 0xa7, 0xa5, 0xa2, 0x88, 0xab, 0xa6, 0x2f, 0x0d, 0xaf, 0xa7,
0xef, 0x4c, 0x9a, 0xa8, 0x36, 0x0f, 0xdb, 0xa8, 0x7c, 0xd9, 0x9b, 0xa9,
0xe3, 0x9b, 0xde, 0xa9, 0x2a, 0x5e, 0x9f, 0xaa, 0x71, 0x28, 0xe2, 0xaa,
0xb8, 0xea, 0xa2, 0xab, 0xff, 0xac, 0xe3, 0xab, 0x66, 0x6f, 0xa6, 0xac,
0xad, 0x39, 0xe7, 0xac, 0xf4, 0xfb, 0xa7, 0xad, 0x3b, 0xbe, 0xea, 0xad,
0xa2, 0x88, 0xab, 0xae, 0xe8, 0x4a, 0xee, 0xae, 0x2f, 0x0d, 0xaf, 0xaf,
0x76, 0xcf, 0xef, 0xaf, 0x7c, 0xd9, 0x9b, 0xb1, 0xb0, 0x3a, 0xbe, 0xb1,
0xe3, 0x9b, 0xde, 0xb1, 0xf7, 0xfc, 0xfe, 0xb1, 0x2a, 0x5e, 0x9f, 0xb2,
0x3e, 0xbf, 0xbf, 0xb2, 0x71, 0x28, 0xe2, 0xb2, 0xb8, 0xea, 0xa2, 0xb3,
0xec, 0x4b, 0xc3, 0xb3, 0xff, 0xac, 0xe3, 0xb3, 0x32, 0x0e, 0x86, 0xb4,
0x66, 0x6f, 0xa6, 0xb4, 0x79, 0xd8, 0xc6, 0xb4, 0xad, 0x39, 0xe7, 0xb4,
0xe0, 0x9a, 0x87, 0xb5, 0xf4, 0xfb, 0xa7, 0xb5, 0x27, 0x5d, 0xca, 0xb5,
0x3b, 0xbe, 0xea, 0xb5, 0x6e, 0x1f, 0x8b, 0xb6, 0xa2, 0x88, 0xab, 0xb6,
0xb5, 0xe9, 0xcb, 0xb6, 0xe8, 0x4a, 0xee, 0xb6, 0xfc, 0xab, 0x8e, 0xb7,
0x2f, 0x0d, 0xaf, 0xb7, 0x63, 0x6e, 0xcf, 0xb7, 0x76, 0xcf, 0xef, 0xb7,
0x65, 0x1c, 0x8a, 0xb8, 0xef, 0x4c, 0x9a, 0xb8, 0x78, 0x7d, 0xaa, 0xb8,
0x22, 0xae, 0xba, 0xb8, 0xac, 0xde, 0xca, 0xb8, 0x36, 0x0f, 0xdb, 0xb8,
0xbf, 0x3f, 0xeb, 0xb8, 0x69, 0x78, 0xfb, 0xb8, 0xf3, 0xa8, 0x8b, 0xb9,
0x7c, 0xd9, 0x9b, 0xb9, 0x26, 0x0a, 0xae, 0xb9, 0xb0, 0x3a, 0xbe, 0xb9,
0x3a, 0x6b, 0xce, 0xb9, 0xe3, 0x9b, 0xde, 0xb9, 0x6d, 0xcc, 0xee, 0xb9,
0xf7, 0xfc, 0xfe, 0xb9, 0xa1, 0x2d, 0x8f, 0xba, 0x2a, 0x5e, 0x9f, 0xba,
0xb4, 0x8e, 0xaf, 0xba, 0x3e, 0xbf, 0xbf, 0xba, 0xe7, 0xef, 0xcf, 0xba,
0x71, 0x28, 0xe2, 0xba, 0xfb, 0x58, 0xf2, 0xba, 0x2e, 0xba, 0x92, 0xbb,
0xb8, 0xea, 0xa2, 0xbb, 0x62, 0x1b, 0xb3, 0xbb, 0xec, 0x4b, 0xc3, 0xbb,
0x75, 0x7c, 0xd3, 0xbb, 0xff, 0xac, 0xe3, 0xbb, 0xa9, 0xdd, 0xf3, 0xbb,
0x32, 0x0e, 0x86, 0xbc, 0xbc, 0x3e, 0x96, 0xbc, 0x66, 0x6f, 0xa6, 0xbc,
0xf0, 0x9f, 0xb6, 0xbc, 0x79, 0xd8, 0xc6, 0xbc, 0x23, 0x09, 0xd7, 0xbc,
0xad, 0x39, 0xe7, 0xbc, 0x37, 0x6a, 0xf7, 0xbc, 0xe0, 0x9a, 0x87, 0xbd,
0x6a, 0xcb, 0x97, 0xbd, 0xf4, 0xfb, 0xa7, 0xbd, 0x7d, 0x2c, 0xba, 0xbd,
0x27, 0x5d, 0xca, 0xbd, 0xb1, 0x8d, 0xda, 0xbd, 0x3b, 0xbe, 0xea, 0xbd,
0xe4, 0xee, 0xfa, 0xbd, 0x6e, 0x1f, 0x8b, 0xbe, 0xf8, 0x4f, 0x9b, 0xbe,
0xa2, 0x88, 0xab, 0xbe, 0x2b, 0xb9, 0xbb, 0xbe, 0xb5, 0xe9, 0xcb, 0xbe,
0x3f, 0x1a, 0xde, 0xbe, 0xe8, 0x4a, 0xee, 0xbe, 0x72, 0x7b, 0xfe, 0xbe,
0xfc, 0xab, 0x8e, 0xbf, 0xa6, 0xdc, 0x9e, 0xbf, 0x2f, 0x0d, 0xaf, 0xbf,
0xb9, 0x3d, 0xbf, 0xbf, 0x63, 0x6e, 0xcf, 0xbf, 0xed, 0x9e, 0xdf, 0xbf,
0x76, 0xcf, 0xef, 0xbf, 0x65, 0x1c, 0x8a, 0xe0, 0xaa, 0x38, 0x92, 0xe0,
0xef, 0x4c, 0x9a, 0xe0, 0x33, 0x69, 0xa2, 0xe0, 0x78, 0x7d, 0xaa, 0xe0,
0xbd, 0x99, 0xb2, 0xe0, 0x22, 0xae, 0xba, 0xe0, 0x67, 0xca, 0xc2, 0xe0,
0xac, 0xde, 0xca, 0xe0, 0xf1, 0xfa, 0xd2, 0xe0, 0x36, 0x0f, 0xdb, 0xe0,
0x7a, 0x2b, 0xe3, 0xe0, 0xbf, 0x3f, 0xeb, 0xe0, 0x24, 0x5c, 0xf3, 0xe0,
0x69, 0x78, 0xfb, 0xe0, 0xae, 0x8c, 0x83, 0xe1, 0xf3, 0xa8, 0x8b, 0xe1,
0x38, 0xbd, 0x93, 0xe1, 0x7c, 0xd9, 0x9b, 0xe1, 0xe1, 0xed, 0xa3, 0xe1,
0x26, 0x0a, 0xae, 0xe1, 0x6b, 0x1e, 0xb6, 0xe1, 0xb0, 0x3a, 0xbe, 0xe1,
0xf5, 0x4e, 0xc6, 0xe1, 0x3a, 0x6b, 0xce, 0xe1, 0x7e, 0x7f, 0xd6, 0xe1,
0xe3, 0x9b, 0xde, 0xe1, 0x28, 0xb8, 0xe6, 0xe1, 0x6d, 0xcc, 0xee, 0xe1,
0xb2, 0xe8, 0xf6, 0xe1, 0xf7, 0xfc, 0xfe, 0xe1, 0x3c, 0x19, 0x87, 0xe2,
0xa1, 0x2d, 0x8f, 0xe2, 0xe5, 0x49, 0x97, 0xe2, 0x2a, 0x5e, 0x9f, 0xe2,
0x6f, 0x7a, 0xa7, 0xe2, 0xb4, 0x8e, 0xaf, 0xe2, 0xf9, 0xaa, 0xb7, 0xe2,
0x3e, 0xbf, 0xbf, 0xe2, 0xa3, 0xdb, 0xc7, 0xe2, 0xe7, 0xef, 0xcf, 0xe2,
0x2c, 0x0c, 0xda, 0xe2, 0x71, 0x28, 0xe2, 0xe2, 0xb6, 0x3c, 0xea, 0xe2,
0xfb, 0x58, 0xf2, 0xe2, 0x60, 0x6d, 0xfa, 0xe2, 0xe9, 0x9d, 0x8a, 0xe3,
0x2e, 0xba, 0x92, 0xe3, 0x73, 0xce, 0x9a, 0xe3, 0xb8, 0xea, 0xa2, 0xe3,
0xfd, 0xfe, 0xaa, 0xe3, 0x62, 0x1b, 0xb3, 0xe3, 0xa7, 0x2f, 0xbb, 0xe3,
0xec, 0x4b, 0xc3, 0xe3, 0x30, 0x68, 0xcb, 0xe3, 0x75, 0x7c, 0xd3, 0xe3,
0xba, 0x98, 0xdb, 0xe3, 0xff, 0xac, 0xe3, 0xe3, 0x64, 0xc9, 0xeb, 0xe3,
0xa9, 0xdd, 0xf3, 0xe3, 0xee, 0xf9, 0xfb, 0xe3, 0x32, 0x0e, 0x86, 0xe4,
0x77, 0x2a, 0x8e, 0xe4, 0xbc, 0x3e, 0x96, 0xe4, 0x21, 0x5b, 0x9e, 0xe4,
0x66, 0x6f, 0xa6, 0xe4, 0xab, 0x8b, 0xae, 0xe4, 0xf0, 0x9f, 0xb6, 0xe4,
0x34, 0xbc, 0xbe, 0xe4, 0x79, 0xd8, 0xc6, 0xe4, 0xbe, 0xec, 0xce, 0xe4,
0x23, 0x09, 0xd7, 0xe4, 0x68, 0x1d, 0xdf, 0xe4, 0xad, 0x39, 0xe7, 0xe4,
0xf2, 0x4d, 0xef, 0xe4, 0x37, 0x6a, 0xf7, 0xe4, 0x7b, 0x7e, 0xff, 0xe4,
0xe0, 0x9a, 0x87, 0xe5, 0x25, 0xaf, 0x8f, 0xe5, 0x6a, 0xcb, 0x97, 0xe5,
0xaf, 0xdf, 0x9f, 0xe5, 0xf4, 0xfb, 0xa7, 0xe5, 0x39, 0x18, 0xb2, 0xe5,
0x7d, 0x2c, 0xba, 0xe5, 0xe2, 0x48, 0xc2, 0xe5, 0x27, 0x5d, 0xca, 0xe5,
0x6c, 0x79, 0xd2, 0xe5, 0xb1, 0x8d, 0xda, 0xe5, 0xf6, 0xa9, 0xe2, 0xe5,
0x3b, 0xbe, 0xea, 0xe5, 0x7f, 0xda, 0xf2, 0xe5, 0xe4, 0xee, 0xfa, 0xe5,
0x29, 0x0b, 0x83, 0xe6, 0x6e, 0x1f, 0x8b, 0xe6, 0xb3, 0x3b, 0x93, 0xe6,
0xf8, 0x4f, 0x9b, 0xe6, 0x3d, 0x6c, 0xa3, 0xe6, 0xa2, 0x88, 0xab, 0xe6,
0xe6, 0x9c, 0xb3, 0xe6, 0x2b, 0xb9, 0xbb, 0xe6, 0x70, 0xcd, 0xc3, 0xe6,
0xb5, 0xe9, 0xcb, 0xe6, 0xfa, 0xfd, 0xd3, 0xe6, 0x3f, 0x1a, 0xde, 0xe6,
0xa4, 0x2e, 0xe6, 0xe6, 0xe8, 0x4a, 0xee, 0xe6, 0x2d, 0x5f, 0xf6, 0xe6,
0x72, 0x7b, 0xfe, 0xe6, 0xb7, 0x8f, 0x86, 0xe7, 0xfc, 0xab, 0x8e, 0xe7,
0x61, 0xc8, 0x96, 0xe7, 0xa6, 0xdc, 0x9e, 0xe7, 0xea, 0xf8, 0xa6, 0xe7,
0x2f, 0x0d, 0xaf, 0xe7, 0x74, 0x29, 0xb7, 0xe7, 0xb9, 0x3d, 0xbf, 0xe7,
0xfe, 0x59, 0xc7, 0xe7, 0x63, 0x6e, 0xcf, 0xe7, 0xa8, 0x8a, 0xd7, 0xe7,
0xed, 0x9e, 0xdf, 0xe7, 0x31, 0xbb, 0xe7, 0xe7, 0x76, 0xcf, 0xef, 0xe7,
0xbb, 0xeb, 0xf7, 0xe7, 0x32, 0x0e, 0x86, 0xe8, 0x65, 0x1c, 0x8a, 0xe8,
0x77, 0x2a, 0x8e, 0xe8, 0xaa, 0x38, 0x92, 0xe8, 0xbc, 0x3e, 0x96, 0xe8,
0xef, 0x4c, 0x9a, 0xe8, 0x21, 0x5b, 0x9e, 0xe8, 0x33, 0x69, 0xa2, 0xe8,
0x66, 0x6f, 0xa6, 0xe8, 0x78, 0x7d, 0xaa, 0xe8, 0xab, 0x8b, 0xae, 0xe8,
0xbd, 0x99, 0xb2, 0xe8, 0xf0, 0x9f, 0xb6, 0xe8, 0x22, 0xae, 0xba, 0xe8,
};
// The sha256 hash of the bitcode is stored at this offset in the shader.
const size_t kTestLibHashOffset = 0x104;
// The bitcode that is hashed is stored at this offset and with this size.
const size_t kTestLibBitcodeOffset = 0xd16;
const size_t kTestLibBitcodeSize = 0xa50;
crash_reporter::CrashKeyString<32>& GetLinkIndexCrashKey() {
static crash_reporter::CrashKeyString<32> crash_key("metal-link-index");
return crash_key;
}
} // namespace
std::vector<uint8_t> GetAlteredLibraryData() {
// Make a copy of the shader's data.
std::vector<uint8_t> data(kTestLibData, kTestLibData + kTestLibSize);
// Alter the data at kLiteralOffset to defeat caching.
uint64_t index =
base::RandInt(0, sizeof(kValidLiteralValues) / kLiteralSize - 1);
for (size_t i = 0; i < kLiteralSize; ++i)
data[kLiteralOffset + i] = kValidLiteralValues[kLiteralSize * index + i];
// Compute the hash of the altered bitcode and and place it in the data.
CC_SHA256(&data[kTestLibBitcodeOffset], kTestLibBitcodeSize,
&data[kTestLibHashOffset]);
// Shader link crashes have been observed on bots. Record what index caused
// them if they appear in the wild.
GetLinkIndexCrashKey().Set(base::StringPrintf("%llu", index));
return data;
}
namespace {
base::ScopedDispatchObject<dispatch_data_t> GetLibraryData() {
auto vector_data = GetAlteredLibraryData();
base::ScopedDispatchObject<dispatch_data_t> dispatch_data(
dispatch_data_create(vector_data.data(), vector_data.size(), nullptr,
DISPATCH_DATA_DESTRUCTOR_DEFAULT));
return dispatch_data;
}
// State shared between the compiler callback and the caller.
class TestShaderState : public base::RefCountedThreadSafe<TestShaderState> {
public:
TestShaderState(TestShaderCallback callback,
TestShaderComponent component,
const base::TimeDelta& timeout)
: callback_(std::move(callback)),
component_(component),
timeout_(timeout),
start_time_(base::TimeTicks::Now()) {}
// Called when the completion callback happens.
void OnCompletionHandlerCalled(TestShaderResult result) {
{
base::AutoLock lock(lock_);
result_ = result;
completion_handler_called_time_ = base::TimeTicks::Now();
}
RunCallbackIfReady();
}
// Called when the call to newLibraryWithSource or
// newRenderStateWithDescriptor completes. Note that this may happen before or
// after OnCompletionHandlerCalled is called.
void OnMethodCompleted() {
{
base::AutoLock lock(lock_);
method_completed_time_ = base::TimeTicks::Now();
}
RunCallbackIfReady();
}
// Called on timeout. This is always called eventually.
void OnTimeout() {
{
base::AutoLock lock(lock_);
timed_out_ = true;
}
RunCallbackIfReady();
}
protected:
virtual ~TestShaderState() = default;
void RunCallbackIfReady() {
base::OnceClosure closure;
{
base::AutoLock lock(lock_);
// Early-out if we have already run the callback.
if (!callback_)
return;
// We're ready to run the callback if we have timed out, or if both times
// have been set.
if (!timed_out_ && (method_completed_time_.is_null() ||
completion_handler_called_time_.is_null()))
return;
// It would be truly bizarre to have newLibraryWithSource hang, but yet
// have the completion handler have been called. Crash if we see this,
// rather than trying to reason about it.
if (method_completed_time_.is_null())
CHECK(completion_handler_called_time_.is_null());
// We will use a single histogram for both "how long did compile take" and
// "did compile complete in 1 minute" by pushing timeouts into the maximum
// bucket of UMA_HISTOGRAM_MEDIUM_TIMES.
base::TimeDelta method_time = kTestShaderTimeForever;
if (!method_completed_time_.is_null())
method_time = std::min(timeout_, method_completed_time_ - start_time_);
base::TimeDelta compile_time = kTestShaderTimeForever;
if (!completion_handler_called_time_.is_null())
compile_time =
std::min(timeout_, completion_handler_called_time_ - start_time_);
// Set up the callback to execute once we release the lock.
closure = base::BindOnce(std::move(callback_), component_, result_,
compile_time);
}
if (closure) {
// If this is a link that has completed, then we set the crash key when
// constructing the shader binary. Clear it now, because Metal didn't
// crash while linking the shader.
if (component_ == TestShaderComponent::kLink)
GetLinkIndexCrashKey().Clear();
std::move(closure).Run();
}
}
base::Lock lock_;
TestShaderCallback callback_;
TestShaderResult result_ = TestShaderResult::kTimedOut;
const TestShaderComponent component_;
const base::TimeDelta timeout_;
const base::TimeTicks start_time_;
base::TimeTicks method_completed_time_;
base::TimeTicks completion_handler_called_time_;
bool timed_out_ = false;
friend class base::RefCountedThreadSafe<TestShaderState>;
};
void TestRenderPipelineStateNow(base::scoped_nsprotocol<id<MTLDevice>> device,
const base::TimeDelta& timeout,
TestShaderCallback callback)
API_AVAILABLE(macos(10.14)) {
// Load the library binary. This should not fail.
base::ScopedDispatchObject<dispatch_data_t> library_data = GetLibraryData();
NSError* error = nil;
base::scoped_nsprotocol<id<MTLLibrary>> library(
[device newLibraryWithData:library_data error:&error]);
base::scoped_nsprotocol<id<MTLFunction>> vertex_fn(
[library newFunctionWithName:@"vertexShader"]);
base::scoped_nsprotocol<id<MTLFunction>> fragment_fn(
[library newFunctionWithName:@"fragmentShader"]);
if (error || !library || !vertex_fn || !fragment_fn)
return;
// Initialize the TestShaderState and post the timeout callback, before
// calling into the Metal API.
auto state = base::MakeRefCounted<TestShaderState>(
std::move(callback), TestShaderComponent::kLink, timeout);
base::ThreadPool::PostDelayedTask(
FROM_HERE, {}, base::BindOnce(&TestShaderState::OnTimeout, state),
timeout);
// Request asynchronous compile of the RenderPipelineState.
base::scoped_nsobject<MTLRenderPipelineDescriptor> descriptor(
[[MTLRenderPipelineDescriptor alloc] init]);
[descriptor setLabel:@"Test Pipeline"];
[descriptor setVertexFunction:vertex_fn];
[descriptor setFragmentFunction:fragment_fn];
[descriptor colorAttachments][0].pixelFormat = MTLPixelFormatBGRA8Unorm;
MTLNewRenderPipelineStateCompletionHandler completion_handler =
^(id<MTLRenderPipelineState> render_pipeline_state, NSError* error) {
state->OnCompletionHandlerCalled(render_pipeline_state
? TestShaderResult::kSucceeded
: TestShaderResult::kFailed);
};
[device newRenderPipelineStateWithDescriptor:descriptor
completionHandler:completion_handler];
state->OnMethodCompleted();
}
void TestShaderNow(base::scoped_nsprotocol<id<MTLDevice>> device,
const base::TimeDelta& timeout,
TestShaderCallback callback) API_AVAILABLE(macos(10.14)) {
// Initialize the TestShaderState and post the timeout callback, before
// calling into the Metal API.
auto state = base::MakeRefCounted<TestShaderState>(
std::move(callback), TestShaderComponent::kCompile, timeout);
base::ThreadPool::PostDelayedTask(
FROM_HERE, {}, base::BindOnce(&TestShaderState::OnTimeout, state),
timeout);
const std::string shader_source =
base::StringPrintf(kTestShaderSource, base::RandDouble());
base::scoped_nsobject<NSString> source([[NSString alloc]
initWithCString:shader_source.c_str()
encoding:NSASCIIStringEncoding]);
base::scoped_nsobject<MTLCompileOptions> options(
[[MTLCompileOptions alloc] init]);
MTLNewLibraryCompletionHandler completion_handler =
^(id<MTLLibrary> library, NSError* error) {
state->OnCompletionHandlerCalled(library ? TestShaderResult::kSucceeded
: TestShaderResult::kFailed);
};
[device newLibraryWithSource:source
options:options
completionHandler:completion_handler];
state->OnMethodCompleted();
}
} // namespace
void TestShader(TestShaderCallback callback,
const base::TimeDelta& delay,
const base::TimeDelta& timeout) {
bool disabled_at_command_line =
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableMetalTestShaders);
if (disabled_at_command_line)
return;
// Select a component to test at random.
TestShaderComponent component = base::RandInt(0, 1)
? TestShaderComponent::kLink
: TestShaderComponent::kCompile;
// The metallib listed above is in MTLLanguageVersion2_1, which is available
// only on 10.14 and above.
if (@available(macOS 10.14, *)) {
base::scoped_nsprotocol<id<MTLDevice>> device(CreateDefaultDevice());
if (device) {
// Select the callback depending on if we're testing online or offline
// compile.
base::OnceClosure closure;
switch (component) {
case TestShaderComponent::kCompile:
closure = base::BindOnce(&TestShaderNow, device, timeout,
std::move(callback));
break;
case TestShaderComponent::kLink:
closure = base::BindOnce(&TestRenderPipelineStateNow, device, timeout,
std::move(callback));
break;
}
if (closure) {
base::ThreadPool::PostDelayedTask(FROM_HERE,
{base::TaskPriority::HIGHEST},
std::move(closure), delay);
return;
}
}
}
std::move(callback).Run(component, TestShaderResult::kNotAttempted,
base::TimeDelta());
}
} // namespace metal