Sfoglia il codice sorgente

Change screenshot APIs (#581)

* Change screenshot APIs

Signed-off-by: jiaweig <[email protected]>

* Typedef names

Signed-off-by: jiaweig <[email protected]>

---------

Signed-off-by: jiaweig <[email protected]>
jiaweig 2 anni fa
parent
commit
388cf34419

+ 2 - 2
Gem/Code/Source/Automation/PrecommitWizardSettings.h

@@ -69,13 +69,13 @@ namespace AtomSampleViewer
                     if (screenshotTestInfos[j].m_officialComparisonResult.m_resultCode == ScriptReporter::ImageComparisonResult::ResultCode::Pass)
                     {
                         m_reportsOrderedByThresholdToInspect.insert(AZStd::pair<float, ScriptReporter::ReportIndex>(
-                            screenshotTestInfos[j].m_officialComparisonResult.m_finalDiffScore,
+                            screenshotTestInfos[j].m_officialComparisonResult.m_diffScore,
                             ScriptReporter::ReportIndex{ i, j }));
                     }
                     else
                     {
                         m_failedReports.insert(AZStd::pair<float, ScriptReporter::ReportIndex>(
-                            screenshotTestInfos[j].m_officialComparisonResult.m_finalDiffScore,
+                            screenshotTestInfos[j].m_officialComparisonResult.m_diffScore,
                             ScriptReporter::ReportIndex{ i, j }));
                     }
                 }

+ 103 - 45
Gem/Code/Source/Automation/ScriptManager.cpp

@@ -690,7 +690,7 @@ namespace AtomSampleViewer
         ImGui::Text("Screenshot Name: %s", screenshotTest.m_officialBaselineScreenshotFilePath.c_str());
 
         ImGui::Separator();
-        ImGui::Text("Diff Score: %f", screenshotTest.m_officialComparisonResult.m_finalDiffScore);
+        ImGui::Text("Diff Score: %f", screenshotTest.m_officialComparisonResult.m_diffScore);
 
         // TODO: Render screenshots in ImGui.
         ImGui::Separator();
@@ -854,7 +854,7 @@ namespace AtomSampleViewer
             const ScriptReporter::ScreenshotTestInfo& screenshotTest = scriptReport.m_screenshotTests[reportIndex.second];
             ImGui::Text(
                 "\t%s %s '%s' %f", scriptReport.m_scriptAssetPath.c_str(), screenshotTest.m_screenshotFilePath.c_str(),
-                screenshotTest.m_toleranceLevel.m_name.c_str(), screenshotTest.m_officialComparisonResult.m_finalDiffScore);
+                screenshotTest.m_toleranceLevel.m_name.c_str(), screenshotTest.m_officialComparisonResult.m_diffScore);
         }
         // Present the information by printing highest differences first. See enum class ImageDifferenceLevel
         for (int i = aznumeric_cast<int>(imageDifferenceSummary.size() - 1); i >= 0; --i)
@@ -868,7 +868,7 @@ namespace AtomSampleViewer
                     const ScriptReporter::ScreenshotTestInfo& screenshotTest = scriptReport.m_screenshotTests[reportIndex.second];
                     ImGui::Text(
                         "\t%s %s '%s' %f", scriptReport.m_scriptAssetPath.c_str(), screenshotTest.m_screenshotFilePath.c_str(),
-                        screenshotTest.m_toleranceLevel.m_name.c_str(), screenshotTest.m_officialComparisonResult.m_finalDiffScore);
+                        screenshotTest.m_toleranceLevel.m_name.c_str(), screenshotTest.m_officialComparisonResult.m_diffScore);
                 }
             }
         }
@@ -1413,12 +1413,21 @@ namespace AtomSampleViewer
 
     bool ScriptManager::PrepareForScreenCapture(const AZStd::string& imageName)
     {
-        AZStd::string fullFilePath;
+        AZ::Render::FrameCapturePathOutcome pathOutcome;
+
         AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-            fullFilePath,
+            pathOutcome,
             &AZ::Render::FrameCaptureTestRequestBus::Events::BuildScreenshotFilePath,
             imageName, true);
 
