@@ -649,6 +649,18 @@ jboolean clipDestCoords(
649
649
SurfaceData_InvokeUnlock (env, srcOps, &srcInfo);
650
650
}
651
651
652
+ void copyFromMTLBuffer (void *pDst, id <MTLBuffer > srcBuf, jint offset, jint len, BOOL convertFromArgbPre) {
653
+ char *pSrc = (char *)srcBuf.contents + offset;
654
+ if (convertFromArgbPre) {
655
+ jint pixelLen = len>>2 ;
656
+ for (int i = 0 ; i < pixelLen; i++) {
657
+ LoadIntArgbPreTo1IntArgb ((jint*)pSrc, 0 , i, ((jint*)pDst)[i]);
658
+ }
659
+ } else {
660
+ memcpy (pDst, pSrc, len);
661
+ }
662
+ }
663
+
652
664
/* *
653
665
* Specialized blit method for copying a native MTL "Surface" (pbuffer,
654
666
* window, etc.) to a system memory ("Sw") surface.
@@ -719,7 +731,7 @@ jboolean clipDestCoords(
719
731
// Metal texture is (0,0) at left-top
720
732
srcx = srcOps->xOffset + srcx;
721
733
srcy = srcOps->yOffset + srcy;
722
- const int srcLength = width * height * 4 ; // NOTE: assume that src format is MTLPixelFormatBGRA8Unorm
734
+ const int byteLength = width * height * 4 ; // NOTE: assume that src format is MTLPixelFormatBGRA8Unorm
723
735
724
736
// Create MTLBuffer (or use static)
725
737
MTLRasterFormatInfo rfi = RasterFormatInfos[dsttype];
@@ -771,27 +783,28 @@ jboolean clipDestCoords(
771
783
toBuffer: mtlbuf
772
784
destinationOffset: 0 /* offset already taken in: pDst = PtrAddBytes(pDst, dstx * dstInfo.pixelStride)*/
773
785
destinationBytesPerRow: width*4
774
- destinationBytesPerImage: width * height* 4 ];
786
+ destinationBytesPerImage: byteLength ];
775
787
[blitEncoder endEncoding ];
776
788
777
789
// Commit and wait for reading complete
778
790
[cb commit ];
779
791
[cb waitUntilCompleted ];
780
792
781
793
// Perform conversion if necessary
794
+ BOOL convertFromPre = !RasterFormatInfos[dsttype].isPremult && !srcOps->isOpaque ;
782
795
if (directCopy) {
783
796
if ((dstInfo.scanStride == width * dstInfo.pixelStride ) &&
784
797
(height == (dstInfo.bounds .y2 - dstInfo.bounds .y1 ))) {
785
798
// mtlbuf.contents have same dimensions as of pDst
786
- memcpy (pDst, mtlbuf. contents , srcLength );
799
+ copyFromMTLBuffer (pDst, mtlbuf, 0 , byteLength, convertFromPre );
787
800
} else {
788
801
// mtlbuf.contents have smaller dimensions than pDst
789
802
// copy each row from mtlbuf.contents at appropriate position in pDst
790
803
// Note : pDst is already addjusted for offsets using PtrAddBytes above
791
804
792
805
int rowSize = width * dstInfo.pixelStride ;
793
806
for (int y = 0 ; y < height; y++) {
794
- memcpy (pDst, mtlbuf. contents + ( y * rowSize) , rowSize);
807
+ copyFromMTLBuffer (pDst, mtlbuf, y * rowSize, rowSize, convertFromPre );
795
808
pDst = PtrAddBytes (pDst, dstInfo.scanStride );
796
809
}
797
810
}
0 commit comments