Commit 99fbbe86 by apatrick@chromium.org

Embed Blit shader byte code in binary.

Ran a WebGL conformance test that exercises the blitter - copy-tex-image-2d-formats. Review URL: https://codereview.appspot.com/6403043 git-svn-id: https://angleproject.googlecode.com/svn/trunk@1229 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 433f4aaa
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 1227 #define BUILD_REVISION 1229
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -8,119 +8,39 @@ ...@@ -8,119 +8,39 @@
#include "libGLESv2/Blit.h" #include "libGLESv2/Blit.h"
#include <d3dx9.h>
#include "common/debug.h" #include "common/debug.h"
#include "libGLESv2/main.h" #include "libGLESv2/main.h"
namespace namespace
{ {
// Standard Vertex Shader #include "libGLESv2/shaders/standardvs.h"
// Input 0 is the homogenous position. #include "libGLESv2/shaders/flipyvs.h"
// Outputs the homogenous position as-is. #include "libGLESv2/shaders/passthroughps.h"
// Outputs a tex coord with (0,0) in the upper-left corner of the screen and (1,1) in the bottom right. #include "libGLESv2/shaders/luminanceps.h"
// C0.X must be negative half-pixel width, C0.Y must be half-pixel height. C0.ZW must be 0. #include "libGLESv2/shaders/componentmaskps.h"
const char standardvs[] =
"struct VS_OUTPUT\n"
"{\n"
" float4 position : POSITION;\n"
" float4 texcoord : TEXCOORD0;\n"
"};\n"
"\n"
"uniform float4 halfPixelSize : c0;\n"
"\n"
"VS_OUTPUT main(in float4 position : POSITION)\n"
"{\n"
" VS_OUTPUT Out;\n"
"\n"
" Out.position = position + halfPixelSize;\n"
" Out.texcoord = position * float4(0.5, -0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0);\n"
"\n"
" return Out;\n"
"}\n";
// Flip Y Vertex Shader
// Input 0 is the homogenous position.
// Outputs the homogenous position as-is.
// Outputs a tex coord with (0,1) in the upper-left corner of the screen and (1,0) in the bottom right.
// C0.XY must be the half-pixel width and height. C0.ZW must be 0.
const char flipyvs[] =
"struct VS_OUTPUT\n"
"{\n"
" float4 position : POSITION;\n"
" float4 texcoord : TEXCOORD0;\n"
"};\n"
"\n"
"uniform float4 halfPixelSize : c0;\n"
"\n"
"VS_OUTPUT main(in float4 position : POSITION)\n"
"{\n"
" VS_OUTPUT Out;\n"
"\n"
" Out.position = position + halfPixelSize;\n"
" Out.texcoord = position * float4(0.5, 0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0);\n"
"\n"
" return Out;\n"
"}\n";
// Passthrough Pixel Shader
// Outputs texture 0 sampled at texcoord 0.
const char passthroughps[] =
"sampler2D tex : s0;\n"
"\n"
"float4 main(float4 texcoord : TEXCOORD0) : COLOR\n"
"{\n"
" return tex2D(tex, texcoord.xy);\n"
"}\n";
// Luminance Conversion Pixel Shader
// Outputs sample(tex0, tc0).rrra.
// For LA output (pass A) set C0.X = 1, C0.Y = 0.
// For L output (A = 1) set C0.X = 0, C0.Y = 1.
const char luminanceps[] =
"sampler2D tex : s0;\n"
"\n"
"uniform float4 mode : c0;\n"
"\n"
"float4 main(float4 texcoord : TEXCOORD0) : COLOR\n"
"{\n"
" float4 tmp = tex2D(tex, texcoord.xy);\n"
" tmp.w = tmp.w * mode.x + mode.y;\n"
" return tmp.xxxw;\n"
"}\n";
// RGB/A Component Mask Pixel Shader
// Outputs sample(tex0, tc0) with options to force RGB = 0 and/or A = 1.
// To force RGB = 0, set C0.X = 0, otherwise C0.X = 1.
// To force A = 1, set C0.Z = 0, C0.W = 1, otherwise C0.Z = 1, C0.W = 0.
const char componentmaskps[] =
"sampler2D tex : s0;\n"
"\n"
"uniform float4 mode : c0;\n"
"\n"
"float4 main(float4 texcoord : TEXCOORD0) : COLOR\n"
"{\n"
" float4 tmp = tex2D(tex, texcoord.xy);\n"
" tmp.xyz = tmp.xyz * mode.x;\n"
" tmp.w = tmp.w * mode.z + mode.w;\n"
" return tmp;\n"
"}\n";
}
namespace gl const BYTE* const g_shaderCode[] =
{ {
g_vs20_standardvs,
g_vs20_flipyvs,
g_ps20_passthroughps,
g_ps20_luminanceps,
g_ps20_componentmaskps
};
const char * const Blit::mShaderSource[] = const size_t g_shaderSize[] =
{ {
standardvs, sizeof(g_vs20_standardvs),
flipyvs, sizeof(g_vs20_flipyvs),
passthroughps, sizeof(g_ps20_passthroughps),
luminanceps, sizeof(g_ps20_luminanceps),
componentmaskps sizeof(g_ps20_componentmaskps)
}; };
}
namespace gl
{
Blit::Blit(Context *context) Blit::Blit(Context *context)
: mContext(context), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL), mSavedStateBlock(NULL) : mContext(context), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL), mSavedStateBlock(NULL)
{ {
...@@ -206,26 +126,16 @@ bool Blit::setShader(ShaderId source, const char *profile, ...@@ -206,26 +126,16 @@ bool Blit::setShader(ShaderId source, const char *profile,
} }
else else
{ {
// FIXME: Complile these shaders offline and embed the byte code in the module. const BYTE* shaderCode = g_shaderCode[source];
ID3DXBuffer *shaderCode; size_t shaderSize = g_shaderSize[source];
HRESULT hr = D3DXCompileShader(mShaderSource[source], strlen(mShaderSource[source]), NULL, NULL, "main", profile, 0, &shaderCode, NULL, NULL);
if (FAILED(hr))
{
ERR("Failed to compile %s shader for blit operation %d, error 0x%08X.", profile, (int)source, hr);
return false;
}
shader = (display->*createShader)(static_cast<const DWORD*>(shaderCode->GetBufferPointer()), shaderCode->GetBufferSize()); shader = (display->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
if (FAILED(hr)) if (!shader)
{ {
shaderCode->Release(); ERR("Failed to create shader for blit operation");
ERR("Failed to create %s shader for blit operation %d, error 0x%08X.", profile, (int)source, hr);
return false; return false;
} }
shaderCode->Release();
mCompiledShaders[source] = shader; mCompiledShaders[source] = shader;
} }
...@@ -233,7 +143,7 @@ bool Blit::setShader(ShaderId source, const char *profile, ...@@ -233,7 +143,7 @@ bool Blit::setShader(ShaderId source, const char *profile,
if (FAILED(hr)) if (FAILED(hr))
{ {
ERR("Failed to set %s shader for blit operation %d, error 0x%08X.", profile, (int)source, hr); ERR("Failed to set shader for blit operation");
return false; return false;
} }
...@@ -242,12 +152,12 @@ bool Blit::setShader(ShaderId source, const char *profile, ...@@ -242,12 +152,12 @@ bool Blit::setShader(ShaderId source, const char *profile,
bool Blit::setVertexShader(ShaderId shader) bool Blit::setVertexShader(ShaderId shader)
{ {
return setShader<IDirect3DVertexShader9>(shader, mContext->supportsShaderModel3() ? "vs_3_0" : "vs_2_0", &egl::Display::createVertexShader, &IDirect3DDevice9::SetVertexShader); return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &egl::Display::createVertexShader, &IDirect3DDevice9::SetVertexShader);
} }
bool Blit::setPixelShader(ShaderId shader) bool Blit::setPixelShader(ShaderId shader)
{ {
return setShader<IDirect3DPixelShader9>(shader, mContext->supportsShaderModel3() ? "ps_3_0" : "ps_2_0", &egl::Display::createPixelShader, &IDirect3DDevice9::SetPixelShader); return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &egl::Display::createPixelShader, &IDirect3DDevice9::SetPixelShader);
} }
RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
......
...@@ -69,8 +69,6 @@ class Blit ...@@ -69,8 +69,6 @@ class Blit
SHADER_COUNT SHADER_COUNT
}; };
static const char * const mShaderSource[];
// This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown. // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown.
IUnknown *mCompiledShaders[SHADER_COUNT]; IUnknown *mCompiledShaders[SHADER_COUNT];
......
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
sampler2D tex : s0;
uniform float4 mode : c0;
// Passthrough Pixel Shader
// Outputs texture 0 sampled at texcoord 0.
float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR
{
return tex2D(tex, texcoord.xy);
};
// Luminance Conversion Pixel Shader
// Outputs sample(tex0, tc0).rrra.
// For LA output (pass A) set C0.X = 1, C0.Y = 0.
// For L output (A = 1) set C0.X = 0, C0.Y = 1.
float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR
{
float4 tmp = tex2D(tex, texcoord.xy);
tmp.w = tmp.w * mode.x + mode.y;
return tmp.xxxw;
};
// RGB/A Component Mask Pixel Shader
// Outputs sample(tex0, tc0) with options to force RGB = 0 and/or A = 1.
// To force RGB = 0, set C0.X = 0, otherwise C0.X = 1.
// To force A = 1, set C0.Z = 0, C0.W = 1, otherwise C0.Z = 1, C0.W = 0.
float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR
{
float4 tmp = tex2D(tex, texcoord.xy);
tmp.xyz = tmp.xyz * mode.x;
tmp.w = tmp.w * mode.z + mode.w;
return tmp;
};
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
struct VS_OUTPUT
{
float4 position : POSITION;
float4 texcoord : TEXCOORD0;
};
uniform float4 halfPixelSize : c0;
// Standard Vertex Shader
// Input 0 is the homogenous position.
// Outputs the homogenous position as-is.
// Outputs a tex coord with (0,0) in the upper-left corner of the screen and (1,1) in the bottom right.
// C0.X must be negative half-pixel width, C0.Y must be half-pixel height. C0.ZW must be 0.
VS_OUTPUT standardvs(in float4 position : POSITION)
{
VS_OUTPUT Out;
Out.position = position + halfPixelSize;
Out.texcoord = position * float4(0.5, -0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0);
return Out;
};
// Flip Y Vertex Shader
// Input 0 is the homogenous position.
// Outputs the homogenous position as-is.
// Outputs a tex coord with (0,1) in the upper-left corner of the screen and (1,0) in the bottom right.
// C0.XY must be the half-pixel width and height. C0.ZW must be 0.
VS_OUTPUT flipyvs(in float4 position : POSITION)
{
VS_OUTPUT Out;
Out.position = position + halfPixelSize;
Out.texcoord = position * float4(0.5, 0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0);
return Out;
};
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /E componentmaskps /T ps_2_0 /Fh componentmaskps.h Blit.ps
//
//
// Parameters:
//
// float4 mode;
// sampler2D tex;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// mode c0 1
// tex s0 1
//
ps_2_0
dcl t0.xy
dcl_2d s0
texld r0, t0, s0
mul r1.xyz, r0, c0.x
mad r1.w, r0.w, c0.z, c0.w
mov oC0, r1
// approximately 4 instruction slots used (1 texture, 3 arithmetic)
#endif
const BYTE g_ps20_componentmaskps[] =
{
0, 2, 255, 255, 254, 255,
43, 0, 67, 84, 65, 66,
28, 0, 0, 0, 119, 0,
0, 0, 0, 2, 255, 255,
2, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
112, 0, 0, 0, 68, 0,
0, 0, 2, 0, 0, 0,
1, 0, 0, 0, 76, 0,
0, 0, 0, 0, 0, 0,
92, 0, 0, 0, 3, 0,
0, 0, 1, 0, 0, 0,
96, 0, 0, 0, 0, 0,
0, 0, 109, 111, 100, 101,
0, 171, 171, 171, 1, 0,
3, 0, 1, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 116, 101, 120, 0,
4, 0, 12, 0, 1, 0,
1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 112, 115,
95, 50, 95, 48, 0, 77,
105, 99, 114, 111, 115, 111,
102, 116, 32, 40, 82, 41,
32, 72, 76, 83, 76, 32,
83, 104, 97, 100, 101, 114,
32, 67, 111, 109, 112, 105,
108, 101, 114, 32, 57, 46,
50, 57, 46, 57, 53, 50,
46, 51, 49, 49, 49, 0,
31, 0, 0, 2, 0, 0,
0, 128, 0, 0, 3, 176,
31, 0, 0, 2, 0, 0,
0, 144, 0, 8, 15, 160,
66, 0, 0, 3, 0, 0,
15, 128, 0, 0, 228, 176,
0, 8, 228, 160, 5, 0,
0, 3, 1, 0, 7, 128,
0, 0, 228, 128, 0, 0,
0, 160, 4, 0, 0, 4,
1, 0, 8, 128, 0, 0,
255, 128, 0, 0, 170, 160,
0, 0, 255, 160, 1, 0,
0, 2, 0, 8, 15, 128,
1, 0, 228, 128, 255, 255,
0, 0
};
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /E flipyvs /T vs_2_0 /Fh flipyvs.h Blit.vs
//
//
// Parameters:
//
// float4 halfPixelSize;
//
//
// Registers:
//
// Name Reg Size
// ------------- ----- ----
// halfPixelSize c0 1
//
vs_2_0
def c1, 0.5, 1, 0, 0
dcl_position v0
add oPos, v0, c0
mad oT0, v0, c1.xxyy, c1.xxzz
// approximately 2 instruction slots used
#endif
const BYTE g_vs20_flipyvs[] =
{
0, 2, 254, 255, 254, 255,
35, 0, 67, 84, 65, 66,
28, 0, 0, 0, 87, 0,
0, 0, 0, 2, 254, 255,
1, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
80, 0, 0, 0, 48, 0,
0, 0, 2, 0, 0, 0,
1, 0, 0, 0, 64, 0,
0, 0, 0, 0, 0, 0,
104, 97, 108, 102, 80, 105,
120, 101, 108, 83, 105, 122,
101, 0, 171, 171, 1, 0,
3, 0, 1, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 118, 115, 95, 50,
95, 48, 0, 77, 105, 99,
114, 111, 115, 111, 102, 116,
32, 40, 82, 41, 32, 72,
76, 83, 76, 32, 83, 104,
97, 100, 101, 114, 32, 67,
111, 109, 112, 105, 108, 101,
114, 32, 57, 46, 50, 57,
46, 57, 53, 50, 46, 51,
49, 49, 49, 0, 81, 0,
0, 5, 1, 0, 15, 160,
0, 0, 0, 63, 0, 0,
128, 63, 0, 0, 0, 0,
0, 0, 0, 0, 31, 0,
0, 2, 0, 0, 0, 128,
0, 0, 15, 144, 2, 0,
0, 3, 0, 0, 15, 192,
0, 0, 228, 144, 0, 0,
228, 160, 4, 0, 0, 4,
0, 0, 15, 224, 0, 0,
228, 144, 1, 0, 80, 160,
1, 0, 160, 160, 255, 255,
0, 0
};
@ECHO OFF
REM
REM Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
REM Use of this source code is governed by a BSD-style license that can be
REM found in the LICENSE file.
REM
PATH %PATH%;%DXSDK_DIR%\Utilities\bin\x86
fxc /E standardvs /T vs_2_0 /Fh standardvs.h Blit.vs
fxc /E flipyvs /T vs_2_0 /Fh flipyvs.h Blit.vs
fxc /E passthroughps /T ps_2_0 /Fh passthroughps.h Blit.ps
fxc /E luminanceps /T ps_2_0 /Fh luminanceps.h Blit.ps
fxc /E componentmaskps /T ps_2_0 /Fh componentmaskps.h Blit.ps
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /E luminanceps /T ps_2_0 /Fh luminanceps.h Blit.ps
//
//
// Parameters:
//
// float4 mode;
// sampler2D tex;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// mode c0 1
// tex s0 1
//
ps_2_0
dcl t0.xy
dcl_2d s0
texld r0, t0, s0
mad r1.w, r0.w, c0.x, c0.y
mov r1.xyz, r0.x
mov oC0, r1
// approximately 4 instruction slots used (1 texture, 3 arithmetic)
#endif
const BYTE g_ps20_luminanceps[] =
{
0, 2, 255, 255, 254, 255,
43, 0, 67, 84, 65, 66,
28, 0, 0, 0, 119, 0,
0, 0, 0, 2, 255, 255,
2, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
112, 0, 0, 0, 68, 0,
0, 0, 2, 0, 0, 0,
1, 0, 0, 0, 76, 0,
0, 0, 0, 0, 0, 0,
92, 0, 0, 0, 3, 0,
0, 0, 1, 0, 0, 0,
96, 0, 0, 0, 0, 0,
0, 0, 109, 111, 100, 101,
0, 171, 171, 171, 1, 0,
3, 0, 1, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 116, 101, 120, 0,
4, 0, 12, 0, 1, 0,
1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 112, 115,
95, 50, 95, 48, 0, 77,
105, 99, 114, 111, 115, 111,
102, 116, 32, 40, 82, 41,
32, 72, 76, 83, 76, 32,
83, 104, 97, 100, 101, 114,
32, 67, 111, 109, 112, 105,
108, 101, 114, 32, 57, 46,
50, 57, 46, 57, 53, 50,
46, 51, 49, 49, 49, 0,
31, 0, 0, 2, 0, 0,
0, 128, 0, 0, 3, 176,
31, 0, 0, 2, 0, 0,
0, 144, 0, 8, 15, 160,
66, 0, 0, 3, 0, 0,
15, 128, 0, 0, 228, 176,
0, 8, 228, 160, 4, 0,
0, 4, 1, 0, 8, 128,
0, 0, 255, 128, 0, 0,
0, 160, 0, 0, 85, 160,
1, 0, 0, 2, 1, 0,
7, 128, 0, 0, 0, 128,
1, 0, 0, 2, 0, 8,
15, 128, 1, 0, 228, 128,
255, 255, 0, 0
};
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /E passthroughps /T ps_2_0 /Fh passthroughps.h Blit.ps
//
//
// Parameters:
//
// sampler2D tex;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// tex s0 1
//
ps_2_0
dcl t0.xy
dcl_2d s0
texld r0, t0, s0
mov oC0, r0
// approximately 2 instruction slots used (1 texture, 1 arithmetic)
#endif
const BYTE g_ps20_passthroughps[] =
{
0, 2, 255, 255, 254, 255,
32, 0, 67, 84, 65, 66,
28, 0, 0, 0, 75, 0,
0, 0, 0, 2, 255, 255,
1, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
68, 0, 0, 0, 48, 0,
0, 0, 3, 0, 0, 0,
1, 0, 0, 0, 52, 0,
0, 0, 0, 0, 0, 0,
116, 101, 120, 0, 4, 0,
12, 0, 1, 0, 1, 0,
1, 0, 0, 0, 0, 0,
0, 0, 112, 115, 95, 50,
95, 48, 0, 77, 105, 99,
114, 111, 115, 111, 102, 116,
32, 40, 82, 41, 32, 72,
76, 83, 76, 32, 83, 104,
97, 100, 101, 114, 32, 67,
111, 109, 112, 105, 108, 101,
114, 32, 57, 46, 50, 57,
46, 57, 53, 50, 46, 51,
49, 49, 49, 0, 31, 0,
0, 2, 0, 0, 0, 128,
0, 0, 3, 176, 31, 0,
0, 2, 0, 0, 0, 144,
0, 8, 15, 160, 66, 0,
0, 3, 0, 0, 15, 128,
0, 0, 228, 176, 0, 8,
228, 160, 1, 0, 0, 2,
0, 8, 15, 128, 0, 0,
228, 128, 255, 255, 0, 0
};
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
//
// fxc /E standardvs /T vs_2_0 /Fh standardvs.h Blit.vs
//
//
// Parameters:
//
// float4 halfPixelSize;
//
//
// Registers:
//
// Name Reg Size
// ------------- ----- ----
// halfPixelSize c0 1
//
vs_2_0
def c1, 0.5, -0.5, 1, 0
dcl_position v0
add oPos, v0, c0
mad oT0, v0, c1.xyzz, c1.xxww
// approximately 2 instruction slots used
#endif
const BYTE g_vs20_standardvs[] =
{
0, 2, 254, 255, 254, 255,
35, 0, 67, 84, 65, 66,
28, 0, 0, 0, 87, 0,
0, 0, 0, 2, 254, 255,
1, 0, 0, 0, 28, 0,
0, 0, 0, 1, 0, 0,
80, 0, 0, 0, 48, 0,
0, 0, 2, 0, 0, 0,
1, 0, 0, 0, 64, 0,
0, 0, 0, 0, 0, 0,
104, 97, 108, 102, 80, 105,
120, 101, 108, 83, 105, 122,
101, 0, 171, 171, 1, 0,
3, 0, 1, 0, 4, 0,
1, 0, 0, 0, 0, 0,
0, 0, 118, 115, 95, 50,
95, 48, 0, 77, 105, 99,
114, 111, 115, 111, 102, 116,
32, 40, 82, 41, 32, 72,
76, 83, 76, 32, 83, 104,
97, 100, 101, 114, 32, 67,
111, 109, 112, 105, 108, 101,
114, 32, 57, 46, 50, 57,
46, 57, 53, 50, 46, 51,
49, 49, 49, 0, 81, 0,
0, 5, 1, 0, 15, 160,
0, 0, 0, 63, 0, 0,
0, 191, 0, 0, 128, 63,
0, 0, 0, 0, 31, 0,
0, 2, 0, 0, 0, 128,
0, 0, 15, 144, 2, 0,
0, 3, 0, 0, 15, 192,
0, 0, 228, 144, 0, 0,
228, 160, 4, 0, 0, 4,
0, 0, 15, 224, 0, 0,
228, 144, 1, 0, 164, 160,
1, 0, 240, 160, 255, 255,
0, 0
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment