Skip to content

Commit

Permalink
much improved drawing performance
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianEberius committed Apr 2, 2010
1 parent 5d1ca1a commit 941e8d5
Show file tree
Hide file tree
Showing 9 changed files with 837 additions and 1,078 deletions.
2 changes: 1 addition & 1 deletion AsyncBGDrawOperation.m
Expand Up @@ -75,7 +75,7 @@ - (void)partialBackgroundDraw

[image lockFocus];
[drawnPart drawInRect:partToDraw
fromRect:rectToRedraw
fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:1.0];
[image unlockFocus];

Expand Down
95 changes: 28 additions & 67 deletions AsyncDrawOperation.m
Expand Up @@ -55,11 +55,11 @@ - (void)setPartToDraw:(NSRect)part
partToDraw = part;
}

- (void)main
- (void)main
{
if ([self isCancelled])
if ([self isCancelled])
return;

switch (mode) {
case MM_COMPLETE_IMAGE:
[self makeCompleteSnapshot];
Expand All @@ -72,101 +72,62 @@ - (void)main
}
}

- (void)makePartialSnapshot
- (void)makePartialSnapshot
{
[[minimapView drawLock] lock];
NSImage* old_image = [minimapView theImage];
int gutterSize = [minimapView gutterSize];
NSRect tvBounds = NSMakeRect(gutterSize, 0,
[[minimapView textView] bounds].size.width-gutterSize,
NSRect tvBounds = NSMakeRect(gutterSize, 0,
[[minimapView textView] bounds].size.width-gutterSize,
[[minimapView textView] bounds].size.height);
NSRect bounds = [minimapView bounds];
float scaleFactor = bounds.size.width / tvBounds.size.width;
int h = tvBounds.size.height*scaleFactor;
NSRect newImageRect = NSMakeRect(0, 0, bounds.size.width, h);
NSImage* image = [[[NSImage alloc] initWithSize:newImageRect.size] autorelease];
if ([self checkCancelled])
if ([self checkCancelled])
return;
NSRect rectToRedraw = NSMakeRect(tvBounds.origin.x,
partToDraw.origin.y/scaleFactor,
NSRect rectToRedraw = NSMakeRect(tvBounds.origin.x,
partToDraw.origin.y/scaleFactor,
tvBounds.size.width,
partToDraw.size.height/scaleFactor);
NSImage* drawnPart = [[minimapView textView] snapshotByDrawingInRect:rectToRedraw];
if ([self checkCancelled])
if ([self checkCancelled])
return;

[image lockFocus];
[fillColor set];
NSRectFill(NSMakeRect(0, 0, [image size].width, [image size].height));
// new image is longer or equal
if (h >= [old_image size].height) {
[old_image drawInRect:NSMakeRect(0, 0, [image size].width, [old_image size].height)
fromRect:NSZeroRect
fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:1.0];
}
else {
[old_image drawInRect:newImageRect
fromRect:NSMakeRect(0,0, [old_image size].width, [image size].height)
fromRect:NSMakeRect(0,0, [old_image size].width, [image size].height)
operation:NSCompositeSourceOver fraction:1.0];
}

[drawnPart drawInRect:partToDraw
fromRect:rectToRedraw
fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:1.0];
[image unlockFocus];

if ([self checkCancelled])
if ([self checkCancelled])
return;
[minimapView performSelectorOnMainThread:@selector(asyncDrawFinished:) withObject:image waitUntilDone:YES];

[[minimapView drawLock] unlock];
}

<<<<<<< HEAD
=======
- (void)partialBackgroundDraw
{
[[minimapView drawLock] lock];
NSImage* image = [minimapView theImage];

if ([self checkCancelled])
return;
NSRect tvBounds = [[minimapView textView] bounds];
int gutterSize = [minimapView gutterSize];
float scaleFactor = tvBounds.size.height / [image size].height;
NSRect rectToRedraw = NSMakeRect(gutterSize,
partToDraw.origin.y*scaleFactor,
tvBounds.size.width - gutterSize,
partToDraw.size.height*scaleFactor);
NSImage* drawnPart = [[minimapView textView] snapshotByDrawingInRect:rectToRedraw];

if ([self checkCancelled])
return;

[image lockFocus];
[drawnPart drawInRect:partToDraw
fromRect:rectToRedraw
operation:NSCompositeSourceOver fraction:1.0];
[image unlockFocus];

NSRect visRect = [minimapView getVisiblePartOfMinimap];
int p1 = partToDraw.origin.y;
int p2 = partToDraw.origin.y+partToDraw.size.height;
int l1 = visRect.origin.y;
int l2 = visRect.origin.y+visRect.size.height;
if ((p1>=l1 && p1<=l2) || (p2>=l1 && p2 <= l2)) {
[minimapView performSelectorOnMainThread:@selector(minorRefresh) withObject:NULL waitUntilDone:FALSE];

}
[[minimapView drawLock] unlock];
}

>>>>>>> newesttry
- (BOOL)checkCancelled
{
if ([self isCancelled]) {
[[minimapView drawLock] unlock];
return YES;
return YES;
}
return NO;
}
Expand All @@ -179,34 +140,34 @@ - (NSRect)scaleRect:(NSRect)rect withFactor:(float)factor
- (void)makeCompleteSnapshot
{
[[minimapView drawLock] lock];
if ([self checkCancelled])
if ([self checkCancelled])
return;
NSView* textView = [minimapView textView];
NSBitmapImageRep* snapshot = [textView snapshot];
int gutterSize = [minimapView gutterSize];
NSBitmapImageRep* croppedSnapshot = [self cropImageRep:snapshot
NSBitmapImageRep* croppedSnapshot = [self cropImageRep:snapshot
ToRect:NSMakeRect(gutterSize, 0, [snapshot size].width-gutterSize, [snapshot size].height)];
if ([self checkCancelled])
if ([self checkCancelled])
return;
NSRect bounds = [minimapView bounds];
float scaleFactor = bounds.size.width / [croppedSnapshot size].width;
int h = croppedSnapshot.size.height*scaleFactor;

NSImage* image = [[[NSImage alloc] initWithSize:NSMakeRect(0, 0, bounds.size.width, h).size] autorelease];
if ([self checkCancelled])

if ([self checkCancelled])
return;
[self initializeFillColorFromTextView];


[image setFlipped:YES];
[image lockFocus];
NSRect imgRect = NSMakeRect(0, 0, bounds.size.width, h);
[croppedSnapshot drawInRect:imgRect];
[image unlockFocus];
[image setFlipped:NO];
if ([self checkCancelled])

if ([self checkCancelled])
return;
[minimapView performSelectorOnMainThread:@selector(asyncDrawFinished:) withObject:image waitUntilDone:YES];
[[minimapView drawLock] unlock];
Expand All @@ -217,8 +178,8 @@ - (void)makeCompleteSnapshot
*/
- (NSBitmapImageRep*)cropImageRep:(NSBitmapImageRep*)rep ToRect:(NSRect)rect {
CGImageRef cgImg = CGImageCreateWithImageInRect([rep CGImage], NSRectToCGRect(rect)); NSBitmapImageRep *result = [[NSBitmapImageRep alloc] initWithCGImage:cgImg];
CGImageRelease(cgImg);

CGImageRelease(cgImg);
return [result autorelease];
}

Expand Down
52 changes: 13 additions & 39 deletions BackgroundUpdater.m
Expand Up @@ -10,6 +10,7 @@
#include "math.h"
#import "MinimapView.h"
#import "AsyncBGDrawOperation.h"
#define REGION_LENGTH 200

@implementation BackgroundUpdater

Expand All @@ -19,7 +20,7 @@ - (id)initWithMinimapView:(MinimapView*)mv andOperationQueue:(NSOperationQueue*)
if (self) {
minimapView = mv;
operationQueue = opQueue;
dirtyRegions = [[NSMutableArray arrayWithCapacity:[[minimapView theImage] size].height/50] retain];
dirtyRegions = [[NSMutableArray arrayWithCapacity:[[minimapView theImage] size].height/REGION_LENGTH] retain];
}
return self;
}
Expand Down Expand Up @@ -52,38 +53,33 @@ - (void)rangeWasRedrawn:(NSValue*)range

- (void)setDirtyExceptForVisiblePart
{
[dirtyRegions removeAllObjects];
NSImage* image = [minimapView theImage];
NSRect visRect = [minimapView getVisiblePartOfMinimap];
<<<<<<< HEAD

=======

>>>>>>> newesttry
int i = visRect.origin.y+visRect.size.height;
int t = visRect.origin.y;
BOOL goUp = TRUE;
BOOL goDown = TRUE;
while (goUp || goDown) {
if (goDown) {
int length = 50;
int length = REGION_LENGTH;
if ((i+length) > [image size].height) {
length = [image size].height - i;
}
<<<<<<< HEAD
NSRange range = NSMakeRange(i, length+1);
[self setRangeDirty:range];
i=i+50;
i=i+REGION_LENGTH;
if (i>[image size].height)
goDown = FALSE;
}
if (goUp) {
int length = 50;
int length = REGION_LENGTH;
if ((t-length) < 0) {
length = t;
}
NSRange range = NSMakeRange(t, length+1);
NSRange range = NSMakeRange(t-length+1, length+1);
[self setRangeDirty:range];
t = t-50;
t = t-REGION_LENGTH;
if (t<0)
goUp = FALSE;
}
Expand All @@ -93,10 +89,12 @@ - (void)setDirtyExceptForVisiblePart
- (void)setRangeDirty:(NSRange)range
{
NSValue* val = [NSValue valueWithRange:range];
/*
for (NSValue* v in dirtyRegions)
if ([v isEqualToValue:val]) {
return;
}
*/
[dirtyRegions addObject:val];
}

Expand All @@ -107,40 +105,16 @@ - (void)addDirtyRegions:(NSArray *)regions

- (void)setCompleteImageDirty
{
[dirtyRegions removeAllObjects];
NSImage* image = [minimapView theImage];
int i;
for (i=0;i<[image size].height;i=i+50) {
int length = 50;
for (i=0;i<[image size].height;i=i+REGION_LENGTH) {
int length = REGION_LENGTH;
if ((i+length) > [image size].height) {
length = [image size].height - i;
}
NSRange range = NSMakeRange(i-1,length+1);
[dirtyRegions addObject:[NSValue valueWithRange:range]];
=======

NSRect rectToDraw = NSMakeRect(visRect.origin.x, i-1, visRect.size.width, length+1);
AsyncDrawOperation* op = [[[AsyncDrawOperation alloc] initWithMinimapView:minimapView andMode:MM_BACKGROUND_DRAW] autorelease];
[op setPartToDraw:rectToDraw];
[operationQueue addOperation:op];
i=i+50;
if (i>[image size].height)
goDown = FALSE;
}
if (goUp) {
int length = 50;
if ((t-length) < 0) {
length = t;
}

NSRect rectToDraw = NSMakeRect(visRect.origin.x, t-length-1, visRect.size.width, length+1);
AsyncDrawOperation* op = [[[AsyncDrawOperation alloc] initWithMinimapView:minimapView andMode:MM_BACKGROUND_DRAW] autorelease];
[op setPartToDraw:rectToDraw];
[operationQueue addOperation:op];
t = t-50;
if (t<0)
goUp = FALSE;
}
>>>>>>> newesttry
}
}
@end
14 changes: 4 additions & 10 deletions MinimapView.h
Expand Up @@ -21,13 +21,11 @@ extern int const scaleDownTo;
NSTimer* timer;
NSLock* drawLock;
BackgroundUpdater* updater;

<<<<<<< HEAD

float lastScrollPosition;

NSRange viewableRange;
float visRectPosBeforeScrolling;
=======
float scrollDiffToTextView;
NSRange viewableRange;
>>>>>>> newesttry
NSRect visiblePartOfImage;
Boolean refreshAll;
Boolean minimapIsScrollable;
Expand All @@ -50,11 +48,7 @@ extern int const scaleDownTo;
#pragma mark public-api
- (void)refreshDisplay;
- (void)refreshViewableRange;
<<<<<<< HEAD
- (void)smallRefresh;
=======
- (void)minorRefresh;
>>>>>>> newesttry
- (int)gutterSize;
- (void)updateGutterSize;
- (void)setNewDocument;
Expand Down

0 comments on commit 941e8d5

Please sign in to comment.