[vlc-commits] [Git][videolan/vlc][master] 2 commits: d3d11_player: use a SRWLOCK instead of a CRITICAL_SECTION
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri Aug 20 14:07:47 UTC 2021
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
27515ae5 by Steve Lhomme at 2021-08-20T13:54:28+00:00
d3d11_player: use a SRWLOCK instead of a CRITICAL_SECTION
It's lighter and faster.
- - - - -
f35b34c0 by Steve Lhomme at 2021-08-20T13:54:28+00:00
d3d11_player: adjust the swapchain size when resizing
This will provide better quality when expanding the size compared to the
initial size.
- - - - -
1 changed file:
- doc/libvlc/d3d11_player.cpp
Changes:
=====================================
doc/libvlc/d3d11_player.cpp
=====================================
@@ -25,8 +25,8 @@
#include <vlc/vlc.h>
-#define SCREEN_WIDTH 1500
-#define SCREEN_HEIGHT 900
+#define INITIAL_WIDTH 1500
+#define INITIAL_HEIGHT 900
#define BORDER_LEFT (-0.95f)
#define BORDER_RIGHT ( 0.85f)
#define BORDER_TOP ( 0.95f)
@@ -74,8 +74,12 @@ struct render_context
ID3D11SamplerState *samplerState;
- CRITICAL_SECTION sizeLock; // the ReportSize callback cannot be called during/after the Cleanup_cb is called
+ SRWLOCK sizeLock; // the ReportSize callback cannot be called during/after the Cleanup_cb is called
+ SRWLOCK swapchainLock; // protect the swapchain access when the UI needs to resize it
unsigned width, height;
+ struct {
+ unsigned width, height;
+ } client_area;
void (*ReportSize)(void *ReportOpaque, unsigned width, unsigned height);
void *ReportOpaque;
};
@@ -131,8 +135,8 @@ static void init_direct3d(struct render_context *ctx)
scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- scd.BufferDesc.Width = SCREEN_WIDTH;
- scd.BufferDesc.Height = SCREEN_HEIGHT;
+ scd.BufferDesc.Width = ctx->client_area.width;
+ scd.BufferDesc.Height = ctx->client_area.height;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = ctx->hWnd;
scd.SampleDesc.Count = 1;
@@ -165,12 +169,7 @@ static void init_direct3d(struct render_context *ctx)
pMultithread->Release();
}
- // RECT currentRect;
- // GetWindowRect(hWnd, ¤tRect);
- //currentRect.right - currentRect.left;
- //currentRect.bottom - currentRect.top;
-
- D3D11_VIEWPORT viewport = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0 };
+ D3D11_VIEWPORT viewport = { 0, 0, (FLOAT)ctx->client_area.width, (FLOAT)ctx->client_area.height, 0, 0 };
ctx->d3dctx->RSSetViewports(1, &viewport);
@@ -443,6 +442,7 @@ static bool StartRendering_cb( void *opaque, bool enter )
struct render_context *ctx = static_cast<struct render_context *>( opaque );
if ( enter )
{
+ AcquireSRWLockExclusive(&ctx->swapchainLock);
// DEBUG: draw greenish background to show where libvlc doesn't draw in the texture
// Normally you should Clear with a black background
static const FLOAT greenRGBA[4] = {0.5f, 0.5f, 0.0f, 1.0f};
@@ -457,6 +457,7 @@ static bool StartRendering_cb( void *opaque, bool enter )
// We start the drawing of the shared texture in our app as early as possible
// in hope it's done as soon as Swap_cb is called
ctx->d3dctx->DrawIndexed(ctx->quadIndexCount, 0, 0);
+ ReleaseSRWLockExclusive(&ctx->swapchainLock);
}
return true;
@@ -489,12 +490,13 @@ static void Cleanup_cb( void *opaque )
ctx->d3dctxVLC->Release();
}
+// receive the libvlc callback to call when we want to change the libvlc output size
static void Resize_cb( void *opaque,
void (*report_size_change)(void *report_opaque, unsigned width, unsigned height),
void *report_opaque )
{
struct render_context *ctx = static_cast<struct render_context *>( opaque );
- EnterCriticalSection(&ctx->sizeLock);
+ AcquireSRWLockExclusive(&ctx->sizeLock);
ctx->ReportSize = report_size_change;
ctx->ReportOpaque = report_opaque;
@@ -503,7 +505,7 @@ static void Resize_cb( void *opaque,
/* report our initial size */
ctx->ReportSize(ctx->ReportOpaque, ctx->width, ctx->height);
}
- LeaveCriticalSection(&ctx->sizeLock);
+ ReleaseSRWLockExclusive(&ctx->sizeLock);
}
static const char *AspectRatio = NULL;
@@ -527,13 +529,39 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
{
case WM_SIZE:
{
- /* tell libvlc that our size has changed */
+ ctx->client_area.width = LOWORD(lParam);
+ ctx->client_area.height = HIWORD(lParam);
+
+ // update the swapchain to match our window client area
+ AcquireSRWLockExclusive(&ctx->swapchainLock);
+ if (ctx->swapchain != nullptr)
+ {
+ ctx->swapchainRenderTarget->Release();
+ ctx->swapchain->ResizeBuffers(0, ctx->client_area.width, ctx->client_area.height, DXGI_FORMAT_UNKNOWN, 0);
+
+ ID3D11Texture2D *pBackBuffer;
+ ctx->swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
+
+ ctx->d3device->CreateRenderTargetView(pBackBuffer, NULL, &ctx->swapchainRenderTarget);
+ pBackBuffer->Release();
+
+ ctx->d3dctx->OMSetRenderTargets(1, &ctx->swapchainRenderTarget, NULL);
+
+ D3D11_VIEWPORT viewport = { 0, 0, (FLOAT)ctx->client_area.width, (FLOAT)ctx->client_area.height, 0, 0 };
+
+ ctx->d3dctx->RSSetViewports(1, &viewport);
+ }
+ ReleaseSRWLockExclusive(&ctx->swapchainLock);
+
ctx->width = LOWORD(lParam) * (BORDER_RIGHT - BORDER_LEFT) / 2.0f; /* remove the orange part ! */
ctx->height = HIWORD(lParam) * (BORDER_TOP - BORDER_BOTTOM) / 2.0f;
- EnterCriticalSection(&ctx->sizeLock);
+
+ // tell libvlc we want a new rendering size
+ // we could also match the source video size and scale in swapchain render
+ AcquireSRWLockExclusive(&ctx->sizeLock);
if (ctx->ReportSize != nullptr)
ctx->ReportSize(ctx->ReportOpaque, ctx->width, ctx->height);
- LeaveCriticalSection(&ctx->sizeLock);
+ ReleaseSRWLockExclusive(&ctx->sizeLock);
}
break;
@@ -606,7 +634,8 @@ int WINAPI WinMain(HINSTANCE hInstance,
free( file_path );
Context.p_mp = libvlc_media_player_new_from_media( p_media );
- InitializeCriticalSection(&Context.sizeLock);
+ InitializeSRWLock(&Context.sizeLock);
+ InitializeSRWLock(&Context.swapchainLock);
ZeroMemory(&wc, sizeof(WNDCLASSEX));
@@ -619,16 +648,19 @@ int WINAPI WinMain(HINSTANCE hInstance,
RegisterClassEx(&wc);
- RECT wr = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
+ RECT wr = {0, 0, INITIAL_WIDTH, INITIAL_HEIGHT};
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
+ Context.client_area.width = wr.right - wr.left;
+ Context.client_area.height = wr.bottom - wr.top;
+
Context.hWnd = CreateWindowEx(0,
"WindowClass",
"libvlc Demo app",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
- wr.right - wr.left,
- wr.bottom - wr.top,
+ Context.client_area.width,
+ Context.client_area.height,
NULL,
NULL,
hInstance,
@@ -671,7 +703,5 @@ int WINAPI WinMain(HINSTANCE hInstance,
libvlc_release( p_libvlc );
- DeleteCriticalSection(&Context.sizeLock);
-
return msg.wParam;
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/5b9beae04210dcbd6f33c6f8c3869c8b483d4151...f35b34c0a1a6b1c267c3f104217f0d7cbb9e4374
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/5b9beae04210dcbd6f33c6f8c3869c8b483d4151...f35b34c0a1a6b1c267c3f104217f0d7cbb9e4374
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list