Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 8b2c1ab

Browse files
authored
Merge branch 'flutter:main' into fix-toByteData
2 parents 2a14dd2 + 42689ea commit 8b2c1ab

File tree

7 files changed

+276
-91
lines changed

7 files changed

+276
-91
lines changed

display_list/display_list.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ DisplayList::DisplayList()
2525
bounds_({0, 0, 0, 0}),
2626
can_apply_group_opacity_(true) {}
2727

28-
DisplayList::DisplayList(uint8_t* ptr,
28+
DisplayList::DisplayList(DisplayListStorage&& storage,
2929
size_t byte_count,
3030
unsigned int op_count,
3131
size_t nested_byte_count,
3232
unsigned int nested_op_count,
3333
const SkRect& bounds,
3434
bool can_apply_group_opacity,
3535
sk_sp<const DlRTree> rtree)
36-
: storage_(ptr),
36+
: storage_(std::move(storage)),
3737
byte_count_(byte_count),
3838
op_count_(op_count),
3939
nested_byte_count_(nested_byte_count),

display_list/display_list.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,26 @@ class SaveLayerOptions {
215215
};
216216
};
217217

218+
// Manages a buffer allocated with malloc.
219+
class DisplayListStorage {
220+
public:
221+
DisplayListStorage() = default;
222+
DisplayListStorage(DisplayListStorage&&) = default;
223+
224+
uint8_t* get() const { return ptr_.get(); }
225+
226+
void realloc(size_t count) {
227+
ptr_.reset(static_cast<uint8_t*>(std::realloc(ptr_.release(), count)));
228+
FML_CHECK(ptr_);
229+
}
230+
231+
private:
232+
struct FreeDeleter {
233+
void operator()(uint8_t* p) { std::free(p); }
234+
};
235+
std::unique_ptr<uint8_t, FreeDeleter> ptr_;
236+
};
237+
218238
// The base class that contains a sequence of rendering operations
219239
// for dispatch to a Dispatcher. These objects must be instantiated
220240
// through an instance of DisplayListBuilder::build().
@@ -263,7 +283,7 @@ class DisplayList : public SkRefCnt {
263283
static void DisposeOps(uint8_t* ptr, uint8_t* end);
264284

265285
private:
266-
DisplayList(uint8_t* ptr,
286+
DisplayList(DisplayListStorage&& ptr,
267287
size_t byte_count,
268288
unsigned int op_count,
269289
size_t nested_byte_count,
@@ -272,10 +292,7 @@ class DisplayList : public SkRefCnt {
272292
bool can_apply_group_opacity,
273293
sk_sp<const DlRTree> rtree);
274294

275-
struct SkFreeDeleter {
276-
void operator()(uint8_t* p) { sk_free(p); }
277-
};
278-
std::unique_ptr<uint8_t, SkFreeDeleter> storage_;
295+
DisplayListStorage storage_;
279296
size_t byte_count_;
280297
unsigned int op_count_;
281298

display_list/display_list_builder.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
6161
nested_bytes_ = nested_op_count_ = 0;
6262
storage_.realloc(bytes);
6363
bool compatible = layer_stack_.back().is_group_opacity_compatible();
64-
return sk_sp<DisplayList>(new DisplayList(storage_.release(), bytes, count,
64+
return sk_sp<DisplayList>(new DisplayList(std::move(storage_), bytes, count,
6565
nested_bytes, nested_count,
6666
bounds(), compatible, rtree()));
6767
}

display_list/display_list_builder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ class DisplayListBuilder final : public virtual Dispatcher,
362362
private:
363363
void checkForDeferredSave();
364364

365-
SkAutoTMalloc<uint8_t> storage_;
365+
DisplayListStorage storage_;
366366
size_t used_ = 0;
367367
size_t allocated_ = 0;
368368
int op_count_ = 0;

shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm

Lines changed: 112 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -211,114 +211,144 @@ - (instancetype)initWithData:(NSMutableData*)data {
211211
}
212212

213213
- (void)writeByte:(UInt8)value {
214-
[_data appendBytes:&value length:1];
214+
FlutterStandardCodecHelperWriteByte((__bridge CFMutableDataRef)_data, value);
215215
}
216216

217217
- (void)writeBytes:(const void*)bytes length:(NSUInteger)length {
218-
[_data appendBytes:bytes length:length];
218+
FlutterStandardCodecHelperWriteBytes((__bridge CFMutableDataRef)_data, bytes, length);
219219
}
220220

221221
- (void)writeData:(NSData*)data {
222-
[_data appendData:data];
222+
FlutterStandardCodecHelperWriteData((__bridge CFMutableDataRef)_data, (__bridge CFDataRef)data);
223223
}
224224

225225
- (void)writeSize:(UInt32)size {
226-
if (size < 254) {
227-
[self writeByte:(UInt8)size];
228-
} else if (size <= 0xffff) {
229-
[self writeByte:254];
230-
UInt16 value = (UInt16)size;
231-
[self writeBytes:&value length:2];
232-
} else {
233-
[self writeByte:255];
234-
[self writeBytes:&size length:4];
235-
}
226+
FlutterStandardCodecHelperWriteSize((__bridge CFMutableDataRef)_data, size);
236227
}
237228

238229
- (void)writeAlignment:(UInt8)alignment {
239-
UInt8 mod = _data.length % alignment;
240-
if (mod) {
241-
for (int i = 0; i < (alignment - mod); i++) {
242-
[self writeByte:0];
243-
}
244-
}
230+
FlutterStandardCodecHelperWriteAlignment((__bridge CFMutableDataRef)_data, alignment);
245231
}
246232

247233
- (void)writeUTF8:(NSString*)value {
248-
UInt32 length = [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
249-
[self writeSize:length];
250-
[self writeBytes:value.UTF8String length:length];
234+
FlutterStandardCodecHelperWriteUTF8((__bridge CFMutableDataRef)_data,
235+
(__bridge CFStringRef)value);
251236
}
252237

253-
- (void)writeValue:(id)value {
254-
if (value == nil || value == [NSNull null]) {
255-
[self writeByte:FlutterStandardFieldNil];
238+
static FlutterStandardCodecObjcType GetWriteType(id value) {
239+
if (value == nil || (__bridge CFNullRef)value == kCFNull) {
240+
return FlutterStandardCodecObjcTypeNil;
256241
} else if ([value isKindOfClass:[NSNumber class]]) {
257-
CFNumberRef number = (__bridge CFNumberRef)value;
258-
BOOL success = NO;
259-
if (CFGetTypeID(number) == CFBooleanGetTypeID()) {
260-
BOOL b = CFBooleanGetValue((CFBooleanRef)number);
261-
[self writeByte:(b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse)];
262-
success = YES;
263-
} else if (CFNumberIsFloatType(number)) {
264-
Float64 f;
265-
success = CFNumberGetValue(number, kCFNumberFloat64Type, &f);
266-
if (success) {
267-
[self writeByte:FlutterStandardFieldFloat64];
268-
[self writeAlignment:8];
269-
[self writeBytes:(UInt8*)&f length:8];
270-
}
271-
} else if (CFNumberGetByteSize(number) <= 4) {
272-
SInt32 n;
273-
success = CFNumberGetValue(number, kCFNumberSInt32Type, &n);
274-
if (success) {
275-
[self writeByte:FlutterStandardFieldInt32];
276-
[self writeBytes:(UInt8*)&n length:4];
277-
}
278-
} else if (CFNumberGetByteSize(number) <= 8) {
279-
SInt64 n;
280-
success = CFNumberGetValue(number, kCFNumberSInt64Type, &n);
281-
if (success) {
282-
[self writeByte:FlutterStandardFieldInt64];
283-
[self writeBytes:(UInt8*)&n length:8];
284-
}
285-
}
286-
if (!success) {
287-
NSLog(@"Unsupported value: %@ of number type %ld", value, CFNumberGetType(number));
288-
NSAssert(NO, @"Unsupported value for standard codec");
289-
}
242+
return FlutterStandardCodecObjcTypeNSNumber;
290243
} else if ([value isKindOfClass:[NSString class]]) {
291-
NSString* string = value;
292-
[self writeByte:FlutterStandardFieldString];
293-
[self writeUTF8:string];
244+
return FlutterStandardCodecObjcTypeNSString;
294245
} else if ([value isKindOfClass:[FlutterStandardTypedData class]]) {
295-
FlutterStandardTypedData* typedData = value;
296-
[self writeByte:FlutterStandardFieldForDataType(typedData.type)];
297-
[self writeSize:typedData.elementCount];
298-
[self writeAlignment:typedData.elementSize];
299-
[self writeData:typedData.data];
246+
return FlutterStandardCodecObjcTypeFlutterStandardTypedData;
300247
} else if ([value isKindOfClass:[NSData class]]) {
301-
[self writeValue:[FlutterStandardTypedData typedDataWithBytes:value]];
248+
return FlutterStandardCodecObjcTypeNSData;
302249
} else if ([value isKindOfClass:[NSArray class]]) {
303-
NSArray* array = value;
304-
[self writeByte:FlutterStandardFieldList];
305-
[self writeSize:array.count];
306-
for (id object in array) {
307-
[self writeValue:object];
308-
}
250+
return FlutterStandardCodecObjcTypeNSArray;
309251
} else if ([value isKindOfClass:[NSDictionary class]]) {
310-
NSDictionary* dict = value;
311-
[self writeByte:FlutterStandardFieldMap];
312-
[self writeSize:dict.count];
313-
for (id key in dict) {
314-
[self writeValue:key];
315-
[self writeValue:[dict objectForKey:key]];
316-
}
252+
return FlutterStandardCodecObjcTypeNSDictionary;
317253
} else {
318-
NSLog(@"Unsupported value: %@ of type %@", value, [value class]);
319-
NSAssert(NO, @"Unsupported value for standard codec");
254+
return FlutterStandardCodecObjcTypeUnknown;
320255
}
321256
}
257+
258+
struct WriteKeyValuesInfo {
259+
CFTypeRef writer;
260+
CFMutableDataRef data;
261+
};
262+
263+
static void WriteKeyValues(CFTypeRef key, CFTypeRef value, void* context) {
264+
WriteKeyValuesInfo* info = (WriteKeyValuesInfo*)context;
265+
FastWriteValueOfType(info->writer, info->data, key);
266+
FastWriteValueOfType(info->writer, info->data, value);
267+
}
268+
269+
// Recurses into WriteValueOfType directly if it is writing a known type,
270+
// otherwise recurses with objc_msgSend.
271+
static void FastWriteValueOfType(CFTypeRef writer, CFMutableDataRef data, CFTypeRef value) {
272+
FlutterStandardCodecObjcType type = GetWriteType((__bridge id)value);
273+
if (type != FlutterStandardCodecObjcTypeUnknown) {
274+
WriteValueOfType(writer, data, type, value);
275+
} else {
276+
[(__bridge FlutterStandardWriter*)writer writeValue:(__bridge id)value];
277+
}
278+
}
279+
280+
static void WriteValueOfType(CFTypeRef writer,
281+
CFMutableDataRef data,
282+
FlutterStandardCodecObjcType type,
283+
CFTypeRef value) {
284+
switch (type) {
285+
case FlutterStandardCodecObjcTypeNil:
286+
FlutterStandardCodecHelperWriteByte(data, FlutterStandardFieldNil);
287+
break;
288+
case FlutterStandardCodecObjcTypeNSNumber: {
289+
CFNumberRef number = (CFNumberRef)value;
290+
BOOL success = FlutterStandardCodecHelperWriteNumber(data, number);
291+
if (!success) {
292+
NSLog(@"Unsupported value: %@ of number type %ld", value, CFNumberGetType(number));
293+
NSCAssert(NO, @"Unsupported value for standard codec");
294+
}
295+
break;
296+
}
297+
case FlutterStandardCodecObjcTypeNSString: {
298+
CFStringRef string = (CFStringRef)value;
299+
FlutterStandardCodecHelperWriteByte(data, FlutterStandardFieldString);
300+
FlutterStandardCodecHelperWriteUTF8(data, string);
301+
break;
302+
}
303+
case FlutterStandardCodecObjcTypeFlutterStandardTypedData: {
304+
FlutterStandardTypedData* typedData = (__bridge FlutterStandardTypedData*)value;
305+
FlutterStandardCodecHelperWriteByte(data, FlutterStandardFieldForDataType(typedData.type));
306+
FlutterStandardCodecHelperWriteSize(data, typedData.elementCount);
307+
FlutterStandardCodecHelperWriteAlignment(data, typedData.elementSize);
308+
FlutterStandardCodecHelperWriteData(data, (__bridge CFDataRef)typedData.data);
309+
break;
310+
}
311+
case FlutterStandardCodecObjcTypeNSData:
312+
WriteValueOfType(writer, data, FlutterStandardCodecObjcTypeFlutterStandardTypedData,
313+
(__bridge CFTypeRef)
314+
[FlutterStandardTypedData typedDataWithBytes:(__bridge NSData*)value]);
315+
break;
316+
case FlutterStandardCodecObjcTypeNSArray: {
317+
CFArrayRef array = (CFArrayRef)value;
318+
FlutterStandardCodecHelperWriteByte(data, FlutterStandardFieldList);
319+
CFIndex count = CFArrayGetCount(array);
320+
FlutterStandardCodecHelperWriteSize(data, count);
321+
for (CFIndex i = 0; i < count; ++i) {
322+
FastWriteValueOfType(writer, data, CFArrayGetValueAtIndex(array, i));
323+
}
324+
break;
325+
}
326+
case FlutterStandardCodecObjcTypeNSDictionary: {
327+
CFDictionaryRef dict = (CFDictionaryRef)value;
328+
FlutterStandardCodecHelperWriteByte(data, FlutterStandardFieldMap);
329+
CFIndex count = CFDictionaryGetCount(dict);
330+
FlutterStandardCodecHelperWriteSize(data, count);
331+
WriteKeyValuesInfo info = {
332+
.writer = writer,
333+
.data = data,
334+
};
335+
CFDictionaryApplyFunction(dict, WriteKeyValues, (void*)&info);
336+
break;
337+
}
338+
case FlutterStandardCodecObjcTypeUnknown: {
339+
id objc_value = (__bridge id)value;
340+
NSLog(@"Unsupported value: %@ of type %@", objc_value, [objc_value class]);
341+
NSCAssert(NO, @"Unsupported value for standard codec");
342+
break;
343+
}
344+
}
345+
}
346+
347+
- (void)writeValue:(id)value {
348+
FlutterStandardCodecObjcType type = GetWriteType(value);
349+
WriteValueOfType((__bridge CFTypeRef)self, (__bridge CFMutableDataRef)self->_data, type,
350+
(__bridge CFTypeRef)value);
351+
}
322352
@end
323353

324354
@implementation FlutterStandardReader {

0 commit comments

Comments
 (0)