diff --git a/headless/Compare.cpp b/headless/Compare.cpp index 2031b1ed07..c139aae781 100644 --- a/headless/Compare.cpp +++ b/headless/Compare.cpp @@ -365,11 +365,9 @@ std::vector TranslateDebugBufferToCompare(const GPUDebugBuffer *buffer, u32 return data; } -double CompareScreenshot(const std::vector &pixels, u32 stride, u32 w, u32 h, const Path& screenshotFilename, std::string &error) -{ - if (pixels.size() < stride * h) - { - error = "Buffer format conversion error"; +double ScreenshotComparer::Compare(const Path &screenshotFilename) { + if (pixels_.size() < stride_ * h_) { + error_ = "Buffer format conversion error"; return -1.0f; } @@ -381,16 +379,16 @@ double CompareScreenshot(const std::vector &pixels, u32 stride, u32 w, u32 if (loader->Exists()) { uint8_t header[2]; if (loader->ReadAt(0, 2, header) != 2) { - error = "Unable to read screenshot data: " + screenshotFilename.ToVisualString(); + error_ = "Unable to read screenshot data: " + screenshotFilename.ToVisualString(); return -1.0f; } if (header[0] == 'B' && header[1] == 'M') { - reference = (u32 *)calloc(stride * h, sizeof(u32)); + reference = (u32 *)calloc(stride_ * h_, sizeof(u32)); asBitmap = true; // The bitmap header is 14 + 40 bytes. We could validate it but the test would fail either way. - if (reference && loader->ReadAt(14 + 40, sizeof(u32), stride * h, reference) != stride * h) { - error = "Unable to read screenshot data: " + screenshotFilename.ToVisualString(); + if (reference && loader->ReadAt(14 + 40, sizeof(u32), stride_ * h_, reference) != stride_ * h_) { + error_ = "Unable to read screenshot data: " + screenshotFilename.ToVisualString(); return -1.0f; } } else { @@ -398,45 +396,45 @@ double CompareScreenshot(const std::vector &pixels, u32 stride, u32 w, u32 std::vector compressed; compressed.resize(loader->FileSize()); if (loader->ReadAt(0, compressed.size(), &compressed[0]) != compressed.size()) { - error = "Unable to read screenshot data: " + screenshotFilename.ToVisualString(); + error_ = "Unable to read screenshot data: " + screenshotFilename.ToVisualString(); return -1.0f; } int width, height; if (!pngLoadPtr(&compressed[0], compressed.size(), &width, &height, (unsigned char **)&reference)) { - error = "Unable to read screenshot data: " + screenshotFilename.ToVisualString(); + error_ = "Unable to read screenshot data: " + screenshotFilename.ToVisualString(); return -1.0f; } } } else { - error = "Unable to read screenshot: " + screenshotFilename.ToVisualString(); + error_ = "Unable to read screenshot: " + screenshotFilename.ToVisualString(); return -1.0f; } if (!reference) { - error = "Unable to allocate screenshot data: " + screenshotFilename.ToVisualString(); + error_ = "Unable to allocate screenshot data: " + screenshotFilename.ToVisualString(); return -1.0f; } u32 errors = 0; if (asBitmap) { // The reference is flipped and BGRA by default for the common BMP compare case. - for (u32 y = 0; y < h; ++y) { - u32 yoff = y * stride; - for (u32 x = 0; x < w; ++x) - errors += ComparePixel(pixels[y * stride + x], reference[yoff + x]); + for (u32 y = 0; y < h_; ++y) { + u32 yoff = y * stride_; + for (u32 x = 0; x < w_; ++x) + errors += ComparePixel(pixels_[y * stride_ + x], reference[yoff + x]); } } else { // Just convert to BGRA for simplicity. - ConvertRGBA8888ToBGRA8888(reference, reference, h * stride); - for (u32 y = 0; y < h; ++y) { - u32 yoff = (h - y - 1) * stride; - for (u32 x = 0; x < w; ++x) - errors += ComparePixel(pixels[y * stride + x], reference[yoff + x]); + ConvertRGBA8888ToBGRA8888(reference, reference, h_ * stride_); + for (u32 y = 0; y < h_; ++y) { + u32 yoff = (h_ - y - 1) * stride_; + for (u32 x = 0; x < w_; ++x) + errors += ComparePixel(pixels_[y * stride_ + x], reference[yoff + x]); } } free(reference); - return (double) errors / (double) (w * h); + return (double) errors / (double) (w_ * h_); } diff --git a/headless/Compare.h b/headless/Compare.h index f1f30f5375..0eb0960b35 100644 --- a/headless/Compare.h +++ b/headless/Compare.h @@ -34,4 +34,23 @@ std::string GetTestName(const Path &bootFilename); bool CompareOutput(const Path &bootFilename, const std::string &output, bool verbose); std::vector TranslateDebugBufferToCompare(const GPUDebugBuffer *buffer, u32 stride, u32 h); -double CompareScreenshot(const std::vector &pixels, u32 stride, u32 w, u32 h, const Path &screenshotFilename, std::string &error); + +class ScreenshotComparer { +public: + ScreenshotComparer(const std::vector &pixels, u32 stride, u32 w, u32 h) + : pixels_(pixels), stride_(stride), w_(w), h_(h) { + } + + double Compare(const Path &screenshotFilename); + + std::string GetError() { + return error_; + } + +protected: + const std::vector &pixels_; + std::string error_; + u32 stride_; + u32 w_; + u32 h_; +}; diff --git a/headless/StubHost.cpp b/headless/StubHost.cpp index e2331d1e48..c7122629ce 100644 --- a/headless/StubHost.cpp +++ b/headless/StubHost.cpp @@ -48,10 +48,10 @@ void HeadlessHost::SendDebugScreenshot(const u8 *pixbuf, u32 w, u32 h) { gpuDebug->GetCurrentFramebuffer(buffer, GPU_DBG_FRAMEBUF_RENDER); const std::vector pixels = TranslateDebugBufferToCompare(&buffer, 512, 272); - std::string error; - double errors = CompareScreenshot(pixels, FRAME_STRIDE, FRAME_WIDTH, FRAME_HEIGHT, comparisonScreenshot_, error); + ScreenshotComparer comparer(pixels, FRAME_STRIDE, FRAME_WIDTH, FRAME_HEIGHT); + double errors = comparer.Compare(comparisonScreenshot_); if (errors < 0) - SendOrCollectDebugOutput(error + "\n"); + SendOrCollectDebugOutput(comparer.GetError() + "\n"); if (errors > 0) {