diff --git a/client/renderers/EGL/desktop.c b/client/renderers/EGL/desktop.c index 147af0b5..38e57a05 100644 --- a/client/renderers/EGL/desktop.c +++ b/client/renderers/EGL/desktop.c @@ -340,8 +340,12 @@ bool egl_desktopSetup(EGL_Desktop * desktop, const LG_RendererFormat format) pixFmt = EGL_PF_RGBA16F; break; - case FRAME_TYPE_BGR: - pixFmt = EGL_PF_BGR; + case FRAME_TYPE_BGR_32: + pixFmt = EGL_PF_BGR_32; + break; + + case FRAME_TYPE_RGB_24: + pixFmt = EGL_PF_BGR_24; break; default: diff --git a/client/renderers/EGL/egltypes.h b/client/renderers/EGL/egltypes.h index da12a645..a0bbc52d 100644 --- a/client/renderers/EGL/egltypes.h +++ b/client/renderers/EGL/egltypes.h @@ -38,7 +38,8 @@ typedef enum EGL_PixelFormat EGL_PF_BGRA, EGL_PF_RGBA10, EGL_PF_RGBA16F, - EGL_PF_BGR + EGL_PF_BGR_32, + EGL_PF_RGB_24 } EGL_PixelFormat; diff --git a/client/renderers/EGL/filter_bgr_bgra.c b/client/renderers/EGL/filter_bgr_bgra.c index a729be5d..83d816a2 100644 --- a/client/renderers/EGL/filter_bgr_bgra.c +++ b/client/renderers/EGL/filter_bgr_bgra.c @@ -111,7 +111,7 @@ static bool egl_filterBGRtoBGRASetup(EGL_Filter * filter, { EGL_FilterBGRtoBGRA * this = UPCAST(EGL_FilterBGRtoBGRA, filter); - if (pixFmt != EGL_PF_BGR) + if (pixFmt != EGL_PF_BGR_32 || pixFmt != EGL_PF_RGB_24) return false; if (this->useDMA != useDMA) diff --git a/client/renderers/EGL/texture_framebuffer.c b/client/renderers/EGL/texture_framebuffer.c index 9a0e197d..09940da5 100644 --- a/client/renderers/EGL/texture_framebuffer.c +++ b/client/renderers/EGL/texture_framebuffer.c @@ -109,7 +109,7 @@ static bool egl_texFBUpdate(EGL_Texture * texture, const EGL_TexUpdate * update) update->rectCount * sizeof(FrameDamageRect)); damage->count += update->rectCount; - if (texture->format.pixFmt == EGL_PF_BGR) + if (texture->format.pixFmt == EGL_PF_BGR_32) { FrameDamageRect scaledDamageRects[damage->count]; for (int i = 0; i < damage->count; i++) diff --git a/client/renderers/EGL/texture_util.c b/client/renderers/EGL/texture_util.c index 61d4209f..941c826d 100644 --- a/client/renderers/EGL/texture_util.c +++ b/client/renderers/EGL/texture_util.c @@ -34,7 +34,8 @@ bool egl_texUtilGetFormat(const EGL_TexSetup * setup, EGL_TexFormat * fmt) { //EGL has no support for 24-bit formats, so we stuff it into a 32-bit //texture to unpack with a shader later - case EGL_PF_BGR: + case EGL_PF_BGR_32: + case EGL_PF_RGB_24: // fallthrough case EGL_PF_BGRA: diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index 7f139f59..ba9c10b7 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -787,7 +787,13 @@ static enum ConfigStatus configure(struct Inst * this) this->dataFormat = GL_HALF_FLOAT; break; - case FRAME_TYPE_BGR: + case FRAME_TYPE_RGB_24: + this->intFormat = GL_RGB8; + this->vboFormat = GL_RGB; + this->dataFormat = GL_UNSIGNED_BYTE; + break; + + case FRAME_TYPE_BGR_32: this->intFormat = GL_RGB8; this->vboFormat = GL_BGR; this->dataFormat = GL_UNSIGNED_BYTE; diff --git a/client/src/main.c b/client/src/main.c index fc30e521..07958da8 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -681,7 +681,8 @@ int main_frameThread(void * unused) lgrFormat.bpp = 64; break; - case FRAME_TYPE_BGR: + case FRAME_TYPE_BGR_32: + case FRAME_TYPE_RGB_24: lgrFormat.bpp = 24; break; diff --git a/common/include/common/types.h b/common/include/common/types.h index 054cb4c8..31d95dbc 100644 --- a/common/include/common/types.h +++ b/common/include/common/types.h @@ -55,7 +55,8 @@ typedef enum FrameType FRAME_TYPE_RGBA , // RGBA interleaved: R,G,B,A 32bpp FRAME_TYPE_RGBA10 , // RGBA interleaved: R,G,B,A 10,10,10,2 bpp FRAME_TYPE_RGBA16F , // RGBA interleaved: R,G,B,A 16,16,16,16 bpp float - FRAME_TYPE_BGR , // BGR (DO NOT COMMIT THIS) + FRAME_TYPE_BGR_32 , // BGR 24-bpp in 32bpp + FRAME_TYPE_RGB_24 , // RGB 24-bpp FRAME_TYPE_MAX , // sentinel value } FrameType; diff --git a/host/include/interface/capture.h b/host/include/interface/capture.h index 9fb4ca22..e9300678 100644 --- a/host/include/interface/capture.h +++ b/host/include/interface/capture.h @@ -48,7 +48,8 @@ typedef enum CaptureFormat CAPTURE_FMT_RGBA , CAPTURE_FMT_RGBA10 , CAPTURE_FMT_RGBA16F, - CAPTURE_FMT_BGR , + CAPTURE_FMT_BGR_32 , + CAPTURE_FMT_RGB_24 , // pointer formats CAPTURE_FMT_COLOR , diff --git a/host/platform/Windows/capture/DXGI/src/dxgi.c b/host/platform/Windows/capture/DXGI/src/dxgi.c index 3a6d16e0..091ed489 100644 --- a/host/platform/Windows/capture/DXGI/src/dxgi.c +++ b/host/platform/Windows/capture/DXGI/src/dxgi.c @@ -1170,15 +1170,12 @@ static CaptureResult dxgi_capture(void) this->dxgiFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; break; - case CAPTURE_FMT_BGR: + case CAPTURE_FMT_BGR_32: this->bpp = 4; this->dxgiFormat = DXGI_FORMAT_B8G8R8A8_UNORM; break; - case CAPTURE_FMT_COLOR : - case CAPTURE_FMT_MONO : - case CAPTURE_FMT_MASKED: - case CAPTURE_FMT_MAX : + default: DEBUG_ERROR("Unsupported input format"); result = CAPTURE_RESULT_ERROR; goto exit; @@ -1247,7 +1244,7 @@ static CaptureResult dxgi_capture(void) FrameDamageRect rect = tex->texDamageRects[i]; // correct the damage rect for BGR packed data - if (this->outputFormat == CAPTURE_FMT_BGR) + if (this->outputFormat == CAPTURE_FMT_BGR_32) { rect.x = (rect.x * 3 ) / 4; // round down rect.width = (rect.width * 3 + 3) / 4; // round up @@ -1445,7 +1442,7 @@ static CaptureResult dxgi_getFrame(FrameBuffer * frame, int frameIndex) tex->damageRectsCount * sizeof(*tex->damageRects)); damage->count += tex->damageRectsCount; - if (this->outputFormat == CAPTURE_FMT_BGR) + if (this->outputFormat == CAPTURE_FMT_BGR_32) { FrameDamageRect scaledDamageRects[damage->count]; for (int i = 0; i < ARRAYSIZE(scaledDamageRects); i++) { diff --git a/host/platform/Windows/capture/DXGI/src/pp/downsample.c b/host/platform/Windows/capture/DXGI/src/pp/downsample.c index bac1d4c3..ba7e56e2 100644 --- a/host/platform/Windows/capture/DXGI/src/pp/downsample.c +++ b/host/platform/Windows/capture/DXGI/src/pp/downsample.c @@ -88,7 +88,7 @@ static bool downsample_configure(void * opaque, bool result = false; DownsampleInst * inst = (DownsampleInst *)opaque; - if (*format == CAPTURE_FMT_BGR) + if (*format == CAPTURE_FMT_BGR_32) this.disabled = true; if (this.disabled) diff --git a/host/platform/Windows/capture/DXGI/src/pp/rgb24.c b/host/platform/Windows/capture/DXGI/src/pp/rgb24.c index 7ddf25ca..0d797cef 100644 --- a/host/platform/Windows/capture/DXGI/src/pp/rgb24.c +++ b/host/platform/Windows/capture/DXGI/src/pp/rgb24.c @@ -192,7 +192,7 @@ static bool rgb24_configure(void * opaque, *cols = this.width; *rows = this.height; - *format = CAPTURE_FMT_BGR; + *format = CAPTURE_FMT_BGR_32; comRef_toGlobal(inst->tex , tex ); comRef_toGlobal(inst->target, target ); diff --git a/host/platform/Windows/capture/DXGI/src/util.c b/host/platform/Windows/capture/DXGI/src/util.c index bc765513..9f79218a 100644 --- a/host/platform/Windows/capture/DXGI/src/util.c +++ b/host/platform/Windows/capture/DXGI/src/util.c @@ -338,7 +338,7 @@ DXGI_FORMAT getDXGIFormat(CaptureFormat format) case CAPTURE_FMT_RGBA16F: return DXGI_FORMAT_R16G16B16A16_FLOAT; - case CAPTURE_FMT_BGR: + case CAPTURE_FMT_BGR_32: return DXGI_FORMAT_B8G8R8A8_UNORM; default: diff --git a/host/platform/Windows/capture/NVFBC/src/nvfbc.c b/host/platform/Windows/capture/NVFBC/src/nvfbc.c index ff3e26fe..eb4b4340 100644 --- a/host/platform/Windows/capture/NVFBC/src/nvfbc.c +++ b/host/platform/Windows/capture/NVFBC/src/nvfbc.c @@ -60,6 +60,7 @@ struct iface bool seperateCursor; bool dwmFlush; + bool noHDR; CaptureGetPointerBuffer getPointerBufferFn; CapturePostPointerBuffer postPointerBufferFn; LGThread * pointerThread; @@ -70,10 +71,12 @@ struct iface bool resChanged, scale; unsigned int targetWidth, targetHeight; - unsigned int formatVer; - unsigned int grabWidth, grabHeight, grabStride; - unsigned int shmStride; - bool isHDR; + unsigned int formatVer; + unsigned int grabWidth, grabHeight, grabStride; + unsigned int bpp; + CaptureFormat format; + unsigned int shmStride; + bool isHDR; uint8_t * frameBuffer; uint8_t * diffMap; @@ -166,6 +169,13 @@ static void nvfbc_initOptions(void) .type = OPTION_TYPE_BOOL, .value.x_bool = false }, + { + .module = "nvfbc", + .name = "noHDR", + .description = "Capture HDR content as SDR", + .type = OPTION_TYPE_BOOL, + .value.x_bool = true + }, {0} }; @@ -183,6 +193,7 @@ static bool nvfbc_create( this->seperateCursor = option_get_bool("nvfbc", "decoupleCursor"); this->dwmFlush = option_get_bool("nvfbc", "dwmFlush" ); + this->noHDR = option_get_bool("nvfbc", "noHDR" ); this->getPointerBufferFn = getPointerBufferFn; this->postPointerBufferFn = postPointerBufferFn; @@ -303,10 +314,13 @@ static bool nvfbc_init(void) getDesktopSize(&this->width, &this->height); updateScale(); + this->bpp = this->noHDR ? 3 : 4; + this->format = this->noHDR ? CAPTURE_FMT_RGB_24 : CAPTURE_FMT_RGBA10; + HANDLE event; if (!NvFBCToSysSetup( this->nvfbc, - BUFFER_FMT_ARGB10, + this->noHDR ? BUFFER_FMT_RGB : BUFFER_FMT_ARGB10, !this->seperateCursor, this->seperateCursor, true, @@ -655,7 +669,7 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame, ++this->formatVer; } - const unsigned int maxHeight = maxFrameSize / (this->shmStride * 4); + const unsigned int maxHeight = maxFrameSize / (this->shmStride * this->bpp); this->dataHeight = min(maxHeight, this->grabHeight); frame->formatVer = this->formatVer; @@ -666,15 +680,15 @@ static CaptureResult nvfbc_waitFrame(CaptureFrame * frame, frame->dataWidth = this->grabWidth; frame->dataHeight = this->dataHeight; frame->truncated = maxHeight < this->grabHeight; - frame->pitch = this->shmStride * 4; + frame->pitch = this->shmStride * this->bpp; frame->stride = this->shmStride; frame->rotation = CAPTURE_ROT_0; updateDamageRects(frame); - frame->format = CAPTURE_FMT_RGBA10; + frame->format = this->format; frame->hdr = this->grabInfo.bIsHDR; - frame->hdrPQ = true; + frame->hdrPQ = this->grabInfo.bIsHDR; return CAPTURE_RESULT_OK; } @@ -705,16 +719,19 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame, int frameIndex) } unsigned int x2 = x; - while (x2 < w && ((!wasFresh && info->diffMap[y * w + x2]) || this->diffMap[y * w + x2])) + while (x2 < w && ((!wasFresh && info->diffMap[y * w + x2]) || + this->diffMap[y * w + x2])) ++x2; - unsigned int width = (min(x2 << this->diffShift, this->grabWidth) - (x << this->diffShift)) * 4; - rectCopyUnaligned(frameData, this->frameBuffer, ystart, yend, x << (2 + this->diffShift), - this->shmStride * 4, this->grabStride * 4, width); + unsigned int width = (min(x2 << this->diffShift, this->grabWidth) - + (x << this->diffShift)) * this->bpp; + rectCopyUnaligned(frameData, this->frameBuffer, ystart, yend, + x << (2 + this->diffShift), this->shmStride * this->bpp, + this->grabStride * this->bpp, width); x = x2; } - framebuffer_set_write_ptr(frame, yend * this->shmStride * 4); + framebuffer_set_write_ptr(frame, yend * this->shmStride * this->bpp); } } else if (this->grabStride != this->shmStride) @@ -722,16 +739,17 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame, int frameIndex) for (int y = 0; y < this->dataHeight; y += 64) { int yend = min(this->dataHeight, y + 128); - rectCopyUnaligned(frameData, this->frameBuffer, y, yend, 0, this->shmStride * 4, - this->grabStride * 4, this->grabWidth * 4); - framebuffer_set_write_ptr(frame, yend * this->shmStride * 4); + rectCopyUnaligned(frameData, this->frameBuffer, y, yend, 0, + this->shmStride * this->bpp, this->grabStride * this->bpp, + this->grabWidth * this->bpp); + framebuffer_set_write_ptr(frame, yend * this->shmStride * this->bpp); } } else framebuffer_write( frame, this->frameBuffer, - this->dataHeight * this->grabInfo.dwBufferWidth * 4 + this->dataHeight * this->grabInfo.dwBufferWidth * this->bpp ); for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i) diff --git a/host/src/app.c b/host/src/app.c index ff5f8635..5d910387 100644 --- a/host/src/app.c +++ b/host/src/app.c @@ -267,8 +267,12 @@ static bool sendFrame(void) flags |= FRAME_FLAG_HDR; break; - case CAPTURE_FMT_BGR: - fi->type = FRAME_TYPE_BGR; + case CAPTURE_FMT_BGR_32: + fi->type = FRAME_TYPE_BGR_32; + break; + + case CAPTURE_FMT_RGB_24: + fi->type = FRAME_TYPE_RGB_24; break; default: