0

I'm working on a game on iPhone, which uses C++ and OpenGL ES 1.x library. It works fine on simulator. But when I install it on real iPhone, I found out that on iPhone original, it took about 20 milliseconds to render a frame. However, it took 35~40 milliseconds to render a frame on iPhone 3GS.

I've tried various OS, including 3GS + iOS 3.1.2, 3G + iOS 4.0, 3GS + iOS 4.1, iPad + iOS 3.2. All of them render much slower than iPhone original, which sounds really ridiculous to me. I tried google for anything I can think of, fixing every problem it might be related to, but nothing changed.

I have 2 machine which these pieces of code render faster: 1) iPhone original with iOS 3.1.3, 2) iPod Touch with iOS 3.1.3. Both took about 20 milliseconds to render a frame. And 4 machine which render mysteriously slower: 1) iPhone 3G with iOS 4.0, 2) iPhone 3GS with iOS 3.1.2, 3) iPhone 3GS with iOS 4.1, 4) iPad with iOS 3.2. iPhone took about 35-40 milliseconds to render a frame and iPad took around 25.

I use PVRTC for texture, which is first cooked and make into a bundle. It uses total of ten 512x512 textures, three 1024x1024 textures. The piece of code which binding texture is as follow:

 GLenum internalFormat = 0;
 GLenum pixelType      = 0;

 // resolve type
 ResetFlags_();
 assert(2==attr.Dimension && 1==attr.Depth);
 switch (attr.Format) 
 {
 case FORMAT_PVRTC2:
  assert(attr.Width==attr.Height);
  if (attr.AlphaBits>0)
   internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  else
   internalFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  break; 
 case FORMAT_PVRTC4:
  assert(attr.Width==attr.Height);
  if (attr.AlphaBits>0)
   internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  else
   internalFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  break;

  ... other formats ...

 }

 // prepare temp buffer to load
 MemoryBuffer tmpBuffer(true);
 uint8* buffer = tmpBuffer.GetWritePtr(attr.TextureSize);

 // read data
 stream.Read(buffer, attr.TextureSize);
 if (stream.Fail())
  return false;

 // init
 width_    = attr.Width;
 height_    = attr.Height;
 LODs_    = attr.LODs;
 alphaBits_ = attr.AlphaBits;

 // create and upload texture
 glGenTextures(1, &glTexture_);
 glBindTexture(GL_TEXTURE_2D, glTexture_);

 uint32 offset = 0;
 uint32 dim    = width_; // = height
 uint32 w, h;
 switch (internalFormat)
 {
 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  for (uint32 i=0; i<LODs_; ++i) {
   assert(offset<attr.TextureSize);
   w = dim >> ((FORMAT_PVRTC2==attr.Format) ? 3:2);
   h = dim >> 2;

   // Clamp to minimum number of blocks
   if (w<2) w = 2;
   if (h<2) h = 2;

   uint32 const image_size = w * h * 8; //  8 bytes for each block
   glCompressedTexImage2D(GL_TEXTURE_2D, i, internalFormat, dim, dim, 0, image_size, buffer+offset);
   dim >>= 1;
   offset += image_size;
   break;

  ... other formats ...

 }


 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); // tri-linear?
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

 SetContext_(&glTexture_);
 return true;

Rendering part is huge because it uses an engine developed by others. As far as I can tell, it uses glDrawArrays and no shader was used.

Anyone had encounter the same problem before? I really can't see why iPhone original render much faster than iPhone 3GS.

p.s. I forgot to say. I draw only 2D rectangles with textures only. And it's around 20 rectangles in my game ( one background and one UI with 480x360 size. Others are commonly 64x64 units.)

Chengyang
  • 21
  • 6
  • Are you using particle systems? Does the engine you mention happen to be cocos2d? – Toastor Nov 05 '10 at 08:44
  • No I didn't use particle system. The engine is not cocos2D, it is an engine written in C++ which was originally on PC then ported to iPhone. – Chengyang Nov 05 '10 at 09:16

1 Answers1

1

The behaviour you are getting could be because of the possible emulation of Fixed Function Pipeline (FFP) via Programmable Pipeline (i.e. shaders).

Can you please execute a test that will load and display your textures in some way, completely without your engine.