//--------------------------------------------------------------------------
/// EndFrame is used to signal the end of a rendered frame and to stop/send
/// the captured results that were logged during the frame render.
/// \return Nothing.
//--------------------------------------------------------------------------
void MultithreadedTraceAnalyzerLayer::EndFrame()
{
    // Check again which trace type is active at the end of the frame. Need to match how it was started.
    int autotraceFlags = GetTraceTypeFlags();

    // If the linked trace was requested, return all of the results through a single response.
    bool bLinkedTraceRequested = (mCmdLinkedTrace.IsActive() || mCmdLinkedTraceWithSave.IsActive()) || (autotraceFlags == kTraceType_Linked);

    // Will we be required to dump the trace response to a file on disk?
    bool bSaveResponseToFile = mCmdLinkedTraceWithSave.IsActive();

    // If we want a linked trace, we'll need responses from all trace types.
    bool bAPITraceResponseNeeded = m_apiTraceTXT.IsActive() || bLinkedTraceRequested || (autotraceFlags & kTraceType_API);
    bool bGPUTraceResponseNeeded = m_cmdGPUTrace.IsActive() || bLinkedTraceRequested || (autotraceFlags & kTraceType_GPU);

    if (bAPITraceResponseNeeded || bGPUTraceResponseNeeded)
    {
        // We're done collecting, so turn off the interception and profiler switch.
        InterceptorBase* interceptor = GetInterceptor();
        interceptor->SetCollectTrace(false);
        interceptor->SetProfilingEnabled(false);

        AfterAPITrace();
        AfterGPUTrace();

        std::string apiTraceResponseString, gpuTraceResponseString;

        if (bAPITraceResponseNeeded)
        {
            mbCollectingApiTrace = false;
            apiTraceResponseString.assign(GetAPITraceTXT().c_str());
        }

        if (bGPUTraceResponseNeeded)
        {
            mbGPUTraceAlreadyCollected = false;
            gpuTraceResponseString.assign(GetGPUTraceTXT().c_str());
        }

        std::stringstream fullResponseString;

        if (bAPITraceResponseNeeded)
        {
#if !defined(CODEXL_GRAPHICS)

            // In Linked trace mode, insert a separator indicating the split between response types.
            if (bLinkedTraceRequested)
            {
                fullResponseString << "//Type:API" << std::endl;
            }

#endif
            fullResponseString << apiTraceResponseString.c_str() << std::endl;
        }

        if (bGPUTraceResponseNeeded)
        {
#if !defined(CODEXL_GRAPHICS)

            // In Linked trace mode, insert a separator indicating the split between response types.
            if (bLinkedTraceRequested)
            {
                fullResponseString << "//Type:GPU" << std::endl;
            }

#endif
            fullResponseString << gpuTraceResponseString.c_str() << std::endl;
        }

        // If the autotrace flags are anything besides "None," we'll just store the trace log internally so the client can pick it up later.
        bool bShouldCacheForAutotrace = (autotraceFlags != kTraceType_None);

        if (bShouldCacheForAutotrace)
        {
            // Don't send the response back through a command yet.
            // The client will know to pick it up through a special AutoCapture command.
            mCachedTraceResponse.assign(fullResponseString.str());
            mbWaitingForAutocaptureClient = true;
        }
        else
        {
            // Send the response string back to the server through a specific request command.
            if (bLinkedTraceRequested)
            {
                HandleLinkedTraceResponse(fullResponseString, bSaveResponseToFile);
            }
            else
            {
                if (bAPITraceResponseNeeded)
                {
                    m_apiTraceTXT.Send(apiTraceResponseString.c_str());
                }
                else if (bGPUTraceResponseNeeded)
                {
                    m_cmdGPUTrace.Send(gpuTraceResponseString.c_str());
                }
            }
        }

    }

    // When AutoCapture is enabled, we need to delay rendering so the user has time to retrieve the cached response.
    if (mbWaitingForAutocaptureClient)
    {
        // For AutoCapture the client will send the separate request below to collect the cached trace response.
        if (mCmdAutoCaptureCachedTrace.IsActive())
        {
            // We're done waiting to send the cached response to the client. Move on with playback.
            mbWaitingForAutocaptureClient = false;

            mCmdAutoCaptureCachedTrace.Send(mCachedTraceResponse.c_str());
            mCachedTraceResponse.clear();
        }
        else
        {
            // Sleep to give the user a chance to connect during playback.
            osSleep(500);
        }
    }

    if (mRetrieveCachedTraceResponse.IsActive())
    {
        const char* pathToTraceMetadata = mRetrieveCachedTraceResponse.GetValue();
        if (strlen(pathToTraceMetadata) > 0)
        {
            // Read the metadata file and store the contents in a structure.
            TraceMetadata traceMetadata;
            bool bReadMetadataFileSuccessfully = ReadTraceMetadataFile(pathToTraceMetadata, traceMetadata);
            if (bReadMetadataFileSuccessfully)
            {
                gtASCIIString traceContents;
                bool bReadTraceSuccessfully = LoadTraceFile(traceMetadata.mPathToTraceFile, traceContents);
                if (bReadTraceSuccessfully)
                {
                    // At this point the full trace response text should be loaded into our string and ready to be sent back to the client.
                    mRetrieveCachedTraceResponse.Send(traceContents.asCharArray());
                }
                else
                {
                    Log(logERROR, "Failed to read trace file at '%s'.", traceMetadata.mPathToTraceFile.c_str());
                }
            }
            else
            {
                Log(logERROR, "Failed to read metadata file at '%s'.", pathToTraceMetadata);
            }
        }
        else
        {
            Log(logERROR, "Failed to locate valid path to trace metadata file.");
        }
    }
}
コード例 #2
0
//--------------------------------------------------------------------------
/// EndFrame is used to signal the end of a rendered frame and to stop/send
/// the captured results that were logged during the frame render.
/// \return Nothing.
//--------------------------------------------------------------------------
void MultithreadedTraceAnalyzerLayer::EndFrame()
{
    // Check again which trace type is active at the end of the frame. Need to match how it was started.
    int autotraceFlags = GetTraceTypeFlags();

    // Will we be required to dump the trace response to a file on disk?
    bool bSaveResponseToFile = GetParentLayerManager()->mCmdFrameCaptureWithSave.IsActive() || mbLinkedTraceForCapture;

    // If the linked trace was requested, return all of the results through a single response.
    bool bLinkedTraceRequested = bSaveResponseToFile || mCmdLinkedTrace.IsActive() || (autotraceFlags == kTraceType_Linked);

    // If we want a linked trace, we'll need responses from all trace types.
    bool bAPITraceResponseNeeded = OnlyAPITraceRequested() || bLinkedTraceRequested || (autotraceFlags & kTraceType_API);
    bool bGPUTraceResponseNeeded = OnlyGPUTraceRequested() || bLinkedTraceRequested || (autotraceFlags & kTraceType_GPU);

    if (bAPITraceResponseNeeded || bGPUTraceResponseNeeded)
    {
        // We're done collecting, so turn off trace collection.
        SetCollectTrace(false);

        // Also disable frame profiling.
        ModernAPIFrameProfilerLayer* frameProfiler = GetParentLayerManager()->GetFrameProfilerLayer();
        frameProfiler->SetProfilingEnabled(false);

        AfterAPITrace();
        AfterGPUTrace();

        std::string apiTraceResponseString, gpuTraceResponseString;

        if (bAPITraceResponseNeeded)
        {
            mbCollectingApiTrace = false;
            apiTraceResponseString.assign(GetAPITraceTXT().c_str());
        }

        if (bGPUTraceResponseNeeded)
        {
            mbGPUTraceAlreadyCollected = false;
            gpuTraceResponseString.assign(GetGPUTraceTXT().c_str());
        }

        gtASCIIString fullResponseString;

        if (bAPITraceResponseNeeded)
        {
            fullResponseString += apiTraceResponseString.c_str();
            fullResponseString += "\n";
        }

        if (bGPUTraceResponseNeeded)
        {
            fullResponseString += gpuTraceResponseString.c_str();
            fullResponseString += "\n";
        }

        // If the autotrace flags are anything besides "None," we'll just store the trace log internally so the client can pick it up later.
        bool bShouldCacheForAutotrace = (autotraceFlags != kTraceType_None);

        if (bShouldCacheForAutotrace)
        {
            // Don't send the response back through a command yet.
            // The client will know to pick it up through a special AutoCapture command.
            mCachedTraceResponse.assign(fullResponseString.asCharArray());
            mbWaitingForAutocaptureClient = true;
        }
        else
        {
            // Send the response string back to the server through a specific request command.
            if (bLinkedTraceRequested)
            {
                HandleLinkedTraceResponse(fullResponseString, bSaveResponseToFile);

                // If tracing was active, disable it after handling the response.
                if (mbLinkedTraceForCapture)
                {
                    DisableLinkedTraceCollection();
                }
            }
            else
            {
                if (bAPITraceResponseNeeded)
                {
                    m_apiTraceTXT.Send(apiTraceResponseString.c_str());
                }
                else if (bGPUTraceResponseNeeded)
                {
                    m_cmdGPUTrace.Send(gpuTraceResponseString.c_str());
                }
            }
        }

    }

    // When AutoCapture is enabled, we need to delay rendering so the user has time to retrieve the cached response.
    if (mbWaitingForAutocaptureClient)
    {
        // For AutoCapture the client will send the separate request below to collect the cached trace response.
        if (mCmdAutoCaptureCachedTrace.IsActive())
        {
            // We're done waiting to send the cached response to the client. Move on with playback.
            mbWaitingForAutocaptureClient = false;

            mCmdAutoCaptureCachedTrace.Send(mCachedTraceResponse.c_str());
            mCachedTraceResponse.clear();
        }
        else
        {
            // Sleep to give the user a chance to connect during playback.
            osSleep(500);
        }
    }
}