Add hardware rendering option in UI
This commit is contained in:
@@ -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
|
||||
<!-- 추가 포함 디렉터리 -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 */ }
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user