+        if (!pathOutcome.IsSuccess())
+        {
+            ReportScriptError(pathOutcome.GetError().m_errorMessage);
+            return false;
+        }
+
+        AZStd::string fullFilePath = pathOutcome.IsSuccess() ? pathOutcome.GetValue() : "";
+
         // Delete the file if it already exists because if the screen capture fails, we don't want to do a screenshot comparison test using an old screenshot.
         if (AZ::IO::LocalFileIO::GetInstance()->Exists(fullFilePath.c_str()) && !AZ::IO::LocalFileIO::GetInstance()->Remove(fullFilePath.c_str()))
         {
@@ -1497,27 +1506,39 @@ namespace AtomSampleViewer
             // Note this will pause the script until the capture is complete
             if (PrepareForScreenCapture(imageName))
             {
-                AZStd::string screenshotFilePath;
+                AZ::Render::FrameCapturePathOutcome pathOutcome;
+
                 AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-                    screenshotFilePath,
+                    pathOutcome,
                     &AZ::Render::FrameCaptureTestRequestBus::Events::BuildScreenshotFilePath,
                     imageName, true);
 
-                AZ_Assert(s_instance->m_frameCaptureId == AZ::Render::InvalidFrameCaptureId, "Attempting to start a capture while one is in progress");
-                AZ::Render::FrameCaptureId frameCaptureId = AZ::Render::InvalidFrameCaptureId;
-                AZ::Render::FrameCaptureRequestBus::BroadcastResult(frameCaptureId, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshot, screenshotFilePath);
-                if (frameCaptureId != AZ::Render::InvalidFrameCaptureId)
+                if (!pathOutcome.IsSuccess())
                 {
-                    s_instance->AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(frameCaptureId);
-                    s_instance->m_frameCaptureId = frameCaptureId;
+                    ReportScriptError(pathOutcome.GetError().m_errorMessage);
+                    s_instance->m_isCapturePending = false;
+                    s_instance->m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
+                    s_instance->ResumeScript();
+                    return;
                 }
-                else
+
+                AZStd::string screenshotFilePath = pathOutcome.GetValue();
+
+                AZ_Assert(s_instance->m_frameCaptureId == AZ::Render::InvalidFrameCaptureId, "Attempting to start a capture while one is in progress");
+                
+                AZ::Render::FrameCaptureOutcome capOutcome;
+                AZ::Render::FrameCaptureRequestBus::BroadcastResult(capOutcome, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshot, screenshotFilePath);
+                if (!capOutcome.IsSuccess())
                 {
-                    AZ_Error("Automation", false, "Failed to initiate frame capture for '%s'", screenshotFilePath.c_str());
+                    ReportScriptError(AZStd::string::format("Failed to initiate frame capture for '%s'", screenshotFilePath.c_str()));
                     s_instance->m_isCapturePending = false;
                     s_instance->m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
                     s_instance->ResumeScript();
+                    return;
                 }
+
+                s_instance->m_frameCaptureId = capOutcome.GetValue();
+                s_instance->AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(s_instance->m_frameCaptureId);
             }
         };
 
@@ -1544,27 +1565,39 @@ namespace AtomSampleViewer
             // Note this will pause the script until the capture is complete
             if (PrepareForScreenCapture(imageName))
             {
-                AZStd::string screenshotFilePath;
+                AZ::Render::FrameCapturePathOutcome pathOutcome;
+
                 AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-                    screenshotFilePath,
+                    pathOutcome,
                     &AZ::Render::FrameCaptureTestRequestBus::Events::BuildScreenshotFilePath,
                     imageName, true);
 
-                AZ_Assert(s_instance->m_frameCaptureId == AZ::Render::InvalidFrameCaptureId, "Attempting to start a capture while one is in progress");
-                AZ::Render::FrameCaptureId frameCaptureId = AZ::Render::InvalidFrameCaptureId;
-                AZ::Render::FrameCaptureRequestBus::BroadcastResult(frameCaptureId, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshot, screenshotFilePath);
-                if (frameCaptureId != AZ::Render::InvalidFrameCaptureId)
+                if (!pathOutcome.IsSuccess())
                 {
-                    s_instance->AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(frameCaptureId);
-                    s_instance->m_frameCaptureId = frameCaptureId;
+                    ReportScriptError(pathOutcome.GetError().m_errorMessage);
+                    s_instance->m_isCapturePending = false;
+                    s_instance->m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
+                    s_instance->ResumeScript();
+                    return;
                 }
