コード例 #1
0
ファイル: glTextureManager.cpp プロジェクト: Hakansv/OpenCPN
void glTextureManager::OnEvtThread( OCPN_CompressionThreadEvent & event )
{
    JobTicket *ticket = event.GetTicket();

    if(ticket->b_isaborted || ticket->b_abort){
        for(int i=0 ; i < g_mipmap_max_level+1 ; i++) {
            free(ticket->comp_bits_array[i]);
            free( ticket->compcomp_bits_array[i] );
        }
        
        if(bthread_debug)
            printf( "    Abort job: %08X  Jobs running: %d             Job count: %lu   \n",
                    ticket->ident, GetRunningJobCount(), (unsigned long)todo_list.GetCount());
    } else if(!b_inCompressAllCharts) {
        //   Normal completion from here
        glTextureDescriptor *ptd = ticket->pFact->GetpTD( ticket->rect );
        if(ptd) {
            for(int i=0 ; i < g_mipmap_max_level+1 ; i++)
                ptd->comp_array[i] = ticket->comp_bits_array[i];

            if(ticket->bpost_zip_compress){
                for(int i=0 ; i < g_mipmap_max_level+1 ; i++){
                    ptd->compcomp_array[i] = ticket->compcomp_bits_array[i];
                    ptd->compcomp_size[i] = ticket->compcomp_size_array[i];
                }
            }

            // We need to force a refresh to replace the uncompressed texture
            // This frees video memory and is also really required if we had
            // gone up a mipmap level
            extern ChartCanvas *cc1;
            if(cc1) {
                glChartCanvas::Invalidate(); // ensure we refresh
                cc1->Refresh();
            }
            ptd->compdata_ticks = 10;
        }

        if(bthread_debug)
            printf( "    Finished job: %08X  Jobs running: %d             Job count: %lu   \n",
                    ticket->ident, GetRunningJobCount(), (unsigned long)todo_list.GetCount());
    }

    //      Free all possible memory
    if(b_inCompressAllCharts) { // if compressing all write cache here
        ChartBase *pchart = ChartData->OpenChartFromDB(ticket->m_ChartPath, FULL_INIT );
        ChartData->DeleteCacheChart(pchart);
        delete ticket->pFact;
    }

    delete ticket;

    if(g_raster_format != GL_COMPRESSED_RGB_FXT1_3DFX) {
        running_list.DeleteObject(ticket);
        StartTopJob();
    }
}
コード例 #2
0
bool glTextureManager::StartTopJob()
{
    wxJobListNode *node = todo_list.GetFirst();
    if(!node)
        return false;

    JobTicket *ticket = node->GetData();

    //  Is it possible to start another job?
    if(GetRunningJobCount() >= wxMax(m_max_jobs - ticket->b_throttle, 1))
        return false;

    todo_list.DeleteNode(node);

    glTextureDescriptor *ptd = ticket->pFact->GetpTD( ticket->rect );
    // don't need the job if we already have the compressed data
    if(ptd->comp_array[0]) {
        delete ticket;
        return StartTopJob();
    }

    if(ptd->map_array[0]) {
        if(ticket->level_min_request == 0) {
            // give level 0 buffer to the ticket
            ticket->level0_bits = ptd->map_array[0];
            ptd->map_array[0] = NULL;
        } else {
            // would be nicer to use reference counters
            int size = TextureTileSize(0, false);
            ticket->level0_bits = (unsigned char*)malloc(size);
            memcpy(ticket->level0_bits, ptd->map_array[0], size);
        }
    }

    running_list.Append(ticket);
    DoThreadJob(ticket);

    return true;
}
コード例 #3
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;
}
コード例 #4
0
void glTextureManager::OnEvtThread( OCPN_CompressionThreadEvent & event )
{
    JobTicket *ticket = event.GetTicket();

    if(event.type ==1){
        if(m_progDialog){
            
            // Look for a matching entry...
            bool bfound = false;
            ProgressInfoItem *item;
            wxProgressInfoListNode *tnode = progList.GetFirst();
            while(tnode){
                item = tnode->GetData();
                if(item->file_path == ticket->m_ChartPath){
                    bfound = true;
                    break;
                }
                tnode = tnode->GetNext();
            }
            if(bfound){
                wxString msgx;
                if(1){
                    int bar_length = NBAR_LENGTH;
                    if(m_bcompact)
                        bar_length = 20;
                    
                    msgx += _T("\n[");
                    wxString block = wxString::Format(_T("%c"), 0x2589);
                    float cutoff = ((event.nstat+1) / (float)event.nstat_max) * bar_length;
                    for(int i=0 ; i < bar_length ; i++){
                        if(i <= cutoff)
                            msgx += block;
                        else
                            msgx += _T("-");
                    }
                    msgx += _T("]");

                    if(!m_bcompact){
                        wxString msgy;
                        msgy.Printf(_T("  [%3d/%3d]  "), event.nstat+1, event.nstat_max);
                        msgx += msgy;
                
                        wxFileName fn(ticket->m_ChartPath);
                        msgx += fn.GetFullName();
                    }
                }
                else
                    msgx.Printf(_T("\n %3d/%3d"), event.nstat+1, event.nstat_max);
                
                item->msgx = msgx;
            }

                // look for an empty slot
            else{
                bool bfound_empty = false;
                tnode = progList.GetFirst();
                while(tnode){
                    item = tnode->GetData();
                    if(item->file_path.IsEmpty()){
                        bfound_empty = true;
                        break;
                    }
                    
                    tnode = tnode->GetNext();
                }
                
                if(bfound_empty){
                    item->file_path = ticket->m_ChartPath;
                    wxString msgx;
                    msgx.Printf(_T("\n [%3d/%3d]"), event.nstat+1, event.nstat_max);
                    item->msgx = msgx;
                }
            }
        
            // Ready to compose
            wxString msg;
            tnode = progList.GetFirst();
            while(tnode){
                item = tnode->GetData();
                msg += item->msgx + _T("\n");
                tnode = tnode->GetNext();
            }
            
            if(m_skipout)
                m_progMsg = _T("Skipping, please wait...\n\n");
            
            m_progDialog->Update(m_jcnt, m_progMsg + msg, &m_skip );
            if(m_skip)
                m_skipout = true;
            return;
        }
    }
    
    if(ticket->b_isaborted || ticket->b_abort){
        for(int i=0 ; i < g_mipmap_max_level+1 ; i++) {
            free(ticket->comp_bits_array[i]);
            free( ticket->compcomp_bits_array[i] );
        }
        
        if(bthread_debug)
            printf( "    Abort job: %08X  Jobs running: %d             Job count: %lu   \n",
                    ticket->ident, GetRunningJobCount(), (unsigned long)todo_list.GetCount());
    } else if(!b_inCompressAllCharts) {
        //   Normal completion from here
        glTextureDescriptor *ptd = ticket->pFact->GetpTD( ticket->rect );
        if(ptd) {
            for(int i=0 ; i < g_mipmap_max_level+1 ; i++)
                ptd->comp_array[i] = ticket->comp_bits_array[i];

            if(ticket->bpost_zip_compress){
                for(int i=0 ; i < g_mipmap_max_level+1 ; i++){
                    ptd->compcomp_array[i] = ticket->compcomp_bits_array[i];
                    ptd->compcomp_size[i] = ticket->compcomp_size_array[i];
                }
            }

                    
                    
            // We need to force a refresh to replace the uncompressed texture
            // This frees video memory and is also really required if we had
            // gone up a mipmap level
            extern ChartCanvas *cc1;
            if(cc1) {
                glChartCanvas::Invalidate(); // ensure we refresh
                cc1->Refresh();
            }
            ptd->compdata_ticks = 10;
        }

        if(bthread_debug)
            printf( "    Finished job: %08X  Jobs running: %d             Job count: %lu   \n",
                    ticket->ident, GetRunningJobCount(), (unsigned long)todo_list.GetCount());
    }

    //      Free all possible memory
    if(b_inCompressAllCharts) { // if compressing all write cache here
        ChartBase *pchart = ChartData->OpenChartFromDB(ticket->m_ChartPath, FULL_INIT );
        ChartData->DeleteCacheChart(pchart);
        delete ticket->pFact;
    }

    wxProgressInfoListNode *tnode = progList.GetFirst();
    while(tnode){
        ProgressInfoItem *item = tnode->GetData();
        if(item->file_path == ticket->m_ChartPath)
            item->file_path = _T("");
        tnode = tnode->GetNext();
    }
    
    delete ticket;

    if(g_raster_format != GL_COMPRESSED_RGB_FXT1_3DFX) {
        running_list.DeleteObject(ticket);
        StartTopJob();
    }
}