1- /* $Id: RecordingCodec.cpp 113380 2026-03-13 10:01:45Z andreas.loeffler@oracle.com $ */
1+ /* $Id: RecordingCodec.cpp 113387 2026-03-13 14:11:41Z andreas.loeffler@oracle.com $ */
22/* * @file
33 * Recording codec wrapper.
44 */
@@ -485,8 +485,6 @@ static DECLCALLBACK(int) recordingCodecVPXCompose(PRECORDINGCODEC pCodec, PRECOR
485485 if (RT_FAILURE (vrc))
486486 break ;
487487
488- pFront = pBack;
489-
490488 sw = pSrc->Info .uWidth ;
491489 sh = pSrc->Info .uHeight ;
492490 sx = pSrc->Pos .x ;
@@ -496,6 +494,51 @@ static DECLCALLBACK(int) recordingCodecVPXCompose(PRECORDINGCODEC pCodec, PRECOR
496494
497495 dx = pSrc->Pos .x ;
498496 dy = pSrc->Pos .y ;
497+
498+ /* Re-apply software cursor when the updated video region overlaps it.
499+ *
500+ * Front keeps the composed image (framebuffer + cursor), while back keeps plain
501+ * framebuffer data. A video update can overwrite cursor pixels in front; refresh
502+ * the full cursor area from back and blend the cursor again in that case. */
503+ PRECORDINGVIDEOFRAME const pCursor = pCodec->Video .VPX .pCursorShape ;
504+ if (pCursor)
505+ {
506+ uint32_t const uCurX = pCodec->Video .VPX .PosCursorOld .x ;
507+ uint32_t const uCurY = pCodec->Video .VPX .PosCursorOld .y ;
508+ if ( uCurX < pFront->Info .uWidth
509+ && uCurY < pFront->Info .uHeight )
510+ {
511+ uint32_t const uCurW = RT_MIN (pCursor->Info .uWidth , pFront->Info .uWidth - uCurX);
512+ uint32_t const uCurH = RT_MIN (pCursor->Info .uHeight , pFront->Info .uHeight - uCurY);
513+ if (uCurW && uCurH)
514+ {
515+ uint64_t const uUpdX0 = pSrc->Pos .x ;
516+ uint64_t const uUpdY0 = pSrc->Pos .y ;
517+ uint64_t const uUpdX1 = uUpdX0 + pSrc->Info .uWidth ;
518+ uint64_t const uUpdY1 = uUpdY0 + pSrc->Info .uHeight ;
519+ uint64_t const uCurX0 = uCurX;
520+ uint64_t const uCurY0 = uCurY;
521+ uint64_t const uCurX1 = uCurX0 + uCurW;
522+ uint64_t const uCurY1 = uCurY0 + uCurH;
523+
524+ bool const fIntersects = uUpdX0 < uCurX1
525+ && uUpdX1 > uCurX0
526+ && uUpdY0 < uCurY1
527+ && uUpdY1 > uCurY0;
528+ if (fIntersects )
529+ {
530+ vrc = RecordingVideoFrameBlitFrame (pFront, uCurX, uCurY,
531+ pBack, uCurX, uCurY, uCurW, uCurH);
532+ if (RT_SUCCESS (vrc))
533+ RecordingVideoFrameBlitRawAlpha (pFront, uCurX, uCurY,
534+ pCursor->pau8Buf , pCursor->cbBuf ,
535+ 0 /* uSrcX */ , 0 /* uSrcY */ , uCurW, uCurH,
536+ pCursor->Info .uBytesPerLine ,
537+ pCursor->Info .uBPP , pCursor->Info .enmPixelFmt );
538+ }
539+ }
540+ }
541+ }
499542 break ;
500543 }
501544
0 commit comments