-                else
+
+                AZStd::string screenshotFilePath = pathOutcome.GetValue();
+
+                AZ_Assert(s_instance->m_frameCaptureId == AZ::Render::InvalidFrameCaptureId, "Attempting to start a capture while one is in progress");
+                
+                AZ::Render::FrameCaptureOutcome capOutcome;
+                AZ::Render::FrameCaptureRequestBus::BroadcastResult(capOutcome, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshot, screenshotFilePath);
+                if (!capOutcome.IsSuccess())
                 {
-                    AZ_Error("Automation", false, "Failed to initiate frame capture for '%s'", screenshotFilePath.c_str());
+                    ReportScriptError(AZStd::string::format("Failed to initiate frame capture for '%s'", screenshotFilePath.c_str()));
                     s_instance->m_isCapturePending = false;
                     s_instance->m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
                     s_instance->ResumeScript();
+                    return;
                 }
+
+                s_instance->m_frameCaptureId = capOutcome.GetValue();
+                s_instance->AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(s_instance->m_frameCaptureId);
             }
         };
 
@@ -1588,27 +1621,39 @@ namespace AtomSampleViewer
             // Note this will pause the script until the capture is complete
             if (PrepareForScreenCapture(imageName))
             {
-                AZStd::string screenshotFilePath;
+                AZ::Render::FrameCapturePathOutcome pathOutcome;
+
                 AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-                    screenshotFilePath,
+                    pathOutcome,
                     &AZ::Render::FrameCaptureTestRequestBus::Events::BuildScreenshotFilePath,
                     imageName, true);
 
-                AZ_Assert(s_instance->m_frameCaptureId == AZ::Render::InvalidFrameCaptureId, "Attempting to start a capture while one is in progress");
-                AZ::Render::FrameCaptureId frameCaptureId = AZ::Render::InvalidFrameCaptureId;
-                AZ::Render::FrameCaptureRequestBus::BroadcastResult(frameCaptureId, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshotWithPreview, screenshotFilePath);
-                if (frameCaptureId != AZ::Render::InvalidFrameCaptureId)
+                if (!pathOutcome.IsSuccess())
                 {
-                    s_instance->AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(frameCaptureId);
-                    s_instance->m_frameCaptureId = frameCaptureId;
+                    ReportScriptError(pathOutcome.GetError().m_errorMessage);
+                    s_instance->m_isCapturePending = false;
+                    s_instance->m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
+                    s_instance->ResumeScript();
+                    return;
                 }
-                else
+
+                AZStd::string screenshotFilePath = pathOutcome.GetValue();
+
+                AZ_Assert(s_instance->m_frameCaptureId == AZ::Render::InvalidFrameCaptureId, "Attempting to start a capture while one is in progress");
+                
+                AZ::Render::FrameCaptureOutcome capOutcome;
+                AZ::Render::FrameCaptureRequestBus::BroadcastResult(capOutcome, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshotWithPreview, screenshotFilePath);
+                if (!capOutcome.IsSuccess())
                 {
-                    AZ_Error("Automation", false, "Failed to initiate frame capture for '%s'", screenshotFilePath.c_str());
+                    ReportScriptError(AZStd::string::format("Failed to initiate frame capture for '%s'", screenshotFilePath.c_str()));
                     s_instance->m_isCapturePending = false;
                     s_instance->m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
                     s_instance->ResumeScript();
+                    return;
                 }
+
+                s_instance->m_frameCaptureId = capOutcome.GetValue();
+                s_instance->AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(s_instance->m_frameCaptureId);
             }
         };
 
@@ -1699,27 +1744,40 @@ namespace AtomSampleViewer
             // Note this will pause the script until the capture is complete
             if (PrepareForScreenCapture(imageName))
             {
-                AZStd::string screenshotFilePath;
+                AZ::Render::FrameCapturePathOutcome pathOutcome;
+
                 AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-                    screenshotFilePath,
+                    pathOutcome,
                     &AZ::Render::FrameCaptureTestRequestBus::Events::BuildScreenshotFilePath,
                     imageName, true);
 
