【问题标题】:CoreGraphics argb32_image_mark_rgb24 is slowCoreGraphics argb32_image_mark_rgb24 很慢
【发布时间】:2014-02-09 21:45:52
【问题描述】:

我试图弄清楚为什么 argb32_image_mark_rgb24 在 Mac FreeRDP 客户端中占用了大约 25% 的执行时间。这个函数是从 CGContextDrawImage 调用的,这是我在 drawRect 方法中调用的一个函数。 drawRect 代码如下所示:

CGContextRef cgContext = [[NSGraphicsContext currentContext] graphicsPort];
CGImageRef cgImage = CGBitmapContextCreateImage(self->bitmap_context);
CGContextClipToRect(cgContext, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));
CGContextDrawImage(cgContext, CGRectMake(0, 0, [self bounds].size.width, [self bounds].size.height), cgImage);
CGImageRelease(cgImage);

位图上下文是这样创建的:

CGContextRef mac_create_bitmap_context(rdpContext* context)
{
    CGContextRef bitmap_context;
    rdpGdi* gdi = context->gdi;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    if (gdi->dstBpp == 16)
    {
        bitmap_context = CGBitmapContextCreate(gdi->primary_buffer,
                               gdi->width, gdi->height, 5, gdi->width * 2, colorSpace,
                               kCGBitmapByteOrder16Little | kCGImageAlphaNoneSkipFirst);
    }
    else
    {
        bitmap_context = CGBitmapContextCreate(gdi->primary_buffer,
                               gdi->width, gdi->height, 8, gdi->width * 4, colorSpace,
                               kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
    }

    CGColorSpaceRelease(colorSpace);

    return bitmap_context;
}

gdi->primary_buffer 是渲染 RDP 绘图调用的软件缓冲区。目前,RDP 渲染库支持 RGB565、RGB555 和大多数 32bpp 变体。

根据我对 API 文档的理解,CGBitmapContextCreate() 创建了一个包装我的软件缓冲区的对象,但不会立即创建副本。像素的复制只会在调用 CGContextDrawImage() 时发生。

我想了解以下内容:

argb32_image_mark_rgb24 究竟是做什么的?它是否执行某种从 ARGB32 到 3 字节 RGB24 像素的转换?添加对 3 字节 RGB24 像素作为软件缓冲区格式的支持是否可以让我避免在这里发生的代价高昂的转换?

否则,我如何更改当前设置剪切矩形的调用,然后使用整个表面进行绘制以进行从源矩形复制到目标矩形的调用? CGContextDrawImage 只需要一个矩形,而不是两个。

谢谢!

【问题讨论】:

    标签: macos core-graphics rdp


    【解决方案1】:

    每帧将整个屏幕的像素从一种格式转换为另一种格式肯定会消耗一些 CPU。

    不过,我有点惊讶目标上下文是 24 位的。我已经有一段时间没有达到那个水平了,但在我的日子里,最终的屏幕通常是 32 位的,8 位只是被忽略了,但那里是为了笑。

    如果您记录深度和颜色通道以及graphicsPort 的所有通道,您会看到什么?

    你是不是在一个奇怪的窗口中?这是在什么硬件上的?

    您可以在 OpenGL 中执行一些技巧,在其中填充纹理,然后将其显示到屏幕上,但同样,您需要确保像素格式与 OpenGL 本身可以执行的操作相匹配。不过,我的理解是它可以处理一些非常时髦的格式,而且它是一条超级快速的路径。

    也许可以查看CGLTexImageIOSurface2D()IOSurfaceRef。有一些example code here

    【讨论】:

      猜你喜欢
      • 2012-04-26
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      相关资源
      最近更新 更多