首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >drawRect性能

drawRect性能
EN

Stack Overflow用户
提问于 2011-05-20 08:04:29
回答 5查看 8.6K关注 0票数 5

我需要在iPad上画很多五百万到一百万的多边形。在实验之后,我只能得到一个fps如果那样。这只是一个例子,我真正的代码有一些大小很好的多边形。

以下是几个问题:

  1. 为什么不将Quartz框架添加到我的项目中呢?
  2. 如果多个多边形重复,我能利用视图或者它们太重吗?
  3. 任何替代方案,QTPaint都可以处理这一点,但是可以使用gpu。有类似QT或ios的东西吗?
  4. Opengl能提高这种类型的2d性能吗?

示例图:

代码语言:javascript
复制
//X Y Array of boxes

- (void)drawRect:(CGRect)rect
{
    int reset = [self pan].x;
    int markX = reset;
    int markY = [self pan].y;
    CGContextRef context = UIGraphicsGetCurrentContext();
    for(int i = 0; i < 1000; i++)//1,000,000
    {
        for(int j = 0; j < 1000; j++)
        {
            CGContextMoveToPoint(context, markX,  markY);
            CGContextAddLineToPoint(context, markX, markY + 10);
            CGContextAddLineToPoint(context, markX + 10, markY + 10);
            CGContextAddLineToPoint(context, markX + 10, markY);
            CGContextAddLineToPoint(context, markX, markY);
            CGContextStrokePath(context);
            markX+=12;
        }
        markY += 12;
        markX = reset;
    }

}

平底锅只需移动方框阵列在屏幕上与潘手势。任何帮助或暗示都将不胜感激。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-08-15 19:42:29

你的例子的关键问题是它没有被优化。每当drawRect:被调用时,设备就会呈现所有的1,000,000个方块。更糟糕的是,它正在对循环中的API进行6,000,000次调用。如果您想要刷新这个视图,即使只有30 you,也就是180,000,000次调用/秒。

举个简单的例子,绘制区域的大小为12,000‘s×12,000’s;iPad显示的最大面积为768×1024 (假设全屏肖像)。因此,代码在可见区域之外浪费了大量CPU资源。UIKit有相对轻松地处理此场景的方法。

在管理明显大于可见区域的内容时,应将绘图限制在可见范围内。UIKit有几种处理这个问题的方法;UIScrollView与一个由CATiledLayer支持的视图相结合是最好的选择。

步骤:

免责声明:--这是对上面示例代码的特别优化

  • 创建新的基于视图的应用程序iPad项目
  • 添加对QuartzCore.framework的引用
  • 创建一个新类,比如MyLargeView,从UIView中子类并添加以下代码:
代码语言:javascript
复制
#import <QuartzCore/QuartzCore.h>

@implementation MyLargeView
- (void)awakeFromNib {
    CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
    tiledLayer.tileSize = CGSizeMake(512.0f, 512.0f);
}

// Set the layer's class to be CATiledLayer.
+ (Class)layerClass {
    return [CATiledLayer class];
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
    // only draws what is specified by the rect parameter

    CGContextRef context = UIGraphicsGetCurrentContext();

    // set up some constants for the objects being drawn        
    const CGFloat width  = 10.0f;           // width of rect
    const CGFloat height = 10.0f;           // height of rect
    const CGFloat xSpace = 4.0f;            // space between cells (horizontal)
    const CGFloat ySpace = 4.0f;            // space between cells (vertical)
    const CGFloat tWidth = width + xSpace;  // total width of cell
    const CGFloat tHeight = height + ySpace;// total height of cell

    CGFloat xStart = floorf(rect.origin.x / tWidth);     // first visible cell (column)
    CGFloat yStart = floorf(rect.origin.y / tHeight);    // first visible cell (row)
    CGFloat xCells = rect.size.width / tWidth + 1;       // number of horizontal visible cells
    CGFloat yCells = rect.size.height / tHeight + 1;     // number of vertical visible cells

    for(int x = xStart; x < (xStart + xCells); x++) {
        for(int y = yStart; y < (yStart + yCells); y++) {
            CGFloat xpos = x*tWidth;
            CGFloat ypos = y*tHeight;

            CGContextMoveToPoint(context, xpos,  ypos);
            CGContextAddLineToPoint(context, xpos, ypos + height);
            CGContextAddLineToPoint(context, xpos + width, ypos + height);
            CGContextAddLineToPoint(context, xpos + width, ypos);
            CGContextAddLineToPoint(context, xpos, ypos);
            CGContextStrokePath(context);
        }
    }
}


@end
  • 编辑视图控制器nib并向视图中添加一个UIScrollView
  • 将一个UIView添加到UIScrollView并确保它填充UIScrollView

  • 将类更改为MyLargeView

  • 将MyLargeView的帧大小设置为12,000×12,000

  • 最后,打开视图控制器.m文件并添加以下覆盖:
代码语言:javascript
复制
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    UIScrollView *scrollView = [self.view.subviews objectAtIndex:0];
    scrollView.contentSize = CGSizeMake(12000, 12000);
}

如果您查看drawRect:调用,它只绘制到rect参数指定的区域,它将对应于我们在awakeFromNib方法中配置的CATiledLayer的平铺大小(512×512)。这将缩放到1,000,000×1,000,000像素画布。

需要考虑的替代方案是ScrollViewSuite实例,特别是3_Tiling

票数 18
EN

Stack Overflow用户

发布于 2011-05-20 14:35:33

OpenGL是在iOS设备上加速的GPU硬件。核心图形绘制不是,而且在处理大量小图形原语(行)时可能会慢很多倍。

对于很多小方块来说,用C代码将它们写入位图比线条绘制更快。完成后,只需将位图绘制到视图一次即可。但是Open会更快。

票数 3
EN

Stack Overflow用户

发布于 2011-05-20 08:12:29

第4点,OpenGL应该做得很好。检查是否可以重用这些对象,以及是否可以将一些逻辑移到GLSL代码中。

OpenGL性能优化(在WebGL上下文中,但大多数应该适用):http://www.youtube.com/watch?v=rfQ8rKGTVlg

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6069104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档