Skip to content

Commit 91ce431

Browse files
committed
Recording: Cursor overlay rendering fixes (w/ Guest Additions installed). bugref:11069
svn:sync-xref-src-repo-rev: r173141
1 parent c1d2b3b commit 91ce431

2 files changed

Lines changed: 57 additions & 6 deletions

File tree

src/VBox/Main/src-client/RecordingCodec.cpp

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
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

src/VBox/Main/src-client/RecordingStream.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $Id: RecordingStream.cpp 113382 2026-03-13 10:21:15Z andreas.loeffler@oracle.com $ */
1+
/* $Id: RecordingStream.cpp 113387 2026-03-13 14:11:41Z andreas.loeffler@oracle.com $ */
22
/** @file
33
* Recording stream code.
44
*/
@@ -553,10 +553,19 @@ int RecordingStream::process(RTMSINTERVAL msTimeout)
553553
case RECORDINGFRAME_TYPE_CURSOR_POS:
554554
case RECORDINGFRAME_TYPE_CURSOR_SHAPE:
555555
{
556-
int const vrc2 = recordingCodecEncode(pCodec, pFrame, pFrame->msTimestamp, m_pCtx /* pvUser */);
556+
/* Cursor frames must first be composed into the current image and then encoded. */
557+
int vrc2 = recordingCodecCompose(pCodec, pFrame, pFrame->msTimestamp, m_pCtx /* pvUser */);
557558
AssertRC(vrc2);
558559
if (RT_SUCCESS(vrc))
559560
vrc = vrc2;
561+
562+
if (RT_SUCCESS(vrc2))
563+
{
564+
vrc2 = recordingCodecEncode(pCodec, pFrame, pFrame->msTimestamp, m_pCtx /* pvUser */);
565+
AssertRC(vrc2);
566+
if (RT_SUCCESS(vrc))
567+
vrc = vrc2;
568+
}
560569
break;
561570
}
562571

@@ -843,7 +852,6 @@ int RecordingStream::cmdQueueAddFrame(PRECORDINGFRAME pFrame, PRECORDINGFRAMEPOO
843852

844853
/* Sanity. */
845854
Assert(pCmd->idxPool != RECORDINGFRAME_TYPE_INVALID);
846-
Assert(pCmd->msTimestamp);
847855
Assert(pFrame->msTimestamp == pCmd->msTimestamp);
848856

849857
RECORDINGCMD *pCmdWr;

0 commit comments

Comments
 (0)