Esempio n. 1
0
void BackgroundLoader::FinishResources(int maxMs)
{
    if (IsStarted())
    {
        HiresTimer timer;

        backgroundLoadMutex_.Acquire();

        for (auto i = backgroundLoadQueue_.begin();
             i != backgroundLoadQueue_.end();)
        {
            Resource* resource = i->second.resource_;
            unsigned numDeps = i->second.dependencies_.size();
            AsyncLoadState state = resource->GetAsyncLoadState();
            if (numDeps > 0 || state == ASYNC_QUEUED || state == ASYNC_LOADING)
                ++i;
            else
            {
                // Finishing a resource may need it to wait for other resources to load, in which case we can not
                // hold on to the mutex
                backgroundLoadMutex_.Release();
                FinishBackgroundLoading(i->second);
                backgroundLoadMutex_.Acquire();
                i = backgroundLoadQueue_.erase(i);
            }

            // Break when the time limit passed so that we keep sufficient FPS
            if (timer.GetUSec(false) >= maxMs * 1000LL)
                break;
        }

        backgroundLoadMutex_.Release();
    }
}
//=============================================================================
//=============================================================================
void StaticModelPoolMgr::CreateBVH()
{
    // default settings 
    Platform platform;
    BVH::BuildParams params;
    BVH::Stats bvhStats;
    params.stats = &bvhStats;

    // disable print in NVraytrav
    params.enablePrints = false;

    // create bvh
    HiresTimer htimer;
    m_pNvScene->CreateBVH( &platform, &params );
    long long elapsed = htimer.GetUSec( true );

    // stats
    params.enablePrints = true;
    if ( params.enablePrints )
    {
        const BVHNode *root = m_pNvScene->GetBVHRoot();

        SDL_Log("BVH build time=%I64d msec\n", elapsed/1000);
        SDL_Log("BVH builder: %d tris, %d vertices\n", m_pNvScene->getNumTriangles(), m_pNvScene->getNumVertices());
        SDL_Log("BVH: Scene bounds: (%.1f,%.1f,%.1f) - (%.1f,%.1f,%.1f)\n", 
                root->m_bounds.min().x, root->m_bounds.min().y, root->m_bounds.min().z,
                root->m_bounds.max().x, root->m_bounds.max().y, root->m_bounds.max().z);
        SDL_Log("BVH: SAHCost         = %.2f\n", params.stats->SAHCost );
        SDL_Log("BVH: branchingFactor = %d\n",   params.stats->branchingFactor );
        SDL_Log("BVH: numLeafNodes    = %d\n",   params.stats->numLeafNodes );
        SDL_Log("BVH: numInnerNodes   = %d\n",   params.stats->numInnerNodes );
        SDL_Log("BVH: numTris         = %d\n",   params.stats->numTris );
        SDL_Log("BVH: numChildNodes   = %d\n",   params.stats->numChildNodes );
    }
}
Esempio n. 3
0
void Scene::UpdateAsyncLoading()
{
    PROFILE(UpdateAsyncLoading);

    // If resources left to load, do not load nodes yet
    if (asyncProgress_.loadedResources_ < asyncProgress_.totalResources_)
        return;

    HiresTimer asyncLoadTimer;

    for (;;)
    {
        if (asyncProgress_.loadedNodes_ >= asyncProgress_.totalNodes_)
        {
            FinishAsyncLoading();
            return;
        }

        // Read one child node with its full sub-hierarchy either from binary or XML
        /// \todo Works poorly in scenes where one root-level child node contains all content
        if (!asyncProgress_.xmlFile_)
        {
            unsigned nodeID = asyncProgress_.file_->ReadUInt();
            Node* newNode = CreateChild(nodeID, nodeID < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
            resolver_.AddNode(nodeID, newNode);
            newNode->Load(*asyncProgress_.file_, resolver_);
        }
        else
        {
            unsigned nodeID = asyncProgress_.xmlElement_.GetInt("id");
            Node* newNode = CreateChild(nodeID, nodeID < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
            resolver_.AddNode(nodeID, newNode);
            newNode->LoadXML(asyncProgress_.xmlElement_, resolver_);
            asyncProgress_.xmlElement_ = asyncProgress_.xmlElement_.GetNext("node");
        }

        ++asyncProgress_.loadedNodes_;

        // Break if time limit exceeded, so that we keep sufficient FPS
        if (asyncLoadTimer.GetUSec(false) >= asyncLoadingMs_ * 1000)
            break;
    }

    using namespace AsyncLoadProgress;

    VariantMap& eventData = GetEventDataMap();
    eventData[P_SCENE] = this;
    eventData[P_PROGRESS] = GetAsyncProgress();
    eventData[P_LOADEDNODES] = asyncProgress_.loadedNodes_;
    eventData[P_TOTALNODES] = asyncProgress_.totalNodes_;
    eventData[P_LOADEDRESOURCES]  = asyncProgress_.loadedResources_;
    eventData[P_TOTALRESOURCES] = asyncProgress_.totalResources_;
    SendEvent(E_ASYNCLOADPROGRESS, eventData);
}
Esempio n. 4
0
void BackgroundLoader::WaitForResource(StringHash type, StringHash nameHash)
{
    backgroundLoadMutex_.Acquire();

    // Check if the resource in question is being background loaded
    ea::pair<StringHash, StringHash> key = ea::make_pair(type, nameHash);
    auto i = backgroundLoadQueue_.find(
        key);
    if (i != backgroundLoadQueue_.end())
    {
        backgroundLoadMutex_.Release();

        {
            Resource* resource = i->second.resource_;
            HiresTimer waitTimer;
            bool didWait = false;

            for (;;)
            {
                unsigned numDeps = i->second.dependencies_.size();
                AsyncLoadState state = resource->GetAsyncLoadState();
                if (numDeps > 0 || state == ASYNC_QUEUED || state == ASYNC_LOADING)
                {
                    didWait = true;
                    Time::Sleep(1);
                }
                else
                    break;
            }

            if (didWait)
                URHO3D_LOGDEBUG("Waited " + ea::to_string(waitTimer.GetUSec(false) / 1000) + " ms for background loaded resource " +
                         resource->GetName());
        }

        // This may take a long time and may potentially wait on other resources, so it is important we do not hold the mutex during this
        FinishBackgroundLoading(i->second);

        backgroundLoadMutex_.Acquire();
        backgroundLoadQueue_.erase(i);
        backgroundLoadMutex_.Release();
    }
    else
        backgroundLoadMutex_.Release();
}
Esempio n. 5
0
void WorkQueue::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
{
    // If no worker threads, complete low-priority work here
    if (threads_.Empty() && !queue_.Empty())
    {
        URHO3D_PROFILE(CompleteWorkNonthreaded);

        HiresTimer timer;

        while (!queue_.Empty() && timer.GetUSec(false) < maxNonThreadedWorkMs_ * 1000)
        {
            WorkItem* item = queue_.Front();
            queue_.PopFront();
            item->workFunction_(item, 0);
            item->completed_ = true;
        }
    }

    // Complete and signal items down to the lowest priority
    PurgeCompleted(0);
    PurgePool();
}
Esempio n. 6
0
int main()
{
    #ifdef _MSC_VER
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    #endif
    
    printf("Size of String: %d\n", sizeof(String));
    printf("Size of Vector: %d\n", sizeof(Vector<int>));
    printf("Size of List: %d\n", sizeof(List<int>));
    printf("Size of HashMap: %d\n", sizeof(HashMap<int, int>));
    printf("Size of RefCounted: %d\n", sizeof(RefCounted));

    {
        printf("\nTesting AutoPtr assignment\n");
        AutoPtr<Test> ptr1(new Test);
        AutoPtr<Test> ptr2;
        ptr2 = ptr1;
    }

    {
        printf("\nTesting AutoPtr copy construction\n");
        AutoPtr<Test> ptr1(new Test);
        AutoPtr<Test> ptr2(ptr1);
    }

    {
        printf("\nTesting AutoPtr detaching\n");
        AutoPtr<Test> ptr1(new Test);
        // We would now have a memory leak if we don't manually delete the object
        Test* object = ptr1.Detach();
        delete object;
    }

    {
        printf("\nTesting AutoPtr inside a vector\n");
        Vector<AutoPtr<Test> > vec;
        printf("Filling vector\n");
        for (size_t i = 0; i < 4; ++i)
            vec.Push(new Test());
        printf("Clearing vector\n");
        vec.Clear();
    }
    
    {
        printf("\nTesting SharedPtr\n");
        SharedPtr<TestRefCounted> ptr1(new TestRefCounted);
        SharedPtr<TestRefCounted> ptr2(ptr1);
        printf("Number of refs: %d\n", ptr1.Refs());
    }
    
    {
        printf("\nTesting WeakPtr\n");
        TestRefCounted* object = new TestRefCounted;
        WeakPtr<TestRefCounted> ptr1(object);
        WeakPtr<TestRefCounted> ptr2(ptr1);
        printf("Number of weak refs: %d expired: %d\n", ptr1.WeakRefs(), ptr1.IsExpired());
        ptr2.Reset();
        delete object;
        printf("Number of weak refs: %d expired: %d\n", ptr1.WeakRefs(), ptr1.IsExpired());
    }
    
    {
        printf("\nTesting Vector\n");
        HiresTimer t;
        Vector<int> vec;
        SetRandomSeed(0);
        for (size_t i = 0; i < NUM_ITEMS; ++i)
            vec.Push(Rand());
        int sum = 0;
        int count = 0;
        for (auto it = vec.Begin(); it != vec.End(); ++it)
        {
            sum += *it;
            ++count;
        }
        int usec = (int)t.ElapsedUSec();
        printf("Size: %d capacity: %d\n", vec.Size(), vec.Capacity());
        printf("Counted vector items %d, sum: %d\n", count, sum);
        printf("Processing took %d usec\n", usec);
    }

    {
        printf("\nTesting List\n");
        HiresTimer t;
        List<int> list;
        SetRandomSeed(0);
        for (size_t i = 0; i < NUM_ITEMS; ++i)
            list.Push(Rand());
        int sum = 0;
        int count = 0;
        for (auto it = list.Begin(); it != list.End(); ++it)
        {
            sum += *it;
            ++count;
        }
        int usec = (int)t.ElapsedUSec();
        printf("Size: %d\n", list.Size());
        printf("Counted list items %d, sum: %d\n", count, sum);
        printf("Processing took %d usec\n", usec);

        printf("\nTesting List insertion\n");
        List<int> list2;
        List<int> list3;
        for (int i = 0; i < 10; ++i)
            list3.Push(i);
        list2.Insert(list2.End(), list3);
        for (auto it = list2.Begin(); it != list2.End(); ++it)
            printf("%d ", *it);
        printf("\n");
    }
    
    {
        printf("\nTesting String\n");
        HiresTimer t;
        String test;
        for (size_t i = 0; i < NUM_ITEMS/4; ++i)
            test += "Test";
        String test2;
        test2.AppendWithFormat("Size: %d capacity: %d\n", test.Length(), test.Capacity());
        printf(test2.CString());
        test2 = test2.ToUpper();
        printf(test2.CString());
        test2.Replace("SIZE:", "LENGTH:");
        printf(test2.CString());
        int usec = (int)t.ElapsedUSec();
        printf("Processing took %d usec\n", usec);
    }
    
    {
        printf("\nTesting HashSet\n");
        HiresTimer t;
        size_t found = 0;
        unsigned sum = 0;
        HashSet<int> testHashSet;
        srand(0);
        found = 0;
        sum = 0;
        printf("Insert, search and iteration, %d keys\n", NUM_ITEMS);
        for (size_t i = 0; i < NUM_ITEMS; ++i)
        {
            int number = (rand() & 32767);
            testHashSet.Insert(number);
        }
        for (int i = 0; i < 32768; ++i)
        {
            if (testHashSet.Find(i) != testHashSet.End())
                ++found;
        }
        for (auto it = testHashSet.Begin(); it != testHashSet.End(); ++it)
            sum += *it;
        int usec = (int)t.ElapsedUSec();
        printf("Set size and sum: %d %d\n", testHashSet.Size(), sum);
        printf("Processing took %d usec\n", usec);
    }

    {
        printf("\nTesting HashMap\n");
        HashMap<int, int> testHashMap;

        for (int i = 0; i < 10; ++i)
            testHashMap.Insert(MakePair(i, rand() & 32767));

        printf("Keys: ");
        Vector<int> keys = testHashMap.Keys();
        for (size_t i = 0; i < keys.Size(); ++i)
            printf("%d ", keys[i]);
        printf("\n");
        printf("Values: ");
        Vector<int> values = testHashMap.Values();
        for (size_t i = 0; i < values.Size(); ++i)
            printf("%d ", values[i]);
        printf("\n");
    }

    return 0;
}