-                AZ_Assert(s_instance->m_frameCaptureId == AZ::Render::InvalidFrameCaptureId, "Attempting to start a capture while one is in progress");
-                AZ::Render::FrameCaptureId frameCaptureId = AZ::Render::InvalidFrameCaptureId;
-                AZ::Render::FrameCaptureRequestBus::BroadcastResult(frameCaptureId, &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachment, passHierarchy, slot, screenshotFilePath, readbackOption);
-                if (frameCaptureId != AZ::Render::InvalidFrameCaptureId)
+                if (!pathOutcome.IsSuccess())
                 {
-                    s_instance->AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(frameCaptureId);
-                    s_instance->m_frameCaptureId = frameCaptureId;
+                    ReportScriptError(pathOutcome.GetError().m_errorMessage);
+                    s_instance->m_isCapturePending = false;
+                    s_instance->m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
+                    s_instance->ResumeScript();
+                    return;
                 }
-                else
+
+                AZStd::string screenshotFilePath = pathOutcome.GetValue();
+
+                AZ_Assert(s_instance->m_frameCaptureId == AZ::Render::InvalidFrameCaptureId, "Attempting to start a capture while one is in progress");
+
+                AZ::Render::FrameCaptureOutcome capOutcome;
+                AZ::Render::FrameCaptureRequestBus::BroadcastResult(capOutcome, &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachment, screenshotFilePath, passHierarchy, slot, readbackOption);
+                if (!capOutcome.IsSuccess())
                 {
-                    AZ_Error("Automation", false, "Failed to initiate frame capture for '%s'", screenshotFilePath.c_str());
+                    ReportScriptError(AZStd::string::format("Failed to initiate frame capture for '%s'", screenshotFilePath.c_str()));
                     s_instance->m_isCapturePending = false;
                     s_instance->m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
                     s_instance->ResumeScript();
+                    return;
                 }
+
+                s_instance->m_frameCaptureId = capOutcome.GetValue();
+                s_instance->AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(s_instance->m_frameCaptureId);
+
             }
         };
 

+ 71 - 40
Gem/Code/Source/Automation/ScriptReporter.cpp

@@ -35,7 +35,7 @@ namespace AtomSampleViewer
 
         if (m_resultCode == ResultCode::ThresholdExceeded || m_resultCode == ResultCode::Pass)
         {
-            resultString = AZStd::string::format("Diff Score: %f", m_finalDiffScore);
+            resultString = AZStd::string::format("Diff Score: %f", m_diffScore);
         }
         else if (m_resultCode == ResultCode::WrongSize)
         {
@@ -92,7 +92,7 @@ namespace AtomSampleViewer
         m_invalidationMessage = message;
 
         // Reporting this message here instead of when running the script so it won't show up as an error in the ImGui report.
-        AZ_Error("Automation", m_invalidationMessage.empty(), "Subsequent test results will be invalid because '%s'", m_invalidationMessage.c_str());
+        AZ_Error("ScriptReporter", m_invalidationMessage.empty(), "Subsequent test results will be invalid because '%s'", m_invalidationMessage.c_str());
     }
 
     void ScriptReporter::PushScript(const AZStd::string& scriptAssetPath)
@@ -134,20 +134,49 @@ namespace AtomSampleViewer
     {   
         AZ_Assert(!screenshotName.empty(), "The screenshot file name shouldn't be empty.");
 
+        AZ::Render::FrameCapturePathOutcome pathOutcome;
+
         AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-            m_screenshotFilePath,
+            pathOutcome,
             &AZ::Render::FrameCaptureTestRequestBus::Events::BuildScreenshotFilePath,
             screenshotName, true);
 
+        if (pathOutcome.IsSuccess())
+        {
+            m_screenshotFilePath = pathOutcome.GetValue();
+        }
+        else
+        {
+            AZ_Error("ScriptReporter", false, "%s", pathOutcome.GetError().m_errorMessage.c_str());
+        }
+
         AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-            m_officialBaselineScreenshotFilePath,
+            pathOutcome,
             &AZ::Render::FrameCaptureTestRequestBus::Events::BuildOfficialBaselineFilePath,
             screenshotName, false);
 
