Hi!
I have a scrollview containing about 100 smaller views, all the same size as the screen. My problem is that when my app wants to show the scrollview it takes about 5 seconds to create the contents of all those smaller views which makes the app freeze for 5 seconds.
To fix this I've decided to add the views to the scrollview one at a time and start with the area that's visible in the scrollview. To make this as smooth as possible I want to start a background thread that draws the contents of the view into an offscreen bitmap, when the bitmap is finished the main thread adds the view to the scrollview and the view's drawRect: method simply paints the already completed bitmap into the view.
It kinda works. Most of the time. But occasionally it fails, the offscreen drawing returns "invalid context" or it freezes completely. This is how I do the offscreen drawing:
I have removed a lot of the code in the listing above.
When it freezes I get the following traceback:
There seems to be a collision with some resource dealing with fonts. I've done a few tests and it seems that the problems only occurs when I do the offscreen drawing from an alternate thread and someone else tries to do UI drawing from the main thread at the same time. But I'm not 100% sure that's the case.
I know that all UI operations have to be done from the main thread, but this shouldn't include drawing to an offscreen bitmap, I hope.
I previously tried using the CGBitmapContextCreate() function but I couldn't get the drawing of text to work at all so I switched to using UIGraphicsBeingImageContext() instead.
Any suggestions?
I have a scrollview containing about 100 smaller views, all the same size as the screen. My problem is that when my app wants to show the scrollview it takes about 5 seconds to create the contents of all those smaller views which makes the app freeze for 5 seconds.
To fix this I've decided to add the views to the scrollview one at a time and start with the area that's visible in the scrollview. To make this as smooth as possible I want to start a background thread that draws the contents of the view into an offscreen bitmap, when the bitmap is finished the main thread adds the view to the scrollview and the view's drawRect: method simply paints the already completed bitmap into the view.
It kinda works. Most of the time. But occasionally it fails, the offscreen drawing returns "invalid context" or it freezes completely. This is how I do the offscreen drawing:
Code:
...
[self performSelectorInBackground:@selector(drawBitmap) withObject:nil];
...
- (void)drawBitmap {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int part = nextBitmapPart;
CGRect rect = CGRectMake(0, partSize.height * part, partSize.width, partSize.height);
UIGraphicsBeginImageContext(partSize);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, 0, -partSize.height * part);
[self drawPart:rect context:ctx];
bitmapImage = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();
bitmapPart = part;
[self performSelectorOnMainThread:@selector(showNextPart) withObject:nil waitUntilDone:NO];
[pool release];
}
- (void)drawPart:(CGRect)rect context:(CGContextRef)ctx {
CGContextSetFillColorWithColor(ctx, cgBgColor);
CGContextFillRect(ctx, rect);
...
for (int i = 0; i < nWords; i++) {
if (CGRectIntersectsRect(rect, words[i].textRect)) {
NSString *text = [NSString stringWithUTF8String:words[i].text];
[text drawAtPoint:words[i].textRect.origin withFont:fonts[words[i].font].font];
}
}
}
I have removed a lot of the code in the listing above.
When it freezes I get the following traceback:
Code:
#0 0x94294342 in semaphore_wait_signal_trap
#1 0x94299e06 in pthread_mutex_lock
#2 0x0193d533 in CGFontCacheLock
#3 0x0193d499 in CGGlyphLockLockGlyphBitmaps
#4 0x03f15b3f in ripc_RenderGlyphs
#5 0x03f239e4 in ripc_DrawGlyphs
#6 0x0193c2f4 in draw_glyphs
#7 0x0193bb3f in CGContextShowGlyphsWithAdvances
#8 0x026458d8 in WebCore::Font::drawGlyphs
#9 0x02645505 in WebCore::Font::drawGlyphBuffer
#10 0x0264522a in WebCore::Font::drawSimpleText
#11 0x02644ec0 in drawAtPoint
There seems to be a collision with some resource dealing with fonts. I've done a few tests and it seems that the problems only occurs when I do the offscreen drawing from an alternate thread and someone else tries to do UI drawing from the main thread at the same time. But I'm not 100% sure that's the case.
I know that all UI operations have to be done from the main thread, but this shouldn't include drawing to an offscreen bitmap, I hope.
I previously tried using the CGBitmapContextCreate() function but I couldn't get the drawing of text to work at all so I switched to using UIGraphicsBeingImageContext() instead.
Any suggestions?