mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
use libc memcpy/memmove instead of std.mem if available
This commit is contained in:
@ -19,6 +19,7 @@ const std = @import("std");
|
|||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
const fastmem = @import("fastmem.zig");
|
||||||
|
|
||||||
/// Data is the raw texture data.
|
/// Data is the raw texture data.
|
||||||
data: []u8,
|
data: []u8,
|
||||||
@ -233,7 +234,7 @@ pub fn set(self: *Atlas, reg: Region, data: []const u8) void {
|
|||||||
while (i < reg.height) : (i += 1) {
|
while (i < reg.height) : (i += 1) {
|
||||||
const tex_offset = (((reg.y + i) * self.size) + reg.x) * depth;
|
const tex_offset = (((reg.y + i) * self.size) + reg.x) * depth;
|
||||||
const data_offset = i * reg.width * depth;
|
const data_offset = i * reg.width * depth;
|
||||||
std.mem.copy(
|
fastmem.copy(
|
||||||
u8,
|
u8,
|
||||||
self.data[tex_offset..],
|
self.data[tex_offset..],
|
||||||
data[data_offset .. data_offset + (reg.width * depth)],
|
data[data_offset .. data_offset + (reg.width * depth)],
|
||||||
|
26
src/fastmem.zig
Normal file
26
src/fastmem.zig
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
|
/// Same as std.mem.copy but prefers libc memmove if it is available
|
||||||
|
/// because it is generally much faster.
|
||||||
|
pub inline fn move(comptime T: type, dest: []T, source: []const T) void {
|
||||||
|
if (builtin.link_libc) {
|
||||||
|
_ = memmove(dest.ptr, source.ptr, source.len * @sizeOf(T));
|
||||||
|
} else {
|
||||||
|
std.mem.copy(T, dest, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Same as std.mem.copy but prefers libc memcpy if it is available
|
||||||
|
/// because it is generally much faster.
|
||||||
|
pub inline fn copy(comptime T: type, dest: []T, source: []const T) void {
|
||||||
|
if (builtin.link_libc) {
|
||||||
|
_ = memcpy(dest.ptr, source.ptr, source.len * @sizeOf(T));
|
||||||
|
} else {
|
||||||
|
std.mem.copy(T, dest, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "c" fn memcpy(*anyopaque, *const anyopaque, usize) *anyopaque;
|
||||||
|
extern "c" fn memmove(*anyopaque, *const anyopaque, usize) *anyopaque;
|
@ -18,6 +18,7 @@ const Glyph = font.Glyph;
|
|||||||
const Library = font.Library;
|
const Library = font.Library;
|
||||||
const Presentation = font.Presentation;
|
const Presentation = font.Presentation;
|
||||||
const convert = @import("freetype_convert.zig");
|
const convert = @import("freetype_convert.zig");
|
||||||
|
const fastmem = @import("../../fastmem.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.font_face);
|
const log = std.log.scoped(.font_face);
|
||||||
|
|
||||||
@ -248,7 +249,7 @@ pub const Face = struct {
|
|||||||
var src_ptr = bitmap.buffer;
|
var src_ptr = bitmap.buffer;
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < bitmap.rows) : (i += 1) {
|
while (i < bitmap.rows) : (i += 1) {
|
||||||
std.mem.copy(u8, dst_ptr, src_ptr[0 .. bitmap.width * depth]);
|
fastmem.copy(u8, dst_ptr, src_ptr[0 .. bitmap.width * depth]);
|
||||||
dst_ptr = dst_ptr[tgt_w * depth ..];
|
dst_ptr = dst_ptr[tgt_w * depth ..];
|
||||||
src_ptr += @intCast(usize, bitmap.pitch);
|
src_ptr += @intCast(usize, bitmap.pitch);
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ const color = @import("color.zig");
|
|||||||
const point = @import("point.zig");
|
const point = @import("point.zig");
|
||||||
const CircBuf = @import("circ_buf.zig").CircBuf;
|
const CircBuf = @import("circ_buf.zig").CircBuf;
|
||||||
const Selection = @import("Selection.zig");
|
const Selection = @import("Selection.zig");
|
||||||
|
const fastmem = @import("../fastmem.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.screen);
|
const log = std.log.scoped(.screen);
|
||||||
|
|
||||||
@ -400,7 +401,7 @@ pub const Row = struct {
|
|||||||
// If the source has no graphemes (likely) then this is fast.
|
// If the source has no graphemes (likely) then this is fast.
|
||||||
const end = @min(src.storage.len, self.storage.len);
|
const end = @min(src.storage.len, self.storage.len);
|
||||||
if (!src.storage[0].header.flags.grapheme) {
|
if (!src.storage[0].header.flags.grapheme) {
|
||||||
std.mem.copy(StorageCell, self.storage[1..], src.storage[1..end]);
|
fastmem.copy(StorageCell, self.storage[1..], src.storage[1..end]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,7 +643,7 @@ pub const GraphemeData = union(enum) {
|
|||||||
.three => |v| self.* = .{ .four = .{ v[0], v[1], v[2], cp } },
|
.three => |v| self.* = .{ .four = .{ v[0], v[1], v[2], cp } },
|
||||||
.four => |v| {
|
.four => |v| {
|
||||||
const many = try alloc.alloc(u21, 5);
|
const many = try alloc.alloc(u21, 5);
|
||||||
std.mem.copy(u21, many, &v);
|
fastmem.copy(u21, many, &v);
|
||||||
many[4] = cp;
|
many[4] = cp;
|
||||||
self.* = .{ .many = many };
|
self.* = .{ .many = many };
|
||||||
},
|
},
|
||||||
@ -898,7 +899,7 @@ pub fn scrollRegionUp(self: *Screen, top: RowIndex, bottom: RowIndex, count: usi
|
|||||||
const src_offset = count * (self.cols + 1);
|
const src_offset = count * (self.cols + 1);
|
||||||
const src = buf[src_offset..];
|
const src = buf[src_offset..];
|
||||||
assert(@ptrToInt(dst.ptr) < @ptrToInt(src.ptr));
|
assert(@ptrToInt(dst.ptr) < @ptrToInt(src.ptr));
|
||||||
std.mem.copy(StorageCell, dst, src);
|
fastmem.move(StorageCell, dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1449,7 +1450,7 @@ pub fn resize(self: *Screen, rows: usize, cols: usize) !void {
|
|||||||
|
|
||||||
// The row doesn't fit, meaning we have to soft-wrap the
|
// The row doesn't fit, meaning we have to soft-wrap the
|
||||||
// new row but probably at a diff boundary.
|
// new row but probably at a diff boundary.
|
||||||
std.mem.copy(
|
fastmem.copy(
|
||||||
StorageCell,
|
StorageCell,
|
||||||
new_row.storage[x + 1 ..],
|
new_row.storage[x + 1 ..],
|
||||||
wrapped_cells[wrapped_i .. wrapped_i + copy_len],
|
wrapped_cells[wrapped_i .. wrapped_i + copy_len],
|
||||||
|
@ -13,6 +13,7 @@ const std = @import("std");
|
|||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
const fastmem = @import("../fastmem.zig");
|
||||||
|
|
||||||
/// Unit is the type we use per tabstop unit (see file docs).
|
/// Unit is the type we use per tabstop unit (see file docs).
|
||||||
const Unit = u8;
|
const Unit = u8;
|
||||||
@ -129,7 +130,7 @@ pub fn resize(self: *Tabstops, alloc: Allocator, cols: usize) !void {
|
|||||||
// Note: we can probably try to realloc here but I'm not sure it matters.
|
// Note: we can probably try to realloc here but I'm not sure it matters.
|
||||||
const new = try alloc.alloc(Unit, size);
|
const new = try alloc.alloc(Unit, size);
|
||||||
if (self.dynamic_stops.len > 0) {
|
if (self.dynamic_stops.len > 0) {
|
||||||
std.mem.copy(Unit, new, self.dynamic_stops);
|
fastmem.copy(Unit, new, self.dynamic_stops);
|
||||||
alloc.free(self.dynamic_stops);
|
alloc.free(self.dynamic_stops);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
const trace = @import("tracy").trace;
|
||||||
|
const fastmem = @import("../fastmem.zig");
|
||||||
|
|
||||||
/// Returns a circular buffer containing type T.
|
/// Returns a circular buffer containing type T.
|
||||||
pub fn CircBuf(comptime T: type, comptime default: T) type {
|
pub fn CircBuf(comptime T: type, comptime default: T) type {
|
||||||
@ -82,13 +84,13 @@ pub fn CircBuf(comptime T: type, comptime default: T) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!self.full and self.head >= self.tail) {
|
if (!self.full and self.head >= self.tail) {
|
||||||
std.mem.copy(T, buf, self.storage[self.tail..self.head]);
|
fastmem.copy(T, buf, self.storage[self.tail..self.head]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const middle = self.storage.len - self.tail;
|
const middle = self.storage.len - self.tail;
|
||||||
std.mem.copy(T, buf, self.storage[self.tail..]);
|
fastmem.copy(T, buf, self.storage[self.tail..]);
|
||||||
std.mem.copy(T, buf[middle..], self.storage[0..self.head]);
|
fastmem.copy(T, buf[middle..], self.storage[0..self.head]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns if the buffer is currently empty. To check if its
|
/// Returns if the buffer is currently empty. To check if its
|
||||||
@ -130,6 +132,9 @@ pub fn CircBuf(comptime T: type, comptime default: T) type {
|
|||||||
/// the end of our buffer. This never "rotates" the buffer because
|
/// the end of our buffer. This never "rotates" the buffer because
|
||||||
/// the offset can only be within the size of the buffer.
|
/// the offset can only be within the size of the buffer.
|
||||||
pub fn getPtrSlice(self: *Self, offset: usize, slice_len: usize) [2][]T {
|
pub fn getPtrSlice(self: *Self, offset: usize, slice_len: usize) [2][]T {
|
||||||
|
const tracy = trace(@src());
|
||||||
|
defer tracy.end();
|
||||||
|
|
||||||
// Note: this assertion is very important, it hints the compiler
|
// Note: this assertion is very important, it hints the compiler
|
||||||
// which generates ~10% faster code than without it.
|
// which generates ~10% faster code than without it.
|
||||||
assert(offset + slice_len <= self.capacity());
|
assert(offset + slice_len <= self.capacity());
|
||||||
|
@ -14,6 +14,7 @@ const libuv = @import("libuv");
|
|||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
const tracy = @import("tracy");
|
const tracy = @import("tracy");
|
||||||
const trace = tracy.trace;
|
const trace = tracy.trace;
|
||||||
|
const fastmem = @import("../fastmem.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.io_exec);
|
const log = std.log.scoped(.io_exec);
|
||||||
|
|
||||||
@ -339,7 +340,7 @@ const EventData = struct {
|
|||||||
const req = try self.write_req_pool.get();
|
const req = try self.write_req_pool.get();
|
||||||
const buf = try self.write_buf_pool.get();
|
const buf = try self.write_buf_pool.get();
|
||||||
const end = @min(data.len, i + buf.len);
|
const end = @min(data.len, i + buf.len);
|
||||||
std.mem.copy(u8, buf, data[i..end]);
|
fastmem.copy(u8, buf, data[i..end]);
|
||||||
try self.data_stream.write(
|
try self.data_stream.write(
|
||||||
.{ .req = req },
|
.{ .req = req },
|
||||||
&[1][]u8{buf[0..(end - i)]},
|
&[1][]u8{buf[0..(end - i)]},
|
||||||
|
Reference in New Issue
Block a user