+        if (pathOutcome.IsSuccess())
+        {
+            m_officialBaselineScreenshotFilePath = pathOutcome.GetValue();
+        }
+        else
+        {
+            AZ_Error("ScriptReporter", false, "%s", pathOutcome.GetError().m_errorMessage.c_str());
+        }
+
         AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-            m_localBaselineScreenshotFilePath,
+            pathOutcome,
             &AZ::Render::FrameCaptureTestRequestBus::Events::BuildLocalBaselineFilePath,
             screenshotName, true);
+
+        if (pathOutcome.IsSuccess())
+        {
+            m_localBaselineScreenshotFilePath = pathOutcome.GetValue();
+        }
+        else
+        {
+            AZ_Error("ScriptReporter", false, "%s", pathOutcome.GetError().m_errorMessage.c_str());
+        }
     }
 
     bool ScriptReporter::AddScreenshotTest(const AZStd::string& imageName)
@@ -515,11 +544,11 @@ namespace AtomSampleViewer
                         float diffScore = 0.0f;
                         if (m_currentSortOption == SortOption::OfficialBaselineDiffScore)
                         {
-                            diffScore = screenshotResult.m_officialComparisonResult.m_standardDiffScore;
+                            diffScore = screenshotResult.m_officialComparisonResult.m_diffScore;
                         }
                         else if (m_currentSortOption == SortOption::LocalBaselineDiffScore)
                         {
-                            diffScore = screenshotResult.m_localComparisonResult.m_standardDiffScore;
+                            diffScore = screenshotResult.m_localComparisonResult.m_diffScore;
                         }
 
                         const bool screenshotPassed = screenshotResult.m_officialComparisonResult.m_resultCode == ImageComparisonResult::ResultCode::Pass;
@@ -595,7 +624,7 @@ namespace AtomSampleViewer
                     ImGui::Text("Used Tolerance: %s", screenshotResult.m_toleranceLevel.ToString().c_str());
 
                     const ImageComparisonToleranceLevel* suggestedTolerance = ScriptReporter::FindBestToleranceLevel(
-                        screenshotResult.m_officialComparisonResult.m_finalDiffScore,
+                        screenshotResult.m_officialComparisonResult.m_diffScore,
                         screenshotResult.m_toleranceLevel.m_filterImperceptibleDiffs);
 
                     if (suggestedTolerance)
@@ -607,10 +636,10 @@ namespace AtomSampleViewer
                     {
                         // This gives an idea of what the tolerance level would be if the imperceptible diffs were not filtered out.
                         const ImageComparisonToleranceLevel* unfilteredTolerance =
-                            ScriptReporter::FindBestToleranceLevel(screenshotResult.m_officialComparisonResult.m_standardDiffScore, false);
+                            ScriptReporter::FindBestToleranceLevel(screenshotResult.m_officialComparisonResult.m_diffScore, false);
 
                         ImGui::Text(
-                            "(Unfiltered Diff Score: %f%s)", screenshotResult.m_officialComparisonResult.m_standardDiffScore,
+                            "(Unfiltered Diff Score: %f%s)", screenshotResult.m_officialComparisonResult.m_diffScore,
                             unfilteredTolerance ? AZStd::string::format(" ~ '%s'", unfilteredTolerance->m_name.c_str()).c_str() : "");
                     }
                 }
@@ -801,11 +830,11 @@ namespace AtomSampleViewer
             for (size_t j = 0; j < screenshotTestInfos.size(); ++j)
             {
                 m_reportsSortedByOfficialBaslineScore.insert(AZStd::pair<float, ReportIndex>(
-                    screenshotTestInfos[j].m_officialComparisonResult.m_standardDiffScore,
+                    screenshotTestInfos[j].m_officialComparisonResult.m_diffScore,
                     ReportIndex{ i, j }));
 
                 m_reportsSortedByLocaBaslineScore.insert(AZStd::pair<float, ReportIndex>(
-                    screenshotTestInfos[j].m_localComparisonResult.m_standardDiffScore,
+                    screenshotTestInfos[j].m_localComparisonResult.m_diffScore,
                     ReportIndex{ i, j }));
             }
         }
