Search code examples
iosuiviewglkitviewdidappear

Why is GLKView's drawableWidth and drawableHeight not set in viewDidAppear?


I have delayed accessing view.drawableHeight until viewDidAppear, but ever so often ( one in 3 times approximately) the drawableHeight and drawableWidth are both 0. The view.frame shows correctly.

view.drawableHeight
(NSInteger) $3 = 0

view.drawableWidth
(NSInteger) $4 = 0

And this is the stack. 
[RootViewController viewDidAppear:]
[UIViewController _setViewAppearState:isAnimating:]
[UINavigationController: viewDidAppear:]

(CGRect) [ view frame ]
(CGRect) $2 = origin=(x=0, y=64) size=(width=768, height=960)

self.view.layer.frame
(CGRect) $14 = origin=(x=0, y=64) size=(width=768, height=960)

(CGRect) [((UIWindow *)[self.view window ]) frame]
(CGRect) $15 = origin=(x=0, y=0) size=(width=768, height=1024)

The window frame is taller because it includes the height of the nav bar.

It seems I could use self.view.layer.frame that should give me the dimensions that usually I would expect drawableHeight and drawableWidth to carry. But I was wondering why this behaviour is not consistent, and if it might be indicative of other problems. We are at the viewDidAppear , so one would expect that the framebuffers to be allocated and the drawableHeight and Width be set to reflect the framebuffer size.

This happens both on the xcode simulator and the ipad mini.


Solution

  • First, don't trust the simulator for anything GL/GPU-related. (Basic prototyping GL code, maybe. But for details of something you expect to ship, always check a device.)

    Drawable width and height refer to the size of the GL framebuffer managed by the view. And good drawing code on iOS doesn't allocate GPU resources until they're known to be needed... especially in GL, since many of the things you try to do with GL won't actually happen until you make a draw call. Presumably GLKView doesn't create its framebuffer until it needs to bind it, which doesn't need to happen until shortly before it calls your drawRect: / glkView:drawInRect: implementation for the first time.