Add hardware rendering option in UI

This commit is contained in:
2025-09-23 03:39:44 +09:00
parent 7fa3ab2442
commit 097dfa2282
7 changed files with 101 additions and 30 deletions

View File

@@ -326,6 +326,41 @@ std::string status = "Ready";
- **사용하지 않는 컨트롤**: 주석 처리보다는 완전 제거 권장
- **이벤트 핸들러**: XAML에서 제거된 컨트롤의 이벤트 핸들러는 .h/.cpp에서도 제거
#### XAML 주석 작성 가이드라인
**목적**: 코드 가독성과 유지보수성을 위한 XAML 주석 작성 규칙
**주석 작성 원칙**:
- 모든 주요 UI 섹션에 영어 주석으로 목적 설명
- 복잡한 레이아웃이나 데이터 바인딩에는 상세 주석 추가
- 조건부 표시/숨김 로직이 있는 컨트롤에는 설명 추가
**권장 주석 패턴**:
```xml
<!-- Main video rendering area -->
<Border x:Name="VideoContainer">
<!-- Hardware D3D12 rendering (Phase 1) -->
<SwapChainPanel x:Name="VideoSwapChainPanel" Visibility="Collapsed"/>
<!-- Software CPU rendering (fallback) -->
<Image x:Name="VideoImage" Stretch="Fill"/>
</Border>
<!-- Control panel -->
<StackPanel Orientation="Horizontal">
<!-- Video playback controls -->
<Button Content="Play" Click="PlayButton_Click"/>
<!-- Rendering mode selection -->
<CheckBox Content="Hardware Rendering" IsChecked="True"/>
</StackPanel>
```
**주석이 필요한 경우**:
- UI 레이아웃의 주요 섹션 (상단 바, 메인 콘텐츠, 하단 상태바 등)
- 동적으로 변경되는 Visibility나 IsEnabled 속성을 가진 컨트롤
- 복잡한 Grid 구조나 중첩된 StackPanel
- 특별한 목적을 가진 Border나 Canvas 컨트롤
### 라이브러리 링크 설정
```xml
<!-- 추가 포함 디렉터리 -->

View File

@@ -15,7 +15,7 @@
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- 컨트롤 패널 -->
<!-- Control panel -->
<Border Grid.Row="0" Background="LightGray" Padding="10">
<StackPanel Orientation="Horizontal" Spacing="10">
<Button x:Name="LoadVideoButton"
@@ -43,6 +43,14 @@
<ComboBoxItem Content="3x3 Grid"/>
</ComboBox>
<CheckBox x:Name="UseHardwareRenderingCheckBox"
Content="Hardware Rendering"
IsChecked="True"
VerticalAlignment="Center"
Margin="10,0,0,0"
Checked="UseHardwareRenderingCheckBox_Checked"
Unchecked="UseHardwareRenderingCheckBox_Unchecked"/>
<TextBlock x:Name="StatusDisplay"
Text="Ready"
VerticalAlignment="Center"
@@ -50,10 +58,10 @@
</StackPanel>
</Border>
<!-- 비디오 플레이어 그리드 -->
<!-- Video player grid -->
<ScrollViewer Grid.Row="1" ZoomMode="Enabled" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid x:Name="VideoGrid" Background="Black">
<!-- 동적으로 VideoPlayerControl들이 추가됨 -->
<!-- VideoPlayerControls are added dynamically -->
</Grid>
</ScrollViewer>
</Grid>

View File

@@ -13,7 +13,12 @@ namespace winrt::Vav2Player::implementation
MultiVideoTestWindow::MultiVideoTestWindow()
{
InitializeComponent();
CreateVideoGrid(LayoutType::Single);
// Defer CreateVideoGrid until UI is fully loaded using DispatcherQueue
auto dispatcherQueue = winrt::Microsoft::UI::Dispatching::DispatcherQueue::GetForCurrentThread();
dispatcherQueue.TryEnqueue([this]() {
CreateVideoGrid(LayoutType::Single);
});
}
winrt::Windows::Foundation::IAsyncAction MultiVideoTestWindow::LoadVideoButton_Click(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
@@ -271,9 +276,36 @@ namespace winrt::Vav2Player::implementation
}
}
void MultiVideoTestWindow::UseHardwareRenderingCheckBox_Checked(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
// Apply hardware rendering to all video players
for (auto& player : m_videoPlayers)
{
player.UseHardwareRendering(true);
}
UpdateStatus(L"Hardware Rendering enabled for all players");
}
void MultiVideoTestWindow::UseHardwareRenderingCheckBox_Unchecked(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)
{
// Apply software rendering to all video players
for (auto& player : m_videoPlayers)
{
player.UseHardwareRendering(false);
}
UpdateStatus(L"Software Rendering enabled for all players");
}
void MultiVideoTestWindow::UpdateStatus(winrt::hstring const& message)
{
StatusDisplay().Text(message);
// Safety check: only update if StatusDisplay is available
try {
if (StatusDisplay()) {
StatusDisplay().Text(message);
}
} catch (...) {
// Ignore if UI not ready yet
}
OutputDebugStringA((winrt::to_string(message) + "\n").c_str());
}
}

View File

@@ -17,6 +17,8 @@ namespace winrt::Vav2Player::implementation
void PauseAllButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
void StopAllButton_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
void LayoutComboBox_SelectionChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::Controls::SelectionChangedEventArgs const& e);
void UseHardwareRenderingCheckBox_Checked(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
void UseHardwareRenderingCheckBox_Unchecked(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
private:
std::vector<winrt::Vav2Player::VideoPlayerControl> m_videoPlayers;

View File

@@ -17,7 +17,7 @@
BorderBrush="Gray"
BorderThickness="1">
<Grid x:Name="VideoDisplayArea">
<Grid x:Name="VideoDisplayArea" Background="Black">
<!-- Hardware D3D12 rendering (Phase 1) -->
<SwapChainPanel x:Name="VideoSwapChainPanel"
Visibility="Collapsed"
@@ -44,14 +44,15 @@
<!-- UI overlay -->
<Grid x:Name="OverlayGrid" Background="Transparent">
<!-- 로딩 인디케이터 -->
<!-- Loading indicator -->
<ProgressRing x:Name="LoadingRing"
Width="40" Height="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsActive="False"/>
IsActive="False"
Visibility="Collapsed"/>
<!-- 상태 텍스트 오버레이 -->
<!-- Status text overlay -->
<Border x:Name="StatusOverlay"
Background="#80000000"
CornerRadius="4"

View File

@@ -25,7 +25,7 @@ using namespace winrt::Microsoft::UI::Dispatching;
namespace winrt::Vav2Player::implementation
{
VideoPlayerControl::VideoPlayerControl()
: m_useHardwareRendering(true) // TEST: Enable GPU rendering to test the upload buffer fix
: m_useHardwareRendering(true) // Default to GPU rendering
{
InitializeComponent();
}
@@ -57,19 +57,9 @@ namespace winrt::Vav2Player::implementation
OutputDebugStringA("VideoPlayerControl loaded successfully\n");
// Show purple outline placeholder while waiting
ShowPurpleOutlinePlaceholder();
ShowPurpleOutlinePlaceholder(); // Re-enabled to test
// After 3 seconds, try to load actual video
auto delayTimer = winrt::Microsoft::UI::Xaml::DispatcherTimer();
delayTimer.Interval(std::chrono::seconds(3));
delayTimer.Tick([this, delayTimer](auto&&, auto&&) mutable {
delayTimer.Stop();
// Try to load test video file
auto testVideoPath = L"D:/Project/video-av1/sample/simple_test.webm";
OutputDebugStringA("[DEBUG] Attempting to load test video after 3 second delay\n");
LoadVideo(testVideoPath);
});
delayTimer.Start();
// Ready for user interaction - no automatic video loading
}
catch (...)
{
@@ -97,10 +87,6 @@ namespace winrt::Vav2Player::implementation
}
m_renderBitmap = winrt::Microsoft::UI::Xaml::Media::Imaging::WriteableBitmap(width, height);
VideoImage().Source(m_renderBitmap);
VideoImage().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Visible);
VideoImage().Width(width);
VideoImage().Height(height);
auto buffer = m_renderBitmap.PixelBuffer();
auto bufferByteAccess = buffer.as<::Windows::Storage::Streams::IBufferByteAccess>();
@@ -116,6 +102,11 @@ namespace winrt::Vav2Player::implementation
bufferData[i * 4 + 3] = 0; // Alpha (transparent)
}
VideoImage().Source(m_renderBitmap);
VideoImage().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Visible);
VideoImage().Width(width);
VideoImage().Height(height);
// Draw purple outline (border thickness = 4 pixels)
int borderThickness = 4;
for (int y = 0; y < height; y++)
@@ -648,15 +639,16 @@ namespace winrt::Vav2Player::implementation
void VideoPlayerControl::RenderFrameToScreen(const VideoFrame& frame)
{
// GPU rendering attempt
// GPU rendering attempt (only if user selected GPU pipeline)
if (m_useHardwareRendering && m_gpuRenderer && m_gpuRenderer->IsInitialized()) {
if (m_gpuRenderer->TryRenderFrame(frame)) {
// GPU rendering successful - AspectFit was already applied during initialization
return; // Success - done
}
// If GPU rendering fails, fall back to CPU
}
// CPU rendering fallback (always works)
// CPU rendering (either by user choice or GPU fallback)
RenderFrameSoftware(frame);
}
@@ -797,7 +789,7 @@ namespace winrt::Vav2Player::implementation
void VideoPlayerControl::InitializeVideoRenderer()
{
OutputDebugStringA("[DEBUG] InitializeVideoRenderer() called\n");
// Initialize CPU rendering mode (Phase 1)
// Initialize rendering mode based on user selection
if (!m_useHardwareRendering)
{
// Ensure software rendering UI is visible
@@ -1006,4 +998,5 @@ namespace winrt::Vav2Player::implementation
void VideoPlayerControl::StartControlsHideTimer() { /* Simplified implementation */ }
void VideoPlayerControl::StopControlsHideTimer() { /* Simplified implementation */ }
}

View File

@@ -64,7 +64,7 @@ namespace winrt::Vav2Player::implementation
winrt::Microsoft::UI::Xaml::Media::Imaging::WriteableBitmap m_renderBitmap{ nullptr };
std::vector<uint8_t> m_bgraBuffer;
std::unique_ptr<SimpleGPURenderer> m_gpuRenderer;
bool m_useHardwareRendering = false;
bool m_useHardwareRendering = true; // Default to GPU pipeline
// Playback timer for continuous frame processing
winrt::Microsoft::UI::Xaml::DispatcherTimer m_playbackTimer;