//============================================================================== GlProgramPipelineHandle Material::getProgramPipeline( const RenderingKey& key) { ANKI_ASSERT((U)key.m_pass < m_passesCount); ANKI_ASSERT(key.m_lod < m_lodsCount); U tessCount = 1; if(key.m_tessellation) { ANKI_ASSERT(m_tessellation); tessCount = 2; } U idx = (U)key.m_pass * m_lodsCount * tessCount + key.m_lod * tessCount + key.m_tessellation; ANKI_ASSERT(idx < m_pplines.size()); GlProgramPipelineHandle& ppline = m_pplines[idx]; // Lazily create it if(ANKI_UNLIKELY(!ppline.isCreated())) { Array<GlProgramHandle, 5> progs; U progCount = 0; progs[progCount++] = getProgram(key, 0)->getGlProgram(); if(key.m_tessellation) { progs[progCount++] = getProgram(key, 1)->getGlProgram(); progs[progCount++] = getProgram(key, 2)->getGlProgram(); } progs[progCount++] = getProgram(key, 4)->getGlProgram(); GlDevice& gl = m_resources->_getGlDevice(); GlCommandBufferHandle cmdBuff(&gl); ppline = GlProgramPipelineHandle( cmdBuff, &progs[0], &progs[0] + progCount); cmdBuff.flush(); } return ppline; }
UINT WINAPI CWriteMain::TeeThread(LPVOID param) { CWriteMain* sys = (CWriteMain*)param; wstring cmd = sys->teeCmd; Replace(cmd, L"$FilePath$", sys->savePath); vector<WCHAR> cmdBuff(cmd.c_str(), cmd.c_str() + cmd.size() + 1); WCHAR szCurrentDir[_MAX_PATH]; DWORD ret = GetModuleFileName(NULL, szCurrentDir, _MAX_PATH); if( ret && ret < _MAX_PATH ){ //カレントは実行ファイルのあるフォルダ WCHAR szDrive[_MAX_DRIVE]; WCHAR szDir[_MAX_DIR]; _wsplitpath_s(szCurrentDir, szDrive, _MAX_DRIVE, szDir, _MAX_DIR, NULL, 0, NULL, 0); _wmakepath_s(szCurrentDir, szDrive, szDir, NULL, NULL); //標準入力にパイプしたプロセスを起動する HANDLE tempPipe; HANDLE writePipe; if( CreatePipe(&tempPipe, &writePipe, NULL, 0) ){ HANDLE readPipe; BOOL bRet = DuplicateHandle(GetCurrentProcess(), tempPipe, GetCurrentProcess(), &readPipe, 0, TRUE, DUPLICATE_SAME_ACCESS); CloseHandle(tempPipe); if( bRet ){ SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; STARTUPINFO si = {}; si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = readPipe; //標準(エラー)出力はnulデバイスに捨てる si.hStdOutput = CreateFile(L"nul", GENERIC_WRITE, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); si.hStdError = CreateFile(L"nul", GENERIC_WRITE, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); PROCESS_INFORMATION pi; bRet = CreateProcess(NULL, &cmdBuff.front(), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, szCurrentDir, &si, &pi); CloseHandle(readPipe); if( si.hStdOutput != INVALID_HANDLE_VALUE ){ CloseHandle(si.hStdOutput); } if( si.hStdError != INVALID_HANDLE_VALUE ){ CloseHandle(si.hStdError); } if( bRet ){ CloseHandle(pi.hThread); CloseHandle(pi.hProcess); while( sys->teeThreadStopFlag == FALSE ){ __int64 readablePos; { CBlockLock lock(&sys->wroteLock); readablePos = sys->wrotePos - sys->teeDelay; } LARGE_INTEGER liPos = {}; DWORD read; if( SetFilePointerEx(sys->teeFile, liPos, &liPos, FILE_CURRENT) && readablePos - liPos.QuadPart >= (__int64)sys->teeBuff.size() && ReadFile(sys->teeFile, &sys->teeBuff.front(), (DWORD)sys->teeBuff.size(), &read, NULL) && read > 0 ){ DWORD write; if( WriteFile(writePipe, &sys->teeBuff.front(), read, &write, NULL) == FALSE ){ break; } }else{ Sleep(100); } } //プロセスは回収しない(標準入力が閉じられた後にどうするかはプロセスの判断に任せる) } } CloseHandle(writePipe); } } return 0; }