gpt4 book ai didi

cocoa - 模拟苹果的drawInRect : for offscreen pixel buffers

转载 作者:行者123 更新时间:2023-12-03 17:02:48 25 4
gpt4 key购买 nike

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

所以...下面是我尝试模拟Apple的drawInRect:fromRect:operation:fraction方法来将数据传输到NSView。这两个例程通常存在于 NSImage 或 NSBitmapImageRep 类中。我忽略了 operation: 模式或 fraction: alpha 混合。

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

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

  • 情况 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;
}
}

最佳答案

#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);

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

关于cocoa - 模拟苹果的drawInRect : for offscreen pixel buffers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24724811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com