Cocoa 模仿苹果';s drawInRect:用于屏幕外像素缓冲区

Cocoa 模仿苹果';s drawInRect:用于屏幕外像素缓冲区,cocoa,nsimage,accelerate-framework,Cocoa,Nsimage,Accelerate Framework,我需要一个例程,可以在一个缓冲区的矩形区域到另一个缓冲区之间快速复制原始32位像素malloc-ed数据 所以。。。下面是我试图模仿苹果的drawInRect:fromRect:operation:fraction方法,将数据快速输出到NSView。这两个例程通常存在于NSImage或NSBitmapImageRep类中。我忽略了操作:模式或分数:alpha混合 可以假设x/y/w/h值已经过测试和截断,以确保源/目标矩形位于提供的两个缓冲区内,并且矩形区域不为零且大小相同(即无缩放) 我的测试

我需要一个例程,可以在一个缓冲区的矩形区域到另一个缓冲区之间快速复制原始32位像素
malloc
-ed数据

所以。。。下面是我试图模仿苹果的
drawInRect:fromRect:operation:fraction
方法,将数据快速输出到NSView。这两个例程通常存在于
NSImage
NSBitmapImageRep
类中。我忽略了
操作:
模式或
分数:
alpha混合

可以假设x/y/w/h值已经过测试和截断,以确保源/目标矩形位于提供的两个缓冲区内,并且矩形区域不为零且大小相同(即无缩放)

我的测试表明,在我的特定硬件上复制全高清(1920x1080)区域图像是非常困难的

  • 情况1:32位传输:6.74ms
  • 案例2:64位传输:5.30ms
  • 案例3:memcpy传输:3.20ms
不幸的是,由于其中一些缓冲区是由外部API提供的,我不能保证缓冲区是64位或128位对齐的。话虽如此,我有一种预感,他们在我的情况下-
memcpy
正在测试缓冲区地址是否已表示对齐,并正在执行一些SSE3内部函数来完成其业务(
\u platform\u 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;
    }
}
typedef结构copyRect
{
u_int32_t*数据;
u_int32_t x;
国际在线;
u_int32_t w;
u_int32_t h;
u_int32_t canvasWidth;//即行字节/4
}copyRect;
-(void)copyRectFromSrc:(copyRect*)srcImage到目标:(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=dstmimage->data+dstDelta;
u_int32_t w2=w/2;
//在缓冲区中从上到下扫描
对于(u_int32_t y=0;y
#include//请参见vImage/Conversion.h
vImage_错误vImageCopyBuffer(const vImage_Buffer*src,const vImage_Buffer*dest,size_t pixelSize,vImage_Flags Flags)vImage_非空(1,2)OSX_可用_启动(u MAC_10_10,u IPHONE_80);

有关Alpha合成,请参阅vImage/Alpha.h中的各种Alpha混合例程。

vImageCopyBufer特定于OSX 10.10。
#include <Accelerate/Accelerate.h>  // see vImage/Conversion.h

vImage_Error vImageCopyBuffer(const vImage_Buffer *src, const vImage_Buffer *dest, size_t pixelSize, vImage_Flags flags ) VIMAGE_NON_NULL(1,2) __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0);