@@ -813,12 +842,12 @@ namespace AtomSampleViewer
 
     void ScriptReporter::ReportScriptError([[maybe_unused]] const AZStd::string& message)
     {
-        AZ_Error("Automation", false, "Script: %s", message.c_str());
+        AZ_Error("ScriptReporter", false, "Script: %s", message.c_str());
     }
 
     void ScriptReporter::ReportScriptWarning([[maybe_unused]] const AZStd::string& message)
     {
-        AZ_Warning("Automation", false, "Script: %s", message.c_str());
+        AZ_Warning("ScriptReporter", false, "Script: %s", message.c_str());
     }
 
     void ScriptReporter::ReportScriptIssue(const AZStd::string& message, TraceLevel traceLevel)
@@ -919,7 +948,7 @@ namespace AtomSampleViewer
 
             if (!io->Exists(m_officialBaselineSourceFolder.c_str()))
             {
-                AZ_Error("Automation", false, "Could not find source folder '%s'. Copying to source baseline can only be used on dev platforms.", m_officialBaselineSourceFolder.c_str());
+                AZ_Error("ScriptReporter", false, "Could not find source folder '%s'. Copying to source baseline can only be used on dev platforms.", m_officialBaselineSourceFolder.c_str());
                 m_officialBaselineSourceFolder.clear();
                 success = false;
             }
@@ -981,9 +1010,7 @@ namespace AtomSampleViewer
     void ScriptReporter::ClearImageComparisonResult(ImageComparisonResult& comparisonResult)
     {
         comparisonResult.m_resultCode = ImageComparisonResult::ResultCode::Pass;
-        comparisonResult.m_standardDiffScore = 0.0f;
-        comparisonResult.m_filteredDiffScore = 0.0f;
-        comparisonResult.m_finalDiffScore = 0.0f;
+        comparisonResult.m_diffScore = 0.0f;
     }
 
     void ScriptReporter::ShowUpdateLocalBaselineResult(int successCount, int failureCount)
@@ -995,11 +1022,16 @@ namespace AtomSampleViewer
         }
         else
         {
-            AZStd::string localBaselineFolder;
+            AZ::Render::FrameCapturePathOutcome pathOutcome;
+
             AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-                localBaselineFolder,
+                pathOutcome,
                 &AZ::Render::FrameCaptureTestRequestBus::Events::BuildScreenshotFilePath,
                 "", true);
+
+            AZ_Error("ScriptReporter", pathOutcome.IsSuccess(), "%s", pathOutcome.GetError().m_errorMessage.c_str());
+
+            AZStd::string localBaselineFolder = pathOutcome.IsSuccess() ? pathOutcome.GetValue() : "";
             message = "Destination: " + localBaselineFolder + "\n";
 
             if (successCount > 0)
@@ -1046,26 +1078,24 @@ namespace AtomSampleViewer
         }
         else
         {
-            AZ::Utils::ImageDiffResult result;
+            AZ::Render::FrameCaptureComparisonOutcome compOutcome;
             AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-                result,
+                compOutcome,
                 &AZ::Render::FrameCaptureTestRequestBus::Events::CompareScreenshots,
                 screenshotTestInfo.m_screenshotFilePath,
                 screenshotTestInfo.m_officialBaselineScreenshotFilePath,
                 ImperceptibleDiffFilter
             );
-            screenshotTestInfo.m_officialComparisonResult.m_standardDiffScore = result.m_diffScore;
-            screenshotTestInfo.m_officialComparisonResult.m_filteredDiffScore = result.m_filteredDiffScore;
-            // Set the final score to the standard score just in case the filtered one is ignored
-            screenshotTestInfo.m_officialComparisonResult.m_finalDiffScore = screenshotTestInfo.m_officialComparisonResult.m_standardDiffScore;
 
