forked from TextureGroup/Texture
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NoCopyRendering] Use vm instead of malloc (TextureGroup#833)
* [Contexts] Use mmap directly for possible perf gain and to tag the memory as CGImage * Wrap the mmap in an object * Go straight to dataprovider * Tweak it * Remove wrong comment * Finish that comment * Address warnings
- Loading branch information
1 parent
7d32dad
commit 9bf00e4
Showing
6 changed files
with
147 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// | ||
// ASCGImageBuffer.h | ||
// Texture | ||
// | ||
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
#import <AsyncDisplayKit/ASBaseDefines.h> | ||
#import <CoreGraphics/CGDataProvider.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
AS_SUBCLASSING_RESTRICTED | ||
@interface ASCGImageBuffer : NSObject | ||
|
||
- (instancetype)initWithLength:(NSUInteger)length; | ||
|
||
@property (readonly) void *mutableBytes NS_RETURNS_INNER_POINTER; | ||
|
||
/// Don't do any drawing or call any methods after calling this. | ||
- (CGDataProviderRef)createDataProviderAndInvalidate; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// | ||
// ASCGImageBuffer.m | ||
// Texture | ||
// | ||
// Copyright (c) 2018-present, Pinterest, Inc. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
|
||
#import "ASCGImageBuffer.h" | ||
|
||
#import <sys/mman.h> | ||
#import <mach/mach_init.h> | ||
#import <mach/vm_map.h> | ||
#import <mach/vm_statistics.h> | ||
|
||
/** | ||
* The behavior of this class is modeled on the private function | ||
* _CGDataProviderCreateWithCopyOfData, which is the function used | ||
* by CGBitmapContextCreateImage. | ||
* | ||
* If the buffer is larger than a page, we use mmap and mark it as | ||
* read-only when they are finished drawing. Then we wrap the VM | ||
* in an NSData | ||
*/ | ||
@implementation ASCGImageBuffer { | ||
BOOL _createdData; | ||
BOOL _isVM; | ||
NSUInteger _length; | ||
} | ||
|
||
- (instancetype)initWithLength:(NSUInteger)length | ||
{ | ||
if (self = [super init]) { | ||
_length = length; | ||
_isVM = NO;//(length >= vm_page_size); | ||
if (_isVM) { | ||
_mutableBytes = mmap(NULL, length, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, VM_MAKE_TAG(VM_MEMORY_COREGRAPHICS_DATA), 0); | ||
if (_mutableBytes == MAP_FAILED) { | ||
NSAssert(NO, @"Failed to map for CG image data."); | ||
_isVM = NO; | ||
} | ||
} | ||
|
||
// Check the VM flag again because we may have failed above. | ||
if (!_isVM) { | ||
_mutableBytes = malloc(length); | ||
} | ||
} | ||
return self; | ||
} | ||
|
||
- (void)dealloc | ||
{ | ||
if (!_createdData) { | ||
[ASCGImageBuffer deallocateBuffer:_mutableBytes length:_length isVM:_isVM]; | ||
} | ||
} | ||
|
||
- (CGDataProviderRef)createDataProviderAndInvalidate | ||
{ | ||
NSAssert(!_createdData, @"Should not create data provider from buffer multiple times."); | ||
_createdData = YES; | ||
|
||
// Mark the pages as read-only. | ||
if (_isVM) { | ||
__unused kern_return_t result = vm_protect(mach_task_self(), (vm_address_t)_mutableBytes, _length, true, VM_PROT_READ); | ||
NSAssert(result == noErr, @"Error marking buffer as read-only: %@", [NSError errorWithDomain:NSMachErrorDomain code:result userInfo:nil]); | ||
} | ||
|
||
// Wrap in an NSData | ||
BOOL isVM = _isVM; | ||
NSData *d = [[NSData alloc] initWithBytesNoCopy:_mutableBytes length:_length deallocator:^(void * _Nonnull bytes, NSUInteger length) { | ||
[ASCGImageBuffer deallocateBuffer:bytes length:length isVM:isVM]; | ||
}]; | ||
return CGDataProviderCreateWithCFData((__bridge CFDataRef)d); | ||
} | ||
|
||
+ (void)deallocateBuffer:(void *)buf length:(NSUInteger)length isVM:(BOOL)isVM | ||
{ | ||
if (isVM) { | ||
__unused kern_return_t result = vm_deallocate(mach_task_self(), (vm_address_t)buf, length); | ||
NSAssert(result == noErr, @"Failed to unmap cg image buffer: %@", [NSError errorWithDomain:NSMachErrorDomain code:result userInfo:nil]); | ||
} else { | ||
free(buf); | ||
} | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters