preview window flipped
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m3s
CI / Windows Release Package (push) Has been skipped

This commit is contained in:
2026-05-20 15:03:02 +10:00
parent 7e17315e74
commit f589b1e1fe
2 changed files with 74 additions and 27 deletions

View File

@@ -4,6 +4,7 @@
#include "../logging/Logger.h" #include "../logging/Logger.h"
#include <algorithm> #include <algorithm>
#include <cstring>
namespace RenderCadenceCompositor namespace RenderCadenceCompositor
{ {
@@ -209,6 +210,8 @@ void PreviewWindowThread::Paint(HWND window)
frame.width > 0 && frame.width > 0 &&
frame.height > 0; frame.height > 0;
if (canPaintFrame) if (canPaintFrame)
{
if (CopyPreviewOrientedBgra8Frame(frame))
{ {
const int previousStretchMode = SetStretchBltMode(dc, HALFTONE); const int previousStretchMode = SetStretchBltMode(dc, HALFTONE);
POINT previousBrushOrigin = {}; POINT previousBrushOrigin = {};
@@ -232,7 +235,7 @@ void PreviewWindowThread::Paint(HWND window)
0, 0,
static_cast<int>(frame.width), static_cast<int>(frame.width),
static_cast<int>(frame.height), static_cast<int>(frame.height),
frame.bytes, mPaintPixels.data(),
&bitmapInfo, &bitmapInfo,
DIB_RGB_COLORS, DIB_RGB_COLORS,
SRCCOPY); SRCCOPY);
@@ -242,6 +245,16 @@ void PreviewWindowThread::Paint(HWND window)
SetBrushOrgEx(dc, previousBrushOrigin.x, previousBrushOrigin.y, nullptr); SetBrushOrgEx(dc, previousBrushOrigin.x, previousBrushOrigin.y, nullptr);
} }
else else
{
if (!mLoggedPaintCopyFailure)
{
TryLog(LogLevel::Warning, "preview", "Preview frame could not be copied for mirrored presentation.");
mLoggedPaintCopyFailure = true;
}
FillRect(dc, &client, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
}
}
else
{ {
FillRect(dc, &client, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH))); FillRect(dc, &client, reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
} }
@@ -251,4 +264,34 @@ void PreviewWindowThread::Paint(HWND window)
EndPaint(window, &paint); EndPaint(window, &paint);
} }
bool PreviewWindowThread::CopyPreviewOrientedBgra8Frame(const SystemFrame& frame)
{
constexpr std::size_t kBgraBytesPerPixel = 4;
if (frame.bytes == nullptr || frame.width == 0 || frame.height == 0 || frame.rowBytes <= 0)
return false;
const std::size_t width = static_cast<std::size_t>(frame.width);
const std::size_t height = static_cast<std::size_t>(frame.height);
const std::size_t sourceRowBytes = static_cast<std::size_t>(frame.rowBytes);
const std::size_t destinationRowBytes = width * kBgraBytesPerPixel;
if (sourceRowBytes < destinationRowBytes)
return false;
mPaintPixels.resize(destinationRowBytes * height);
const unsigned char* sourceBytes = static_cast<const unsigned char*>(frame.bytes);
for (std::size_t y = 0; y < height; ++y)
{
const unsigned char* sourceRow = sourceBytes + (height - 1u - y) * sourceRowBytes;
unsigned char* destinationRow = mPaintPixels.data() + y * destinationRowBytes;
for (std::size_t x = 0; x < width; ++x)
{
const unsigned char* sourcePixel = sourceRow + x * kBgraBytesPerPixel;
unsigned char* destinationPixel = destinationRow + x * kBgraBytesPerPixel;
std::memcpy(destinationPixel, sourcePixel, kBgraBytesPerPixel);
}
}
return true;
}
} }

View File

@@ -6,6 +6,7 @@
#include <atomic> #include <atomic>
#include <thread> #include <thread>
#include <vector>
#ifndef NOMINMAX #ifndef NOMINMAX
#define NOMINMAX #define NOMINMAX
@@ -35,9 +36,12 @@ private:
void ThreadMain(); void ThreadMain();
bool CreatePreviewWindow(std::string& error); bool CreatePreviewWindow(std::string& error);
void Paint(HWND window); void Paint(HWND window);
bool CopyPreviewOrientedBgra8Frame(const SystemFrame& frame);
SystemFrameExchange* mExchange = nullptr; SystemFrameExchange* mExchange = nullptr;
PreviewWindowConfig mConfig; PreviewWindowConfig mConfig;
std::vector<unsigned char> mPaintPixels;
bool mLoggedPaintCopyFailure = false;
std::thread mThread; std::thread mThread;
std::atomic<bool> mStopRequested{ false }; std::atomic<bool> mStopRequested{ false };
std::atomic<bool> mRunning{ false }; std::atomic<bool> mRunning{ false };