-            if (result.m_resultCode == AZ::Utils::ImageDiffResultCode::Success)
+            screenshotTestInfo.m_officialComparisonResult.m_diffScore = 0.0;
+
+            if (compOutcome.IsSuccess())
             {
-                screenshotTestInfo.m_officialComparisonResult.m_finalDiffScore = toleranceLevel->m_filterImperceptibleDiffs ?
-                    screenshotTestInfo.m_officialComparisonResult.m_filteredDiffScore :
-                    screenshotTestInfo.m_officialComparisonResult.m_standardDiffScore;
+                screenshotTestInfo.m_officialComparisonResult.m_diffScore = toleranceLevel->m_filterImperceptibleDiffs
+                    ? compOutcome.GetValue().m_diffScore
+                    : compOutcome.GetValue().m_filteredDiffScore;
 
-                if (screenshotTestInfo.m_officialComparisonResult.m_finalDiffScore <= toleranceLevel->m_threshold)
+                if (screenshotTestInfo.m_officialComparisonResult.m_diffScore <= toleranceLevel->m_threshold)
                 {
                     screenshotTestInfo.m_officialComparisonResult.m_resultCode = ImageComparisonResult::ResultCode::Pass;
                 }
@@ -1075,7 +1105,7 @@ namespace AtomSampleViewer
                     // If you change this message, be sure to update the associated tests as well located here: "C:/path/to/Lumberyard/AtomSampleViewer/Standalone/PythonTests"
                     ReportScreenshotComparisonIssue(
                         AZStd::string::format("Screenshot check failed. Diff score %f exceeds threshold of %f ('%s').",
-                            screenshotTestInfo.m_officialComparisonResult.m_finalDiffScore, toleranceLevel->m_threshold, toleranceLevel->m_name.c_str()),
+                            screenshotTestInfo.m_officialComparisonResult.m_diffScore, toleranceLevel->m_threshold, toleranceLevel->m_name.c_str()),
                         screenshotTestInfo.m_officialBaselineScreenshotFilePath,
                         screenshotTestInfo.m_screenshotFilePath,
                         TraceLevel::Error);
@@ -1094,28 +1124,29 @@ namespace AtomSampleViewer
         {
             // Local screenshots should be expected match 100% every time, otherwise warnings are reported. This will help developers track and investigate changes,
             // for example if they make local changes that impact some unrelated AtomSampleViewer sample in an unexpected way, they will see a warning about this.
-            AZ::Utils::ImageDiffResult result;
+            AZ::Render::FrameCaptureComparisonOutcome compOutcome;
             AZ::Render::FrameCaptureTestRequestBus::BroadcastResult(
-                result,
+                compOutcome,
                 &AZ::Render::FrameCaptureTestRequestBus::Events::CompareScreenshots,
                 screenshotTestInfo.m_screenshotFilePath,
                 screenshotTestInfo.m_localBaselineScreenshotFilePath,
                 ImperceptibleDiffFilter
             );
-            screenshotTestInfo.m_localComparisonResult.m_standardDiffScore = result.m_diffScore;
-            screenshotTestInfo.m_localComparisonResult.m_filteredDiffScore = result.m_filteredDiffScore;
-            screenshotTestInfo.m_localComparisonResult.m_finalDiffScore = screenshotTestInfo.m_localComparisonResult.m_standardDiffScore;
 
-            if (result.m_resultCode == AZ::Utils::ImageDiffResultCode::Success)
+            screenshotTestInfo.m_localComparisonResult.m_diffScore = 0.0f;
+
+            if (compOutcome.IsSuccess())
             {
-                if(screenshotTestInfo.m_localComparisonResult.m_standardDiffScore == 0.0f)
+                screenshotTestInfo.m_localComparisonResult.m_diffScore = compOutcome.GetValue().m_diffScore;
+
+                if (screenshotTestInfo.m_localComparisonResult.m_diffScore == 0.0f)
                 {
                     screenshotTestInfo.m_localComparisonResult.m_resultCode = ImageComparisonResult::ResultCode::Pass;
                 }
                 else
                 {
                     ReportScreenshotComparisonIssue(
-                        AZStd::string::format("Screenshot check failed. Screenshot does not match the local baseline; something has changed. Diff score is %f.", screenshotTestInfo.m_localComparisonResult.m_standardDiffScore),
+                        AZStd::string::format("Screenshot check failed. Screenshot does not match the local baseline; something has changed. Diff score is %f.", screenshotTestInfo.m_localComparisonResult.m_diffScore),
                         screenshotTestInfo.m_localBaselineScreenshotFilePath,
                         screenshotTestInfo.m_screenshotFilePath,
                         TraceLevel::Warning);

+ 5 - 3
Gem/Code/Source/Automation/ScriptReporter.h

@@ -104,9 +104,11 @@ namespace AtomSampleViewer
             };
 
             ResultCode m_resultCode = ResultCode::None;
-            float m_standardDiffScore = 0.0f;
-            float m_filteredDiffScore = 0.0f; //!< The diff score after filtering out visually imperceptible differences.
-            float m_finalDiffScore = 0.0f; //! The diff score that was used for comparison. May be m_diffScore or m_filteredDiffScore.
+            //! The diff score that was used for comparison..
+            //! The diff score can be before or after filtering out visually imperceptible differences,
+            //! depending on the tolerance level settings.
+            //! See CalcImageDiffRms.
+            float m_diffScore = 0.0f;
 
             AZStd::string GetSummaryString() const;
         };

+ 9 - 2
Gem/Code/Source/SampleComponentManager.cpp

@@ -670,13 +670,20 @@ namespace AtomSampleViewer
             }
             else if (m_countdownForFrameCapture == 0)
             {
-                AZ::Render::FrameCaptureRequestBus::BroadcastResult(m_frameCaptureId, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshot, m_frameCaptureFilePath);
-                if (m_frameCaptureId != AZ::Render::InvalidFrameCaptureId ) // if unsuccessfull leave state to attempt again next tick
+                AZ::Render::FrameCaptureOutcome capOutcome;
+                AZ::Render::FrameCaptureRequestBus::BroadcastResult(capOutcome, &AZ::Render::FrameCaptureRequestBus::Events::CaptureScreenshot, m_frameCaptureFilePath);
+                if (capOutcome.IsSuccess()) // if unsuccessfull leave state to attempt again next tick
                 {
+                    m_frameCaptureId = capOutcome.GetValue();
+
                     AZ::Render::FrameCaptureNotificationBus::Handler::BusConnect(m_frameCaptureId);
 
                     m_countdownForFrameCapture = -1; // Don't call CaptureScreenshot again
                 }
+                else
+                {
+                    m_frameCaptureId = AZ::Render::InvalidFrameCaptureId;
+                }
             }
         }
     }

