Example #1
0
// メモリの使用状態を表示する
void PrintMemoryStatus()
{
    MEMORY_STATUS s;
    GetMemoryStatus(&s);
    Print("MEMORY STATUS:\n"
          " NUM_OF_MEMORY_BLOCKS: %u\n"
          " SIZE_OF_TOTAL_MEMORY: %u bytes\n",
          s.MemoryBlocksNum, s.MemorySize);
}
Example #2
0
void glTextureManager::OnTimer(wxTimerEvent &event)
{
    m_ticks++;
    
    //  Scrub all the TD's, looking for any completed compression jobs
    //  that have finished
    //  In the interest of not disturbing the GUI, process only one TD per tick
    if(g_GLOptions.m_bTextureCompression) {
        for(ChartPathHashTexfactType::iterator itt = m_chart_texfactory_hash.begin();
            itt != m_chart_texfactory_hash.end(); ++itt ) {
            glTexFactory *ptf = itt->second;
            if(ptf && ptf->OnTimer())
                ;//break;
        }
    }

#if 0
    if((m_ticks % 4/*120*/) == 0){
    
    // inventory
    int mem_total, mem_used;
    GetMemoryStatus(&mem_total, &mem_used);

    int map_size = 0;
    int comp_size = 0;
    int compcomp_size = 0;
    
    for(ChartPathHashTexfactType::iterator itt = m_chart_texfactory_hash.begin();
        itt != m_chart_texfactory_hash.end(); ++itt ) {
        glTexFactory *ptf = itt->second;

        ptf->AccumulateMemStatistics(map_size, comp_size, compcomp_size);
    }

    int m1 = 1024 * 1024;
//    wxString path = wxFileName(m_ChartPath).GetName();
    printf("%6d %6ld Map: %10d  Comp:%10d  CompComp: %10d \n", mem_used/1024, g_tex_mem_used/m1, map_size, comp_size, compcomp_size);//, path.mb_str().data());
  
///    qDebug() << "inv" << map_size/m1 << comp_size/m1 << compcomp_size/m1 << g_tex_mem_used/m1 << mem_used/1024;
    }
#endif
}
Example #3
0
int CFileLoader::Write()
{
	if ( !IsLoaded() )
		return ERROR_FILE_NOT_FOUND;

	if ( !m_data.vStarts.size() || !m_data.vEnemy.size() || !m_data.vLevel.size() )
		return ERROR_NOINTERFACE;

	int err = 0;
	std::vector<BYTE> file = m_File.vFile;

	DWORD systemData = 0, levelData = 0, enemyData = 0, occupiedSpace = 0, totalSpace = 0;
	
	// first, apply modifications to levels
	for(int i = 0; i < MAX_LEVELS; ++i)
		if ( m_vEditors[i]->Changed() )
			m_vEditors[i]->Apply();

	if ( !GetMemoryStatus(systemData, levelData, enemyData, occupiedSpace, totalSpace) || occupiedSpace >= totalSpace 
		|| file.size() < NES_PTR_EOF )
		return ERROR_NOT_ENOUGH_MEMORY;

	const DWORD DELTA_PTR = 0x8010;

	std::vector<DWORD> vLevels, vEnemies;

	m_ptr.ptrLevelStarts = NES_PTR_START - DELTA_PTR;
	CopyMemory(&file[NES_PTR_START], &m_data.vStarts[0], m_data.vStarts.size());

	m_ptr.ptrLevels[0] = m_ptr.ptrLevelStarts + m_data.vStarts.size();
	m_ptr.ptrLevels[1] = m_ptr.ptrLevels[0] + MAX_LEVELS;

	// write levels banks
	DWORD ptr = m_ptr.ptrLevels[1] + MAX_LEVELS;
	int c = m_data.vLevel.size();
	for(int i = 0; i < c; ++i)
	{
		vLevels.push_back(ptr);

		PBYTE pArray = NULL;
		DWORD dwSize = 0;
		if ( m_data.vLevel[i]->MakeByteArray(&pArray, &dwSize) &&
			ptr + dwSize + DELTA_PTR < NES_PTR_EOF )
		{
			CopyMemory(&file[ptr + DELTA_PTR], pArray, dwSize);
			ptr += dwSize;
			delete[] pArray;
		}
		else
			return ERROR_NOT_ENOUGH_MEMORY;
	}

	// write level pointers
	for(int i = 0; i < MAX_LEVELS; ++i)
	{
		file[m_ptr.ptrLevels[1] + DELTA_PTR + i] = HIBYTE(LOWORD(vLevels[m_game.nLevel[i] - 1]));
		file[m_ptr.ptrLevels[0] + DELTA_PTR + i] = LOBYTE(LOWORD(vLevels[m_game.nLevel[i] - 1]));
	}

	// now update place of enemies data
	// note, that we already checked, that we have enough space to store all data

	// enemies pointers arrays
	DWORD dwEnmPtrsSize = MAX_LEVELS * 2 + ( MAX_LEVELS / 10 ) * 4;
	DWORD eptr = max(ptr, m_ptr.ptrEnemies[0]);

	if ( eptr + dwEnmPtrsSize + enemyData + DELTA_PTR > NES_PTR_EOF )	// move data backward
		eptr = NES_PTR_EOF - DELTA_PTR - enemyData - dwEnmPtrsSize;
	
	if ( eptr < ptr ) // cant rewrite level data, but it shall be always false
		return ERROR_NOT_ENOUGH_MEMORY;
	
	if ( ptr < eptr )	// fill free space with 'ff'
		for(DWORD p = ptr + DELTA_PTR; p < eptr + DELTA_PTR; ++p)
			file[p] = 0xFF;
	
	m_ptr.ptrEnemies[0] = eptr;
	m_ptr.ptrEnemies[1] = m_ptr.ptrEnemies[0] + MAX_LEVELS / 10;
	m_ptr.ptrEnemies[2] = m_ptr.ptrEnemies[1] + MAX_LEVELS / 10;
	m_ptr.ptrEnemies[3] = m_ptr.ptrEnemies[2] + MAX_LEVELS / 10;
	eptr = m_ptr.ptrEnemies[3] + MAX_LEVELS / 10;
	ptr = eptr + MAX_LEVELS * 2;
	// now 'eptr' points to start of array ptrs, 
	// and 'ptr' points to data
	
	c = m_data.vEnemy.size();
	for(int i = 0; i < c; ++i)
	{
		vEnemies.push_back(ptr);
		
		PBYTE pArray = NULL;
		DWORD dwSize = 0;
		if ( m_data.vEnemy[i]->MakeByteArray(&pArray, &dwSize) &&
			ptr + dwSize < NES_PTR_EOF )
		{
			CopyMemory(&file[ptr + DELTA_PTR], pArray, dwSize);
			delete[] pArray;

			ptr += dwSize;
		}
		else
			return ERROR_NOT_ENOUGH_MEMORY;
	}

	for(; ptr < NES_PTR_EOF - DELTA_PTR; ++ptr)
		file[ptr + DELTA_PTR] = 0xFF;

	// write enemies pointers
	for(int lv = 0; lv < MAX_LEVELS / 10; ++lv)
	{
		DWORD levelPtrHi = eptr + 20 * lv, levelPtrLo = eptr + 20 * lv + 10;
		file[m_ptr.ptrEnemies[0] + lv + DELTA_PTR] = HIBYTE(LOWORD(levelPtrHi));
		file[m_ptr.ptrEnemies[1] + lv + DELTA_PTR] = LOBYTE(LOWORD(levelPtrHi));
		file[m_ptr.ptrEnemies[2] + lv + DELTA_PTR] = HIBYTE(LOWORD(levelPtrLo));
		file[m_ptr.ptrEnemies[3] + lv + DELTA_PTR] = LOBYTE(LOWORD(levelPtrLo));

		for(int i = 0; i < 10; ++i)
		{
			file[levelPtrHi + DELTA_PTR + i] = HIBYTE(LOWORD(vEnemies[m_game.nEnemy[10 * lv + i] - 1]));
			file[levelPtrLo + DELTA_PTR + i] = LOBYTE(LOWORD(vEnemies[m_game.nEnemy[10 * lv + i] - 1]));
		}
	}

	// write from copy to a file array
	m_File.vFile = file;

	// write main pointers

	Short(NES_PTR_LEVEL_STARTS, LOWORD(m_ptr.ptrLevelStarts));
	Short(NES_PTR_LEVELS1, LOWORD(m_ptr.ptrLevels[0]));
	Short(NES_PTR_LEVELS2, LOWORD(m_ptr.ptrLevels[1]));
	Short(NES_PTR_ENEMY1, LOWORD(m_ptr.ptrEnemies[0]));
	Short(NES_PTR_ENEMY2, LOWORD(m_ptr.ptrEnemies[1]));
	Short(NES_PTR_ENEMY3, LOWORD(m_ptr.ptrEnemies[2]));
	Short(NES_PTR_ENEMY4, LOWORD(m_ptr.ptrEnemies[3]));

	return err;
}
Example #4
0
bool glTextureManager::ScheduleJob(glTexFactory* client, const wxRect &rect, int level,
                                   bool b_throttle_thread, bool b_nolimit, bool b_postZip, bool b_inplace)
{
    wxString chart_path = client->GetChartPath();
    if(!b_nolimit) {
        if(todo_list.GetCount() >= 50){
            // remove last job which is least important
            wxJobListNode *node = todo_list.GetLast();
            JobTicket *ticket = node->GetData();
            todo_list.DeleteNode(node);
            delete ticket;
        }

    //  Avoid adding duplicate jobs, i.e. the same chart_path, and the same rectangle
        wxJobListNode *node = todo_list.GetFirst();
        while(node){
            JobTicket *ticket = node->GetData();
            if( (ticket->m_ChartPath == chart_path) && (ticket->rect == rect)) {
                // bump to front
                todo_list.DeleteNode(node);
                todo_list.Insert(ticket);
                ticket->level_min_request = level;
                return false;
            }
        
            node = node->GetNext();
        }

        // avoid duplicate worker jobs
        wxJobListNode *tnode = running_list.GetFirst();
        while(tnode){
            JobTicket *ticket = tnode->GetData();
            if(ticket->rect == rect &&
               ticket->m_ChartPath == chart_path) {
                return false;
            }
            tnode = tnode->GetNext();
        }
    }
    
    JobTicket *pt = new JobTicket;
    pt->pFact = client;
    pt->rect = rect;
    pt->level_min_request = level;
    glTextureDescriptor *ptd = client->GetOrCreateTD( pt->rect );
    pt->ident = (ptd->tex_name << 16) + level;
    pt->b_throttle = b_throttle_thread;
    pt->m_ChartPath = chart_path;

    pt->level0_bits = NULL;
    pt->b_abort = false;
    pt->b_isaborted = false;
    pt->bpost_zip_compress = b_postZip;
    pt->binplace = b_inplace;

    /* do we compress in ram using builtin libraries, or do we
       upload to the gpu and use the driver to perform compression?
       we have builtin libraries for DXT1 (squish) and ETC1 (etcpak)
       FXT1 must use the driver, ETC1 cannot, and DXT1 can use the driver
       but the results are worse and don't compress well.

    additionally, if we use the driver we must stay single threaded in this thread
    (unless we created multiple opengl contexts), but with with our own libraries,
    we can use multiple threads to take advantage of multiple cores */

    if(g_raster_format != GL_COMPRESSED_RGB_FXT1_3DFX) {
        todo_list.Insert(pt); // push to front as a stack
        if(bthread_debug){
            int mem_used;
            GetMemoryStatus(0, &mem_used);
            printf( "Adding job: %08X  Job Count: %lu  mem_used %d\n", pt->ident, (unsigned long)todo_list.GetCount(), mem_used);
        }
 
        StartTopJob();
    }
    else {
        // give level 0 buffer to the ticket
        pt->level0_bits = ptd->map_array[0];
        ptd->map_array[0] = NULL;
        
        pt->DoJob();

        OCPN_CompressionThreadEvent Nevent(wxEVT_OCPN_COMPRESSIONTHREAD, 0);
        Nevent.type = 0;
        Nevent.SetTicket(pt);
        ProcessEventLocally(Nevent);
        // from here m_ticket is undefined (if deleted in event handler)
    }
    return true;
}
Example #5
0
bool glTextureManager::FactoryCrunch(double factor)
{
    if (m_chart_texfactory_hash.size() == 0) {
        /* nothing to free */
        return false;
    }

    int mem_used, mem_start;
    GetMemoryStatus(0, &mem_used);
    double hysteresis = 0.90;
    mem_start = mem_used;
    ChartPathHashTexfactType::iterator it0;

    bool bMemCrunch = (mem_used > (double)(g_memCacheLimit) * factor *hysteresis && 
                       mem_used > (double)(m_prevMemUsed) * factor *hysteresis)
        || (m_chart_texfactory_hash.size() > MAX_CACHE_FACTORY);
    //  Need more, so delete the oldest factory
    if(!bMemCrunch)
        return false;
        
    //      Find the oldest unused factory
    int lru_oldest = 2147483647;
    glTexFactory *ptf_oldest = NULL;
        
    for( it0 = m_chart_texfactory_hash.begin(); it0 != m_chart_texfactory_hash.end(); ++it0 ) {
        wxString chart_full_path = it0->first;
        glTexFactory *ptf = it0->second;
        if(!ptf)
            continue;
        
        // we better have to find one because glTexFactory keep cache texture open
        // and ocpn will eventually run out of file descriptors
        if( cc1->GetVP().b_quilt )          // quilted
        {
            if( cc1->m_pQuilt && cc1->m_pQuilt->IsComposed() &&
                !cc1->m_pQuilt->IsChartInQuilt( chart_full_path ) ) {
                
                int lru = ptf->GetLRUTime();
                if(lru < lru_oldest && !ptf->BackgroundCompressionAsJob()){
                    lru_oldest = lru;
                    ptf_oldest = ptf;
                }
            }
        } else {
            if( !Current_Ch->GetFullPath().IsSameAs(chart_full_path)) {
                int lru = ptf->GetLRUTime();
                if(lru < lru_oldest && !ptf->BackgroundCompressionAsJob()){
                    lru_oldest = lru;
                    ptf_oldest = ptf;
                }
            }
        }
    }
                    
    //      Found one?
    if(!ptf_oldest)
        return false;

    ptf_oldest->FreeSome( g_memCacheLimit * factor * hysteresis);

    GetMemoryStatus(0, &mem_used);

    bMemCrunch = (mem_used > (double)(g_memCacheLimit) * factor *hysteresis && 
                  mem_used > (double)(m_prevMemUsed) * factor *hysteresis)
        || (m_chart_texfactory_hash.size() > MAX_CACHE_FACTORY);
    //  Need more memory, so delete the oldest factory
    if(!bMemCrunch)
        return false;

    m_chart_texfactory_hash.erase(ptf_oldest->GetChartPath());                // This chart  becoming invalid
                
    delete ptf_oldest;
    
//    int mem_now;
//    GetMemoryStatus(0, &mem_now);
//    printf(">>>>FactoryCrunch  was: %d  is:%d \n", mem_start, mem_now);

    return true;
}