@@ -437,75 +437,26 @@ private bool TryRenderPreparedFlush<TPixel>(
437437 return false ;
438438 }
439439
440+ // Use the target texture directly as the backdrop source.
441+ // This avoids an extra texture allocation and target→source copy.
440442 TextureView * backdropTextureView = flushContext . TargetView ;
441443 int sourceOriginX = targetLocalBounds . X ;
442444 int sourceOriginY = targetLocalBounds . Y ;
443- Texture * outputTexture = flushContext . TargetTexture ;
444- TextureView * outputTextureView = flushContext . TargetView ;
445- bool writesDirectlyToTarget = ! flushContext . RequiresReadback ;
446- bool copyOutputToTarget = ! writesDirectlyToTarget ;
447- int outputOriginX = writesDirectlyToTarget ? targetLocalBounds . X : 0 ;
448- int outputOriginY = writesDirectlyToTarget ? targetLocalBounds . Y : 0 ;
449- if ( writesDirectlyToTarget )
450- {
451- backdropTextureView = flushContext . TargetView ;
452- sourceOriginX = targetLocalBounds . X ;
453- sourceOriginY = targetLocalBounds . Y ;
454- if ( ! TryCreateCompositionTexture (
455- flushContext ,
456- targetLocalBounds . Width ,
457- targetLocalBounds . Height ,
458- out outputTexture ,
459- out outputTextureView ,
460- out error ) )
461- {
462- return false ;
463- }
464-
465- outputOriginX = 0 ;
466- outputOriginY = 0 ;
467- copyOutputToTarget = true ;
468- }
469- else
470- {
471- if ( ! TryCreateCompositionTexture (
472- flushContext ,
473- targetLocalBounds . Width ,
474- targetLocalBounds . Height ,
475- out Texture * sourceTexture ,
476- out backdropTextureView ,
477- out error ) )
478- {
479- return false ;
480- }
481445
482- CopyTextureRegion (
446+ if ( ! TryCreateCompositionTexture (
483447 flushContext ,
484- flushContext . TargetTexture ,
485- targetLocalBounds . X ,
486- targetLocalBounds . Y ,
487- sourceTexture ,
488- 0 ,
489- 0 ,
490448 targetLocalBounds . Width ,
491- targetLocalBounds . Height ) ;
492- sourceOriginX = 0 ;
493- sourceOriginY = 0 ;
494- if ( ! TryCreateCompositionTexture (
495- flushContext ,
496- targetLocalBounds . Width ,
497- targetLocalBounds . Height ,
498- out outputTexture ,
499- out outputTextureView ,
500- out error ) )
501- {
502- return false ;
503- }
504-
505- outputOriginX = 0 ;
506- outputOriginY = 0 ;
449+ targetLocalBounds . Height ,
450+ out Texture * outputTexture ,
451+ out TextureView * outputTextureView ,
452+ out error ) )
453+ {
454+ return false ;
507455 }
508456
457+ int outputOriginX = 0 ;
458+ int outputOriginY = 0 ;
459+
509460 List < CompositionCoverageDefinition > coverageDefinitions = [ ] ;
510461 Dictionary < CoverageDefinitionIdentity , int > coverageDefinitionIndexByKey = [ ] ;
511462 int [ ] batchCoverageIndices = new int [ preparedBatches . Count ] ;
@@ -572,8 +523,15 @@ private bool TryRenderPreparedFlush<TPixel>(
572523 return false ;
573524 }
574525
575- if ( copyOutputToTarget )
526+ if ( flushContext . RequiresReadback )
576527 {
528+ // CPU target: read back directly from the output texture at (0,0)
529+ // instead of copying output→target and then reading from target.
530+ flushContext . ReadbackSourceOverride = outputTexture ;
531+ }
532+ else
533+ {
534+ // Native GPU surface: copy composited output back into the target.
577535 CopyTextureRegion (
578536 flushContext ,
579537 outputTexture ,
@@ -1960,11 +1918,18 @@ flushContext.ReadbackBuffer is null ||
19601918 uint copyBytesPerRow = checked ( ( uint ) copyBounds . Width * ( uint ) Unsafe . SizeOf < TPixel > ( ) ) ;
19611919 copyBytesPerRow = ( copyBytesPerRow + 255U ) & ~ 255U ;
19621920
1921+ // When ReadbackSourceOverride is set, the output texture already contains the
1922+ // composited result at (0,0), so we read from there instead of the target texture.
1923+ bool useOverride = flushContext . ReadbackSourceOverride is not null ;
1924+ Texture * readbackTexture = useOverride ? flushContext . ReadbackSourceOverride : flushContext . TargetTexture ;
1925+ uint readbackOriginX = useOverride ? 0 : ( uint ) copyBounds . X ;
1926+ uint readbackOriginY = useOverride ? 0 : ( uint ) copyBounds . Y ;
1927+
19631928 ImageCopyTexture source = new ( )
19641929 {
1965- Texture = flushContext . TargetTexture ,
1930+ Texture = readbackTexture ,
19661931 MipLevel = 0 ,
1967- Origin = new Origin3D ( ( uint ) copyBounds . X , ( uint ) copyBounds . Y , 0 ) ,
1932+ Origin = new Origin3D ( readbackOriginX , readbackOriginY , 0 ) ,
19681933 Aspect = TextureAspect . All
19691934 } ;
19701935
0 commit comments