//-------------------------------------------------------------------------- /// 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."); } } }
//-------------------------------------------------------------------------- /// 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); } } }