// インスタンス作成 CWindow* CWindow::Create( IMemoryAllocator* allocator, HINSTANCE hInst, HWND hWnd, HDC hDC) { void* buf = ALLOC_ZERO(allocator, sizeof(CWindow)); VRETURN_NULL(buf != IZ_NULL); CWindow* window = new(buf) CWindow(hInst, hWnd, hDC); window->m_Allocator = allocator; return window; }
// インスタンス作成 CVertexBufferGLES2* CVertexBufferGLES2::CreateVertexBuffer( CGraphicsDeviceGLES2* device, IMemoryAllocator* allocator, IZ_UINT stride, IZ_UINT vtxNum, E_GRAPH_RSC_USAGE usage) { IZ_BOOL result = IZ_TRUE; IZ_UINT8* buf = IZ_NULL; CVertexBufferGLES2* instance = IZ_NULL; // メモリ確保 buf = (IZ_UINT8*)ALLOC_ZERO(allocator, sizeof(CVertexBufferGLES2)); if (!(result = (buf != IZ_NULL))) { IZ_ASSERT(IZ_FALSE); goto __EXIT__; } // インスタンス作成 instance = new (buf)CVertexBufferGLES2; { instance->AddRef(); instance->m_Allocator = allocator; SAFE_REPLACE(instance->m_Device, device); } // 本体作成 result = instance->CreateBody( device, stride, vtxNum, usage); if (!result) { goto __EXIT__; } __EXIT__: if (!result) { if (instance != IZ_NULL) { SAFE_RELEASE(instance); } else if (buf != IZ_NULL) { allocator->Free(buf); } } return instance; }
/** * インスタンス作成 */ CGraphicsDevice* CGraphicsDevice::CreateGraphicsDevice(IMemoryAllocator* allocator) { if (s_Instance != IZ_NULL) { // 作成済みなので何もしない return s_Instance; } IZ_ASSERT(allocator != IZ_NULL); IZ_BOOL result = IZ_TRUE; IZ_UINT8* buf = IZ_NULL; CGraphicsDeviceGLES2* instance = IZ_NULL; // メモリ確保 buf = (IZ_UINT8*)ALLOC_ZERO(allocator, sizeof(CGraphicsDeviceGLES2)); VGOTO(buf != IZ_NULL, __EXIT__); // インスタンス作成 instance = new(buf) CGraphicsDeviceGLES2; { instance->m_Allocator = allocator; instance->AddRef(); } if (!result) { goto __EXIT__; } s_Instance = instance; __EXIT__: if (!result) { if (instance != IZ_NULL) { SAFE_RELEASE(instance); } else if (buf != IZ_NULL) { allocator->Free(buf); } } return instance; }
/** * インスタンス作成 */ CPad* CPadDInput::CreatePad( IMemoryAllocator* pAllocator, SInputDeviceInitParam* initParam, IZ_FLOAT analogStickDeadZone) { IZ_UINT8* pBuf = IZ_NULL; CPadDInput* pInstance = IZ_NULL; IZ_BOOL result = IZ_FALSE; // メモリ確保 pBuf = (IZ_UINT8*)ALLOC_ZERO(pAllocator, sizeof(CPadDInput)); result = (pBuf != IZ_NULL); if (!result) { IZ_ASSERT(IZ_FALSE); goto __EXIT__; } // インスタンス作成 pInstance = new(pBuf) CPadDInput; { pInstance->AddRef(); pInstance->m_Allocator = pAllocator; result = pInstance->Init( initParam, analogStickDeadZone); } __EXIT__: if (!result) { if (pInstance != IZ_NULL) { SAFE_RELEASE(pInstance); } else { pAllocator->Free(pBuf); } } return pInstance; }
/** Helper function: read the next token from *s, advance *s to the end of the * token, and return the parsed token. Parse *<b>s</b> according to the list * of tokens in <b>table</b>. */ directory_token_t * get_next_token(memarea_t *area, const char **s, const char *eos, token_rule_t *table) { /** Reject any object at least this big; it is probably an overflow, an * attack, a bug, or some other nonsense. */ #define MAX_UNPARSED_OBJECT_SIZE (128*1024) /** Reject any line at least this big; it is probably an overflow, an * attack, a bug, or some other nonsense. */ #define MAX_LINE_LENGTH (128*1024) const char *next, *eol, *obstart; size_t obname_len; int i; directory_token_t *tok; obj_syntax o_syn = NO_OBJ; char ebuf[128]; const char *kwd = ""; tor_assert(area); tok = ALLOC_ZERO(sizeof(directory_token_t)); tok->tp = ERR_; /* Set *s to first token, eol to end-of-line, next to after first token */ *s = eat_whitespace_eos(*s, eos); /* eat multi-line whitespace */ tor_assert(eos >= *s); eol = memchr(*s, '\n', eos-*s); if (!eol) eol = eos; if (eol - *s > MAX_LINE_LENGTH) { RET_ERR("Line far too long"); } next = find_whitespace_eos(*s, eol); if (!strcmp_len(*s, "opt", next-*s)) { /* Skip past an "opt" at the start of the line. */ *s = eat_whitespace_eos_no_nl(next, eol); next = find_whitespace_eos(*s, eol); } else if (*s == eos) { /* If no "opt", and end-of-line, line is invalid */ RET_ERR("Unexpected EOF"); } /* Search the table for the appropriate entry. (I tried a binary search * instead, but it wasn't any faster.) */ for (i = 0; table[i].t ; ++i) { if (!strcmp_len(*s, table[i].t, next-*s)) { /* We've found the keyword. */ kwd = table[i].t; tok->tp = table[i].v; o_syn = table[i].os; *s = eat_whitespace_eos_no_nl(next, eol); /* We go ahead whether there are arguments or not, so that tok->args is * always set if we want arguments. */ if (table[i].concat_args) { /* The keyword takes the line as a single argument */ tok->args = ALLOC(sizeof(char*)); tok->args[0] = STRNDUP(*s,eol-*s); /* Grab everything on line */ tok->n_args = 1; } else { /* This keyword takes multiple arguments. */ if (get_token_arguments(area, tok, *s, eol)<0) { tor_snprintf(ebuf, sizeof(ebuf),"Far too many arguments to %s", kwd); RET_ERR(ebuf); } *s = eol; } if (tok->n_args < table[i].min_args) { tor_snprintf(ebuf, sizeof(ebuf), "Too few arguments to %s", kwd); RET_ERR(ebuf); } else if (tok->n_args > table[i].max_args) { tor_snprintf(ebuf, sizeof(ebuf), "Too many arguments to %s", kwd); RET_ERR(ebuf); } break; } } if (tok->tp == ERR_) { /* No keyword matched; call it an "K_opt" or "A_unrecognized" */ if (**s == '@') tok->tp = A_UNKNOWN_; else tok->tp = K_OPT; tok->args = ALLOC(sizeof(char*)); tok->args[0] = STRNDUP(*s, eol-*s); tok->n_args = 1; o_syn = OBJ_OK; } /* Check whether there's an object present */ *s = eat_whitespace_eos(eol, eos); /* Scan from end of first line */ tor_assert(eos >= *s); eol = memchr(*s, '\n', eos-*s); if (!eol || eol-*s<11 || strcmpstart(*s, "-----BEGIN ")) /* No object. */ goto check_object; obstart = *s; /* Set obstart to start of object spec */ if (*s+16 >= eol || memchr(*s+11,'\0',eol-*s-16) || /* no short lines, */ strcmp_len(eol-5, "-----", 5) || /* nuls or invalid endings */ (eol-*s) > MAX_UNPARSED_OBJECT_SIZE) { /* name too long */ RET_ERR("Malformed object: bad begin line"); } tok->object_type = STRNDUP(*s+11, eol-*s-16); obname_len = eol-*s-16; /* store objname length here to avoid a strlen() */ *s = eol+1; /* Set *s to possible start of object data (could be eos) */ /* Go to the end of the object */ next = tor_memstr(*s, eos-*s, "-----END "); if (!next) { RET_ERR("Malformed object: missing object end line"); } tor_assert(eos >= next); eol = memchr(next, '\n', eos-next); if (!eol) /* end-of-line marker, or eos if there's no '\n' */ eol = eos; /* Validate the ending tag, which should be 9 + NAME + 5 + eol */ if ((size_t)(eol-next) != 9+obname_len+5 || strcmp_len(next+9, tok->object_type, obname_len) || strcmp_len(eol-5, "-----", 5)) { tor_snprintf(ebuf, sizeof(ebuf), "Malformed object: mismatched end tag %s", tok->object_type); ebuf[sizeof(ebuf)-1] = '\0'; RET_ERR(ebuf); } if (next - *s > MAX_UNPARSED_OBJECT_SIZE) RET_ERR("Couldn't parse object: missing footer or object much too big."); if (!strcmp(tok->object_type, "RSA PUBLIC KEY")) { /* If it's a public key */ tok->key = crypto_pk_new(); if (crypto_pk_read_public_key_from_string(tok->key, obstart, eol-obstart)) RET_ERR("Couldn't parse public key."); } else if (!strcmp(tok->object_type, "RSA PRIVATE KEY")) { /* private key */ tok->key = crypto_pk_new(); if (crypto_pk_read_private_key_from_string(tok->key, obstart, eol-obstart)) RET_ERR("Couldn't parse private key."); } else { /* If it's something else, try to base64-decode it */ int r; tok->object_body = ALLOC(next-*s); /* really, this is too much RAM. */ r = base64_decode(tok->object_body, next-*s, *s, next-*s); if (r<0) RET_ERR("Malformed object: bad base64-encoded data"); tok->object_size = r; } *s = eol; check_object: tok = token_check_object(area, kwd, tok, o_syn); done_tokenizing: return tok; #undef RET_ERR #undef ALLOC #undef ALLOC_ZERO #undef STRDUP #undef STRNDUP }
IZ_BOOL DxtEncoder::init( izanagi::IMemoryAllocator* allocator, izanagi::graph::CGraphicsDevice* device, IZ_UINT width, IZ_UINT height, const char* vtxShader, const char* dxtShader, const char* pixelShader) { m_width = width; m_height = height; char* buf = nullptr; IZ_UINT allocatedSize = 0; { izanagi::CFileInputStream in; VRETURN(in.Open(dxtShader)); allocatedSize = in.GetSize(); buf = (char*)ALLOC(allocator, allocatedSize); in.Read(buf, 0, allocatedSize); buf[allocatedSize] = 0; m_dxt = device->CreatePixelShader(buf); VRETURN(m_dxt); } { izanagi::CFileInputStream in; VRETURN(in.Open(vtxShader)); auto size = in.GetSize(); IZ_ASSERT(allocatedSize >= size); in.Read(buf, 0, size); buf[size] = 0; m_vs = device->CreateVertexShader(buf); VRETURN(m_vs); } { izanagi::CFileInputStream in; VRETURN(in.Open(pixelShader)); auto size = in.GetSize(); IZ_ASSERT(allocatedSize >= size); in.Read(buf, 0, size); buf[size] = 0; m_ps = device->CreatePixelShader(buf); VRETURN(m_ps); } FREE(allocator, buf); { m_shd = device->CreateShaderProgram(); VRETURN(m_shd); VRETURN(m_shd->AttachVertexShader(m_vs)); VRETURN(m_shd->AttachPixelShader(m_dxt)); } { m_shdDraw = device->CreateShaderProgram(); VRETURN(m_shdDraw); VRETURN(m_shdDraw->AttachVertexShader(m_vs)); VRETURN(m_shdDraw->AttachPixelShader(m_ps)); } { // NOTE // DXTは 4x4 ブロックで、128bit/block. // GL_RGBA32UI は 128bit/texel. // すると、1texel が DXTのブロックのサイズと同じになるので、fragment shaderの1pixel出力がそのままDXTの1ブロックになる. m_tex = device->CreateTexture( width / 4, height / 4, 1, izanagi::graph::E_GRAPH_PIXEL_FMT_RGBA32UI, izanagi::graph::E_GRAPH_RSC_USAGE_STATIC); VRETURN(m_tex); CALL_GL_API(glGenFramebuffers(1, &m_fbo)); glGenBuffers(1, &m_pbo); glBindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo); glBufferData(GL_PIXEL_PACK_BUFFER, width * height, 0, GL_STREAM_COPY); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); m_texDxt = device->CreateTexture( width, height, 1, izanagi::graph::E_GRAPH_PIXEL_FMT_DXT5, izanagi::graph::E_GRAPH_RSC_USAGE_STATIC); VRETURN(m_tex); } { m_allocator = allocator; // NOTE // RGBA : w * h * 4; // DXT5 : RGBA / 4 = (w * h * 4) / 4 = w * h auto size = width * height; m_pixels = ALLOC_ZERO(m_allocator, size); } return IZ_TRUE; }