+ 10 - 5
Gem/Code/Source/ShaderReloadTestComponent.cpp

@@ -307,12 +307,17 @@ namespace AtomSampleViewer
         };
 
         m_capturedColorAsString.clear();
-        bool startedCapture = false;
+
+        AZ::Render::FrameCaptureOutcome capOutcome;
         AZ::Render::FrameCaptureRequestBus::BroadcastResult(
-            startedCapture, &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachmentWithCallback, m_passHierarchy,
-            AZStd::string("Output"), captureCallback, AZ::RPI::PassAttachmentReadbackOption::Output);
-        AZ_Error(LogName, startedCapture, "Failed to start CapturePassAttachmentWithCallback");
-        return startedCapture;
+            capOutcome,
+            &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachmentWithCallback,
+            captureCallback,
+            m_passHierarchy,
+            AZStd::string("Output"),
+            AZ::RPI::PassAttachmentReadbackOption::Output);
+        AZ_Error(LogName, capOutcome.IsSuccess(), "%s", capOutcome.GetError().m_errorMessage.c_str());
+        return capOutcome.IsSuccess();
     }
 
     uint32_t ShaderReloadTestComponent::ReadPixel(const uint8_t* rawRGBAPixelData, const AZ::RHI::ImageDescriptor& imageDescriptor, uint32_t x, uint32_t y) const

+ 5 - 1
Gem/Code/Source/TonemappingExampleComponent.cpp

@@ -315,7 +315,11 @@ namespace AtomSampleViewer
     {
         AZStd::string filePath = m_imguiFrameCaptureSaver.GetSaveFilePath();
         AZStd::string slot = "Output";
-        AZ::Render::FrameCaptureRequestBus::Broadcast(&AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachment, m_capturePassHierarchy, slot, filePath,
+        AZ::Render::FrameCaptureRequestBus::Broadcast(
+            &AZ::Render::FrameCaptureRequestBus::Events::CapturePassAttachment,
+            filePath,
+            m_capturePassHierarchy,
+            slot,
             AZ::RPI::PassAttachmentReadbackOption::Output);
     }