我需要一個例程,它可以快速複製一個緩衝區的矩形區域之間的原始32位像素數據。仿真Apple的drawInRect:用於離屏像素緩衝區
所以...下面是我試圖效仿Apple的drawInRect:fromRect:operation:fraction
方法blitting數據輸出到NSView。這兩個例程通常存在於NSImage
或NSBitmapImageRep
類中。我忽略了operation:
模式或fraction:
alpha混合。
可以假設x/y/w/h值已被測試&被截斷以確保源/目標矩形位於提供的兩個緩衝區內,並且矩形區域是非零的並且尺寸相同(即不縮放)。
我的測試表明覆制全HD(1920×1080)在我的特定硬件區域圖像是
- 殼體1:32位傳送:6.74ms
- 殼體2:64位傳送:5.30ms
- 殼體3:memcpy的傳輸:3.20ms
不幸的是,一些這些緩衝器由外部API提供,我沒有保證,緩衝器是64位或128位對齊。話雖如此,我有一種預感他們在我的情況 - memcpy
正在測試,看看是否緩衝區地址說對齊,並正在做一些SSE3內部函數來做生意(_platform_memmove$VARIANT$Ivybridge
)。
有沒有關於改善這一切的建議?
或者也許在Cocoa API中有一些神奇的例程已經這樣做了嗎?
typedef struct copyRect
{
u_int32_t *data;
u_int32_t x;
u_int32_t y;
u_int32_t w;
u_int32_t h;
u_int32_t canvasWidth; // ie. rowBytes/4
} copyRect;
-(void)copyRectFromSrc:(copyRect *)srcImage toTarget:(copyRect *)dstImage
{
u_int32_t h = srcImage->h;
u_int32_t w = srcImage->w;
u_int32_t srcDelta = srcImage->y*srcImage->canvasWidth + srcImage->x;
u_int32_t dstDelta = dstImage->y*dstImage->canvasWidth + dstImage->x;
u_int32_t *srcPtr = srcImage->data+srcDelta;
u_int32_t *dstPtr = dstImage->data+dstDelta;
u_int32_t w2 = w/2;
// scan top-to-bottom in buffer
for (u_int32_t y=0; y<h; y++) {
// case 1: this would work in all cases (single pixel = 32 bits)
// u_int32_t *srcXptr = srcPtr;
// u_int32_t *dstXptr = dstPtr;
// for (u_int32_t x=0; x<w; x++)
// *dstXptr++ = *srcXptr++;
// case 2: this would work if src/dst image were even-width
// u_int64_t *srcXptr = (u_int64_t *)srcPtr;
// u_int64_t *dstXptr = (u_int64_t *)dstPtr;
// for (u_int32_t x=0; x<w2; x++)
// *dstXptr++ = *srcXptr++;
// case 3: this seems to have the best performance (all cases)
memcpy(dstPtr,srcPtr,w*4);
srcPtr += srcImage->canvasWidth;
dstPtr += dstImage->canvasWidth;
}
}
vImageCopyBufer特定於OSX 10.10。 – zzyzy