mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-04-12 10:48:39 +03:00
font/sprite: replace pixman with z2d, extend Box coverage
More complete coverage of the Symbols For Legacy Computing block, including characters from Unicode 16.0. Pixman and the web canvas impl for Canvas have been removed in favor of z2d for drawing, since it has a nicer API with more powerful methods, and is in Zig with no specific platform optimizations so should compile to wasm no problem.
This commit is contained in:
16
build.zig
16
build.zig
@ -1007,10 +1007,6 @@ fn addDeps(
|
||||
.optimize = optimize,
|
||||
});
|
||||
const opengl_dep = b.dependency("opengl", .{});
|
||||
const pixman_dep = b.dependency("pixman", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
const sentry_dep = b.dependency("sentry", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
@ -1044,6 +1040,7 @@ fn addDeps(
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
const z2d_dep = b.dependency("z2d", .{});
|
||||
|
||||
// Wasm we do manually since it is such a different build.
|
||||
if (step.rootModuleTarget().cpu.arch == .wasm32) {
|
||||
@ -1125,12 +1122,16 @@ fn addDeps(
|
||||
step.root_module.addImport("spirv_cross", spirv_cross_dep.module("spirv_cross"));
|
||||
step.root_module.addImport("xev", libxev_dep.module("xev"));
|
||||
step.root_module.addImport("opengl", opengl_dep.module("opengl"));
|
||||
step.root_module.addImport("pixman", pixman_dep.module("pixman"));
|
||||
step.root_module.addImport("sentry", sentry_dep.module("sentry"));
|
||||
step.root_module.addImport("ziglyph", ziglyph_dep.module("ziglyph"));
|
||||
step.root_module.addImport("vaxis", vaxis_dep.module("vaxis"));
|
||||
step.root_module.addImport("wuffs", wuffs_dep.module("wuffs"));
|
||||
step.root_module.addImport("zf", zf_dep.module("zf"));
|
||||
step.root_module.addImport("z2d", b.addModule("z2d", .{
|
||||
.root_source_file = z2d_dep.path("src/z2d.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}));
|
||||
|
||||
// Mac Stuff
|
||||
if (step.rootModuleTarget().isDarwin()) {
|
||||
@ -1196,7 +1197,6 @@ fn addDeps(
|
||||
step.linkSystemLibrary2("freetype2", dynamic_link_opts);
|
||||
step.linkSystemLibrary2("libpng", dynamic_link_opts);
|
||||
step.linkSystemLibrary2("oniguruma", dynamic_link_opts);
|
||||
step.linkSystemLibrary2("pixman-1", dynamic_link_opts);
|
||||
step.linkSystemLibrary2("zlib", dynamic_link_opts);
|
||||
|
||||
if (config.font_backend.hasFontconfig()) {
|
||||
@ -1222,10 +1222,6 @@ fn addDeps(
|
||||
step.linkLibrary(freetype_dep.artifact("freetype"));
|
||||
try static_libs.append(freetype_dep.artifact("freetype").getEmittedBin());
|
||||
|
||||
// Pixman
|
||||
step.linkLibrary(pixman_dep.artifact("pixman"));
|
||||
try static_libs.append(pixman_dep.artifact("pixman").getEmittedBin());
|
||||
|
||||
// Harfbuzz
|
||||
if (config.font_backend.hasHarfbuzz()) {
|
||||
step.linkLibrary(harfbuzz_dep.artifact("harfbuzz"));
|
||||
|
@ -36,7 +36,6 @@
|
||||
.macos = .{ .path = "./pkg/macos" },
|
||||
.oniguruma = .{ .path = "./pkg/oniguruma" },
|
||||
.opengl = .{ .path = "./pkg/opengl" },
|
||||
.pixman = .{ .path = "./pkg/pixman" },
|
||||
.sentry = .{ .path = "./pkg/sentry" },
|
||||
.simdutf = .{ .path = "./pkg/simdutf" },
|
||||
.utfcpp = .{ .path = "./pkg/utfcpp" },
|
||||
@ -61,5 +60,9 @@
|
||||
.url = "git+https://github.com/natecraddock/zf.git?ref=main#bb27a917c3513785c6a91f0b1c10002a5029cacc",
|
||||
.hash = "1220a74107c7f153a2f809e41c7fa7e8dbf75c91043e39fad998247804e5edac2cc8",
|
||||
},
|
||||
.z2d = .{
|
||||
.url = "git+https://github.com/vancluever/z2d?ref=main#285a796eb9c25a2389f087d008f0e60faf0b8eda",
|
||||
.hash = "12206445aa45bcf0170ace371905f705aec1d8d4f61e7dd77839c6621b8c407680a5",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -41,7 +41,6 @@
|
||||
libXi,
|
||||
libXinerama,
|
||||
libXrandr,
|
||||
pixman,
|
||||
zlib,
|
||||
alejandra,
|
||||
pandoc,
|
||||
@ -61,7 +60,6 @@
|
||||
harfbuzz
|
||||
libpng
|
||||
oniguruma
|
||||
pixman
|
||||
zlib
|
||||
|
||||
libX11
|
||||
@ -126,7 +124,6 @@ in
|
||||
harfbuzz
|
||||
libpng
|
||||
oniguruma
|
||||
pixman
|
||||
zlib
|
||||
|
||||
libX11
|
||||
|
@ -7,7 +7,6 @@
|
||||
freetype,
|
||||
harfbuzz,
|
||||
libpng,
|
||||
pixman,
|
||||
zlib,
|
||||
libGL,
|
||||
libX11,
|
||||
@ -133,7 +132,6 @@ in
|
||||
freetype
|
||||
harfbuzz
|
||||
libpng
|
||||
pixman
|
||||
zlib
|
||||
|
||||
libX11
|
||||
|
@ -1,122 +0,0 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const module = b.addModule("pixman", .{ .root_source_file = b.path("main.zig") });
|
||||
|
||||
const upstream = b.dependency("pixman", .{});
|
||||
const lib = b.addStaticLibrary(.{
|
||||
.name = "pixman",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
lib.linkLibC();
|
||||
if (target.result.os.tag != .windows) {
|
||||
lib.linkSystemLibrary("pthread");
|
||||
}
|
||||
if (target.result.isDarwin()) {
|
||||
const apple_sdk = @import("apple_sdk");
|
||||
try apple_sdk.addPaths(b, &lib.root_module);
|
||||
}
|
||||
|
||||
lib.addIncludePath(upstream.path(""));
|
||||
lib.addIncludePath(b.path(""));
|
||||
module.addIncludePath(upstream.path("pixman"));
|
||||
module.addIncludePath(b.path(""));
|
||||
|
||||
var flags = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer flags.deinit();
|
||||
try flags.appendSlice(&.{
|
||||
"-DHAVE_SIGACTION=1",
|
||||
"-DHAVE_ALARM=1",
|
||||
"-DHAVE_MPROTECT=1",
|
||||
"-DHAVE_GETPAGESIZE=1",
|
||||
"-DHAVE_MMAP=1",
|
||||
"-DHAVE_GETISAX=1",
|
||||
"-DHAVE_GETTIMEOFDAY=1",
|
||||
|
||||
"-DHAVE_FENV_H=1",
|
||||
"-DHAVE_SYS_MMAN_H=1",
|
||||
"-DHAVE_UNISTD_H=1",
|
||||
|
||||
"-DSIZEOF_LONG=8",
|
||||
"-DPACKAGE=foo",
|
||||
|
||||
// There is ubsan
|
||||
"-fno-sanitize=undefined",
|
||||
"-fno-sanitize-trap=undefined",
|
||||
});
|
||||
if (!(target.result.os.tag == .windows)) {
|
||||
try flags.appendSlice(&.{
|
||||
"-DHAVE_PTHREADS=1",
|
||||
|
||||
"-DHAVE_POSIX_MEMALIGN=1",
|
||||
});
|
||||
}
|
||||
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path(""),
|
||||
.files = srcs,
|
||||
.flags = flags.items,
|
||||
});
|
||||
|
||||
lib.installHeader(b.path("pixman-version.h"), "pixman-version.h");
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path("pixman"),
|
||||
"",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
|
||||
b.installArtifact(lib);
|
||||
|
||||
if (target.query.isNative()) {
|
||||
const test_exe = b.addTest(.{
|
||||
.name = "test",
|
||||
.root_source_file = b.path("main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
test_exe.linkLibrary(lib);
|
||||
var it = module.import_table.iterator();
|
||||
while (it.next()) |entry| test_exe.root_module.addImport(entry.key_ptr.*, entry.value_ptr.*);
|
||||
|
||||
const tests_run = b.addRunArtifact(test_exe);
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&tests_run.step);
|
||||
}
|
||||
}
|
||||
|
||||
const srcs: []const []const u8 = &.{
|
||||
"pixman/pixman.c",
|
||||
"pixman/pixman-access.c",
|
||||
"pixman/pixman-access-accessors.c",
|
||||
"pixman/pixman-bits-image.c",
|
||||
"pixman/pixman-combine32.c",
|
||||
"pixman/pixman-combine-float.c",
|
||||
"pixman/pixman-conical-gradient.c",
|
||||
"pixman/pixman-filter.c",
|
||||
"pixman/pixman-x86.c",
|
||||
"pixman/pixman-mips.c",
|
||||
"pixman/pixman-arm.c",
|
||||
"pixman/pixman-ppc.c",
|
||||
"pixman/pixman-edge.c",
|
||||
"pixman/pixman-edge-accessors.c",
|
||||
"pixman/pixman-fast-path.c",
|
||||
"pixman/pixman-glyph.c",
|
||||
"pixman/pixman-general.c",
|
||||
"pixman/pixman-gradient-walker.c",
|
||||
"pixman/pixman-image.c",
|
||||
"pixman/pixman-implementation.c",
|
||||
"pixman/pixman-linear-gradient.c",
|
||||
"pixman/pixman-matrix.c",
|
||||
"pixman/pixman-noop.c",
|
||||
"pixman/pixman-radial-gradient.c",
|
||||
"pixman/pixman-region16.c",
|
||||
"pixman/pixman-region32.c",
|
||||
"pixman/pixman-solid-fill.c",
|
||||
//"pixman/pixman-timer.c",
|
||||
"pixman/pixman-trap.c",
|
||||
"pixman/pixman-utils.c",
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
.{
|
||||
.name = "pixman",
|
||||
.version = "0.42.2",
|
||||
.paths = .{""},
|
||||
.dependencies = .{
|
||||
.pixman = .{
|
||||
.url = "https://deps.files.ghostty.dev/pixman-pixman-0.42.2.tar.gz",
|
||||
.hash = "12209b9206f9a5d31ccd9a2312cc72cb9dfc3e034aee1883c549dc1d753fae457230",
|
||||
},
|
||||
|
||||
.apple_sdk = .{ .path = "../apple-sdk" },
|
||||
},
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
pub const c = @cImport({
|
||||
@cInclude("pixman.h");
|
||||
});
|
@ -1,4 +0,0 @@
|
||||
pub const Error = error{
|
||||
// Pixman doesn't really have errors so we just have a single error.
|
||||
PixmanFailure,
|
||||
};
|
@ -1,118 +0,0 @@
|
||||
const std = @import("std");
|
||||
const c = @import("c.zig").c;
|
||||
const pixman = @import("main.zig");
|
||||
|
||||
pub const FormatCode = enum(c_uint) {
|
||||
// 128bpp formats
|
||||
rgba_float = c.PIXMAN_FORMAT_BYTE(128, c.PIXMAN_TYPE_RGBA_FLOAT, 32, 32, 32, 32),
|
||||
|
||||
// 96bpp formats
|
||||
rgb_float = c.PIXMAN_FORMAT_BYTE(96, c.PIXMAN_TYPE_RGBA_FLOAT, 0, 32, 32, 32),
|
||||
|
||||
// 32bpp formats
|
||||
a8r8g8b8 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ARGB, 8, 8, 8, 8),
|
||||
x8r8g8b8 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ARGB, 0, 8, 8, 8),
|
||||
a8b8g8r8 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ABGR, 8, 8, 8, 8),
|
||||
x8b8g8r8 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ABGR, 0, 8, 8, 8),
|
||||
b8g8r8a8 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_BGRA, 8, 8, 8, 8),
|
||||
b8g8r8x8 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_BGRA, 0, 8, 8, 8),
|
||||
r8g8b8a8 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_RGBA, 8, 8, 8, 8),
|
||||
r8g8b8x8 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_RGBA, 0, 8, 8, 8),
|
||||
x14r6g6b6 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ARGB, 0, 6, 6, 6),
|
||||
x2r10g10b10 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ARGB, 0, 10, 10, 10),
|
||||
a2r10g10b10 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ARGB, 2, 10, 10, 10),
|
||||
x2b10g10r10 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ABGR, 0, 10, 10, 10),
|
||||
a2b10g10r10 = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ABGR, 2, 10, 10, 10),
|
||||
|
||||
// sRGB formats
|
||||
a8r8g8b8_sRGB = c.PIXMAN_FORMAT(32, c.PIXMAN_TYPE_ARGB_SRGB, 8, 8, 8, 8),
|
||||
r8g8b8_sRGB = c.PIXMAN_FORMAT(24, c.PIXMAN_TYPE_ARGB_SRGB, 0, 8, 8, 8),
|
||||
|
||||
// 24bpp formats
|
||||
r8g8b8 = c.PIXMAN_FORMAT(24, c.PIXMAN_TYPE_ARGB, 0, 8, 8, 8),
|
||||
b8g8r8 = c.PIXMAN_FORMAT(24, c.PIXMAN_TYPE_ABGR, 0, 8, 8, 8),
|
||||
|
||||
// 16bpp formats
|
||||
r5g6b5 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ARGB, 0, 5, 6, 5),
|
||||
b5g6r5 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ABGR, 0, 5, 6, 5),
|
||||
|
||||
a1r5g5b5 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ARGB, 1, 5, 5, 5),
|
||||
x1r5g5b5 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ARGB, 0, 5, 5, 5),
|
||||
a1b5g5r5 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ABGR, 1, 5, 5, 5),
|
||||
x1b5g5r5 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ABGR, 0, 5, 5, 5),
|
||||
a4r4g4b4 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ARGB, 4, 4, 4, 4),
|
||||
x4r4g4b4 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ARGB, 0, 4, 4, 4),
|
||||
a4b4g4r4 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ABGR, 4, 4, 4, 4),
|
||||
x4b4g4r4 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_ABGR, 0, 4, 4, 4),
|
||||
|
||||
// 8bpp formats
|
||||
a8 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_A, 8, 0, 0, 0),
|
||||
r3g3b2 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_ARGB, 0, 3, 3, 2),
|
||||
b2g3r3 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_ABGR, 0, 3, 3, 2),
|
||||
a2r2g2b2 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_ARGB, 2, 2, 2, 2),
|
||||
a2b2g2r2 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_ABGR, 2, 2, 2, 2),
|
||||
|
||||
c8 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_COLOR, 0, 0, 0, 0),
|
||||
g8 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_GRAY, 0, 0, 0, 0),
|
||||
|
||||
x4a4 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_A, 4, 0, 0, 0),
|
||||
|
||||
// c8/g8 equivalent
|
||||
// x4c4 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_COLOR, 0, 0, 0, 0),
|
||||
// x4g4 = c.PIXMAN_FORMAT(8, c.PIXMAN_TYPE_GRAY, 0, 0, 0, 0),
|
||||
|
||||
// 4bpp formats
|
||||
a4 = c.PIXMAN_FORMAT(4, c.PIXMAN_TYPE_A, 4, 0, 0, 0),
|
||||
r1g2b1 = c.PIXMAN_FORMAT(4, c.PIXMAN_TYPE_ARGB, 0, 1, 2, 1),
|
||||
b1g2r1 = c.PIXMAN_FORMAT(4, c.PIXMAN_TYPE_ABGR, 0, 1, 2, 1),
|
||||
a1r1g1b1 = c.PIXMAN_FORMAT(4, c.PIXMAN_TYPE_ARGB, 1, 1, 1, 1),
|
||||
a1b1g1r1 = c.PIXMAN_FORMAT(4, c.PIXMAN_TYPE_ABGR, 1, 1, 1, 1),
|
||||
|
||||
c4 = c.PIXMAN_FORMAT(4, c.PIXMAN_TYPE_COLOR, 0, 0, 0, 0),
|
||||
g4 = c.PIXMAN_FORMAT(4, c.PIXMAN_TYPE_GRAY, 0, 0, 0, 0),
|
||||
|
||||
// 1bpp formats
|
||||
a1 = c.PIXMAN_FORMAT(1, c.PIXMAN_TYPE_A, 1, 0, 0, 0),
|
||||
|
||||
g1 = c.PIXMAN_FORMAT(1, c.PIXMAN_TYPE_GRAY, 0, 0, 0, 0),
|
||||
|
||||
// YUV formats
|
||||
yuy2 = c.PIXMAN_FORMAT(16, c.PIXMAN_TYPE_YUY2, 0, 0, 0, 0),
|
||||
yv12 = c.PIXMAN_FORMAT(12, c.PIXMAN_TYPE_YV12, 0, 0, 0, 0),
|
||||
|
||||
pub inline fn bpp(self: FormatCode) u32 {
|
||||
return self.reshift(24, 8);
|
||||
}
|
||||
|
||||
/// Calculates a valid stride for the bpp and width. Based on Cairo.
|
||||
pub fn strideForWidth(self: FormatCode, width: u32) c_int {
|
||||
const alignment = @sizeOf(u32);
|
||||
const val = @as(c_int, @intCast((self.bpp() * width + 7) / 8));
|
||||
return val + (alignment - 1) & -alignment;
|
||||
}
|
||||
|
||||
// Converted from pixman.h
|
||||
fn reshift(self: FormatCode, ofs: u5, num: u5) u32 {
|
||||
const val = @intFromEnum(self);
|
||||
const v1 = val >> ofs;
|
||||
const v2 = @as(c_uint, 1) << num;
|
||||
const v3 = @as(u5, @intCast((val >> 22) & 3));
|
||||
return ((v1 & (v2 - 1)) << v3);
|
||||
}
|
||||
};
|
||||
|
||||
test "bpp" {
|
||||
const testing = std.testing;
|
||||
|
||||
try testing.expectEqual(@as(u32, 1), FormatCode.g1.bpp());
|
||||
try testing.expectEqual(@as(u32, 4), FormatCode.g4.bpp());
|
||||
try testing.expectEqual(@as(u32, 8), FormatCode.g8.bpp());
|
||||
}
|
||||
|
||||
test "stride" {
|
||||
const testing = std.testing;
|
||||
|
||||
try testing.expectEqual(@as(c_int, 4), FormatCode.g1.strideForWidth(10));
|
||||
try testing.expectEqual(@as(c_int, 8), FormatCode.g4.strideForWidth(10));
|
||||
try testing.expectEqual(@as(c_int, 12), FormatCode.g8.strideForWidth(10));
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
const std = @import("std");
|
||||
const c = @import("c.zig").c;
|
||||
const pixman = @import("main.zig");
|
||||
|
||||
pub const Image = opaque {
|
||||
pub fn createBitsNoClear(
|
||||
format: pixman.FormatCode,
|
||||
width: c_int,
|
||||
height: c_int,
|
||||
bits: [*]u32,
|
||||
stride: c_int,
|
||||
) pixman.Error!*Image {
|
||||
return @as(?*Image, @ptrCast(c.pixman_image_create_bits_no_clear(
|
||||
@intFromEnum(format),
|
||||
width,
|
||||
height,
|
||||
bits,
|
||||
stride,
|
||||
))) orelse return pixman.Error.PixmanFailure;
|
||||
}
|
||||
|
||||
pub fn createSolidFill(
|
||||
color: pixman.Color,
|
||||
) pixman.Error!*Image {
|
||||
return @as(?*Image, @ptrCast(c.pixman_image_create_solid_fill(
|
||||
@ptrCast(&color),
|
||||
))) orelse return pixman.Error.PixmanFailure;
|
||||
}
|
||||
|
||||
pub fn unref(self: *Image) bool {
|
||||
return c.pixman_image_unref(@ptrCast(self)) == 1;
|
||||
}
|
||||
|
||||
/// A variant of getDataUnsafe that sets the length of the slice to
|
||||
/// height * stride. Its possible the buffer is larger but this is the
|
||||
/// known safe values. If you KNOW the buffer is larger you can use the
|
||||
/// unsafe variant.
|
||||
pub fn getData(self: *Image) []u32 {
|
||||
const height = self.getHeight();
|
||||
const stride = self.getStride();
|
||||
const ptr = self.getDataUnsafe();
|
||||
const len = @as(usize, @intCast(height * stride));
|
||||
return ptr[0..len];
|
||||
}
|
||||
|
||||
pub fn getDataUnsafe(self: *Image) [*]u32 {
|
||||
return c.pixman_image_get_data(@ptrCast(self));
|
||||
}
|
||||
|
||||
pub fn getHeight(self: *Image) c_int {
|
||||
return c.pixman_image_get_height(@ptrCast(self));
|
||||
}
|
||||
|
||||
pub fn getWidth(self: *Image) c_int {
|
||||
return c.pixman_image_get_width(@ptrCast(self));
|
||||
}
|
||||
|
||||
pub fn getStride(self: *Image) c_int {
|
||||
return c.pixman_image_get_stride(@ptrCast(self));
|
||||
}
|
||||
|
||||
pub fn fillBoxes(
|
||||
self: *Image,
|
||||
op: pixman.Op,
|
||||
color: pixman.Color,
|
||||
boxes: []const pixman.Box32,
|
||||
) pixman.Error!void {
|
||||
if (c.pixman_image_fill_boxes(
|
||||
@intFromEnum(op),
|
||||
@ptrCast(self),
|
||||
@ptrCast(&color),
|
||||
@intCast(boxes.len),
|
||||
@ptrCast(boxes.ptr),
|
||||
) == 0) return pixman.Error.PixmanFailure;
|
||||
}
|
||||
|
||||
pub fn fillRectangles(
|
||||
self: *Image,
|
||||
op: pixman.Op,
|
||||
color: pixman.Color,
|
||||
rects: []const pixman.Rectangle16,
|
||||
) pixman.Error!void {
|
||||
if (c.pixman_image_fill_rectangles(
|
||||
@intFromEnum(op),
|
||||
@ptrCast(self),
|
||||
@ptrCast(&color),
|
||||
@intCast(rects.len),
|
||||
@ptrCast(rects.ptr),
|
||||
) == 0) return pixman.Error.PixmanFailure;
|
||||
}
|
||||
|
||||
pub fn rasterizeTrapezoid(
|
||||
self: *Image,
|
||||
trap: pixman.Trapezoid,
|
||||
x_off: c_int,
|
||||
y_off: c_int,
|
||||
) void {
|
||||
c.pixman_rasterize_trapezoid(
|
||||
@ptrCast(self),
|
||||
@ptrCast(&trap),
|
||||
x_off,
|
||||
y_off,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn composite(
|
||||
self: *Image,
|
||||
op: pixman.Op,
|
||||
src: *Image,
|
||||
mask: ?*Image,
|
||||
src_x: i16,
|
||||
src_y: i16,
|
||||
mask_x: i16,
|
||||
mask_y: i16,
|
||||
dest_x: i16,
|
||||
dest_y: i16,
|
||||
width: u16,
|
||||
height: u16,
|
||||
) void {
|
||||
c.pixman_image_composite(
|
||||
@intFromEnum(op),
|
||||
@ptrCast(src),
|
||||
@ptrCast(mask),
|
||||
@ptrCast(self),
|
||||
src_x,
|
||||
src_y,
|
||||
mask_x,
|
||||
mask_y,
|
||||
dest_x,
|
||||
dest_y,
|
||||
width,
|
||||
height,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn compositeTriangles(
|
||||
self: *Image,
|
||||
op: pixman.Op,
|
||||
src: *Image,
|
||||
mask_format: pixman.FormatCode,
|
||||
x_src: c_int,
|
||||
y_src: c_int,
|
||||
x_dst: c_int,
|
||||
y_dst: c_int,
|
||||
tris: []const pixman.Triangle,
|
||||
) void {
|
||||
c.pixman_composite_triangles(
|
||||
@intFromEnum(op),
|
||||
@ptrCast(src),
|
||||
@ptrCast(self),
|
||||
@intFromEnum(mask_format),
|
||||
x_src,
|
||||
y_src,
|
||||
x_dst,
|
||||
y_dst,
|
||||
@intCast(tris.len),
|
||||
@ptrCast(tris.ptr),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
test "create and destroy" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
const width = 10;
|
||||
const height = 10;
|
||||
const format: pixman.FormatCode = .g1;
|
||||
const stride = format.strideForWidth(width);
|
||||
|
||||
const len = height * @as(usize, @intCast(stride));
|
||||
const data = try alloc.alloc(u32, len);
|
||||
defer alloc.free(data);
|
||||
@memset(data, 0);
|
||||
const img = try Image.createBitsNoClear(.g1, width, height, data.ptr, stride);
|
||||
try testing.expectEqual(@as(c_int, height), img.getHeight());
|
||||
try testing.expectEqual(@as(c_int, stride), img.getStride());
|
||||
try testing.expect(img.getData().len == height * stride);
|
||||
try testing.expect(img.unref());
|
||||
}
|
||||
|
||||
test "fill boxes a1" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
// Dimensions
|
||||
const width = 100;
|
||||
const height = 100;
|
||||
const format: pixman.FormatCode = .a1;
|
||||
const stride = format.strideForWidth(width);
|
||||
|
||||
// Image
|
||||
const len = height * @as(usize, @intCast(stride));
|
||||
const data = try alloc.alloc(u32, len);
|
||||
defer alloc.free(data);
|
||||
@memset(data, 0);
|
||||
const img = try Image.createBitsNoClear(format, width, height, data.ptr, stride);
|
||||
defer _ = img.unref();
|
||||
|
||||
// Fill
|
||||
const color: pixman.Color = .{ .red = 0xFFFF, .green = 0xFFFF, .blue = 0xFFFF, .alpha = 0xFFFF };
|
||||
const boxes = &[_]pixman.Box32{
|
||||
.{
|
||||
.x1 = 0,
|
||||
.y1 = 0,
|
||||
.x2 = width,
|
||||
.y2 = height,
|
||||
},
|
||||
};
|
||||
try img.fillBoxes(.src, color, boxes);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
const std = @import("std");
|
||||
const format = @import("format.zig");
|
||||
const image = @import("image.zig");
|
||||
const types = @import("types.zig");
|
||||
|
||||
pub const c = @import("c.zig").c;
|
||||
pub const Color = types.Color;
|
||||
pub const Error = @import("error.zig").Error;
|
||||
pub const Fixed = types.Fixed;
|
||||
pub const FormatCode = format.FormatCode;
|
||||
pub const Image = image.Image;
|
||||
pub const Op = types.Op;
|
||||
pub const PointFixed = types.PointFixed;
|
||||
pub const LineFixed = types.LineFixed;
|
||||
pub const Triangle = types.Triangle;
|
||||
pub const Trapezoid = types.Trapezoid;
|
||||
pub const Rectangle16 = types.Rectangle16;
|
||||
pub const Box32 = types.Box32;
|
||||
pub const Indexed = types.Indexed;
|
||||
|
||||
test {
|
||||
std.testing.refAllDecls(@This());
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2008 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Carl D. Worth <cworth@cworth.org>
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_VERSION_H__
|
||||
#define PIXMAN_VERSION_H__
|
||||
|
||||
#ifndef PIXMAN_H__
|
||||
# error pixman-version.h should only be included by pixman.h
|
||||
#endif
|
||||
|
||||
#define PIXMAN_VERSION_MAJOR 999
|
||||
#define PIXMAN_VERSION_MINOR 999
|
||||
#define PIXMAN_VERSION_MICRO 999
|
||||
|
||||
#define PIXMAN_VERSION_STRING "999.999.999"
|
||||
|
||||
#define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \
|
||||
((major) * 10000) \
|
||||
+ ((minor) * 100) \
|
||||
+ ((micro) * 1))
|
||||
|
||||
#define PIXMAN_VERSION PIXMAN_VERSION_ENCODE( \
|
||||
PIXMAN_VERSION_MAJOR, \
|
||||
PIXMAN_VERSION_MINOR, \
|
||||
PIXMAN_VERSION_MICRO)
|
||||
|
||||
#ifndef PIXMAN_API
|
||||
# define PIXMAN_API
|
||||
#endif
|
||||
|
||||
#endif /* PIXMAN_VERSION_H__ */
|
@ -1,131 +0,0 @@
|
||||
const std = @import("std");
|
||||
const c = @import("c.zig").c;
|
||||
const pixman = @import("main.zig");
|
||||
|
||||
pub const Op = enum(c_uint) {
|
||||
clear = 0x00,
|
||||
src = 0x01,
|
||||
dst = 0x02,
|
||||
over = 0x03,
|
||||
over_reverse = 0x04,
|
||||
in = 0x05,
|
||||
in_reverse = 0x06,
|
||||
out = 0x07,
|
||||
out_reverse = 0x08,
|
||||
atop = 0x09,
|
||||
atop_reverse = 0x0a,
|
||||
xor = 0x0b,
|
||||
add = 0x0c,
|
||||
saturate = 0x0d,
|
||||
|
||||
disjoint_clear = 0x10,
|
||||
disjoint_src = 0x11,
|
||||
disjoint_dst = 0x12,
|
||||
disjoint_over = 0x13,
|
||||
disjoint_over_reverse = 0x14,
|
||||
disjoint_in = 0x15,
|
||||
disjoint_in_reverse = 0x16,
|
||||
disjoint_out = 0x17,
|
||||
disjoint_out_reverse = 0x18,
|
||||
disjoint_atop = 0x19,
|
||||
disjoint_atop_reverse = 0x1a,
|
||||
disjoint_xor = 0x1b,
|
||||
|
||||
conjoint_clear = 0x20,
|
||||
conjoint_src = 0x21,
|
||||
conjoint_dst = 0x22,
|
||||
conjoint_over = 0x23,
|
||||
conjoint_over_reverse = 0x24,
|
||||
conjoint_in = 0x25,
|
||||
conjoint_in_reverse = 0x26,
|
||||
conjoint_out = 0x27,
|
||||
conjoint_out_reverse = 0x28,
|
||||
conjoint_atop = 0x29,
|
||||
conjoint_atop_reverse = 0x2a,
|
||||
conjoint_xor = 0x2b,
|
||||
|
||||
multiply = 0x30,
|
||||
screen = 0x31,
|
||||
overlay = 0x32,
|
||||
darken = 0x33,
|
||||
lighten = 0x34,
|
||||
color_dodge = 0x35,
|
||||
color_burn = 0x36,
|
||||
hard_light = 0x37,
|
||||
soft_light = 0x38,
|
||||
difference = 0x39,
|
||||
exclusion = 0x3a,
|
||||
hsl_hue = 0x3b,
|
||||
hsl_saturation = 0x3c,
|
||||
hsl_color = 0x3d,
|
||||
hsl_luminosity = 0x3e,
|
||||
};
|
||||
|
||||
pub const Color = extern struct {
|
||||
red: u16,
|
||||
green: u16,
|
||||
blue: u16,
|
||||
alpha: u16,
|
||||
};
|
||||
|
||||
pub const Fixed = enum(i32) {
|
||||
_,
|
||||
|
||||
pub fn init(v: anytype) Fixed {
|
||||
return switch (@TypeOf(v)) {
|
||||
comptime_int, i32, u32 => @enumFromInt(v << 16),
|
||||
f64 => @enumFromInt(@as(i32, @intFromFloat(v * 65536))),
|
||||
else => {
|
||||
@compileLog(@TypeOf(v));
|
||||
@compileError("unsupported type");
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const PointFixed = extern struct {
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
};
|
||||
|
||||
pub const LineFixed = extern struct {
|
||||
p1: PointFixed,
|
||||
p2: PointFixed,
|
||||
};
|
||||
|
||||
pub const Triangle = extern struct {
|
||||
p1: PointFixed,
|
||||
p2: PointFixed,
|
||||
p3: PointFixed,
|
||||
};
|
||||
|
||||
pub const Trapezoid = extern struct {
|
||||
top: Fixed,
|
||||
bottom: Fixed,
|
||||
left: LineFixed,
|
||||
right: LineFixed,
|
||||
};
|
||||
|
||||
pub const Rectangle16 = extern struct {
|
||||
x: i16,
|
||||
y: i16,
|
||||
width: u16,
|
||||
height: u16,
|
||||
};
|
||||
|
||||
pub const Box32 = extern struct {
|
||||
x1: i32,
|
||||
y1: i32,
|
||||
x2: i32,
|
||||
y2: i32,
|
||||
};
|
||||
|
||||
pub const Indexed = extern struct {
|
||||
color: bool,
|
||||
rgba: [256]u32,
|
||||
ent: [32768]u8,
|
||||
};
|
||||
|
||||
test {
|
||||
std.testing.refAllDecls(@This());
|
||||
}
|
@ -3,6 +3,7 @@ const canvas = @import("sprite/canvas.zig");
|
||||
pub const Face = @import("sprite/Face.zig");
|
||||
|
||||
pub const Box = canvas.Box;
|
||||
pub const Point = canvas.Point;
|
||||
pub const Canvas = canvas.Canvas;
|
||||
pub const Color = canvas.Color;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -188,29 +188,65 @@ const Kind = enum {
|
||||
=> .box,
|
||||
},
|
||||
|
||||
// Box fonts
|
||||
0x2500...0x257F, // "Box Drawing" block
|
||||
0x2580...0x259F, // "Block Elements" block
|
||||
0x2800...0x28FF, // "Braille" block
|
||||
// == Box fonts ==
|
||||
|
||||
0x1FB00...0x1FB3B, // "Symbols for Legacy Computing" block
|
||||
0x1FB3C...0x1FB40,
|
||||
0x1FB47...0x1FB4B,
|
||||
0x1FB57...0x1FB5B,
|
||||
0x1FB62...0x1FB66,
|
||||
0x1FB6C...0x1FB6F,
|
||||
0x1FB41...0x1FB45,
|
||||
0x1FB4C...0x1FB50,
|
||||
0x1FB52...0x1FB56,
|
||||
0x1FB5D...0x1FB61,
|
||||
0x1FB68...0x1FB6B,
|
||||
0x1FB70...0x1FB8B,
|
||||
0x1FB46,
|
||||
0x1FB51,
|
||||
0x1FB5C,
|
||||
0x1FB67,
|
||||
0x1FB9A,
|
||||
0x1FB9B,
|
||||
// "Box Drawing" block
|
||||
// ─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏ ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟ ┠
|
||||
// ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯ ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿ ╀ ╁
|
||||
// ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏ ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟ ╠ ╡ ╢
|
||||
// ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯ ╰ ╱ ╲ ╳ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿
|
||||
0x2500...0x257F,
|
||||
|
||||
// "Block Elements" block
|
||||
// ▀ ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▉ ▊ ▋ ▌ ▍ ▎ ▏ ▐ ░ ▒ ▓ ▔ ▕ ▖ ▗ ▘ ▙ ▚ ▛ ▜ ▝ ▞ ▟
|
||||
0x2580...0x259F,
|
||||
|
||||
// "Braille" block
|
||||
0x2800...0x28FF,
|
||||
|
||||
// "Symbols for Legacy Computing" block
|
||||
// (Block Mosaics / "Sextants")
|
||||
// 🬀 🬁 🬂 🬃 🬄 🬅 🬆 🬇 🬈 🬉 🬊 🬋 🬌 🬍 🬎 🬏 🬐 🬑 🬒 🬓 🬔 🬕 🬖 🬗 🬘 🬙 🬚 🬛 🬜 🬝 🬞 🬟 🬠
|
||||
// 🬡 🬢 🬣 🬤 🬥 🬦 🬧 🬨 🬩 🬪 🬫 🬬 🬭 🬮 🬯 🬰 🬱 🬲 🬳 🬴 🬵 🬶 🬷 🬸 🬹 🬺 🬻
|
||||
// (Smooth Mosaics)
|
||||
// 🬼 🬽 🬾 🬿 🭀 🭁 🭂 🭃 🭄 🭅 🭆
|
||||
// 🭇 🭈 🭉 🭊 🭋 🭌 🭍 🭎 🭏 🭐 🭑
|
||||
// 🭒 🭓 🭔 🭕 🭖 🭗 🭘 🭙 🭚 🭛 🭜
|
||||
// 🭝 🭞 🭟 🭠 🭡 🭢 🭣 🭤 🭥 🭦 🭧
|
||||
// 🭨 🭩 🭪 🭫 🭬 🭭 🭮 🭯
|
||||
// (Block Elements)
|
||||
// 🭰 🭱 🭲 🭳 🭴 🭵 🭶 🭷 🭸 🭹 🭺 🭻
|
||||
// 🭼 🭽 🭾 🭿 🮀 🮁
|
||||
// 🮂 🮃 🮄 🮅 🮆
|
||||
// 🮇 🮈 🮉 🮊 🮋
|
||||
// (Rectangular Shade Characters)
|
||||
// 🮌 🮍 🮎 🮏 🮐 🮑 🮒
|
||||
0x1FB00...0x1FB92,
|
||||
// (Rectangular Shade Characters)
|
||||
// 🮔
|
||||
// (Fill Characters)
|
||||
// 🮕 🮖 🮗
|
||||
// (Diagonal Fill Characters)
|
||||
// 🮘 🮙
|
||||
// (Smooth Mosaics)
|
||||
// 🮚 🮛
|
||||
// (Triangular Shade Characters)
|
||||
// 🮜 🮝 🮞 🮟
|
||||
// (Character Cell Diagonals)
|
||||
// 🮠 🮡 🮢 🮣 🮤 🮥 🮦 🮧 🮨 🮩 🮪 🮫 🮬 🮭 🮮
|
||||
// (Light Solid Line With Stroke)
|
||||
// 🮯
|
||||
0x1FB94...0x1FBAF,
|
||||
// (Negative Terminal Characters)
|
||||
// 🮽 🮾 🮿
|
||||
0x1FBBD...0x1FBBF,
|
||||
// (Block Elements)
|
||||
//
|
||||
// (Character Cell Diagonals)
|
||||
//
|
||||
// (Geometric Shapes)
|
||||
//
|
||||
0x1FBCE...0x1FBEF,
|
||||
=> .box,
|
||||
|
||||
// Powerline fonts
|
||||
|
@ -11,7 +11,7 @@ const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const font = @import("../main.zig");
|
||||
const Trapezoid = @import("canvas.zig").Trapezoid;
|
||||
const Quad = @import("canvas.zig").Quad;
|
||||
|
||||
const log = std.log.scoped(.powerline_font);
|
||||
|
||||
@ -176,10 +176,10 @@ fn draw_wedge_triangle(self: Powerline, canvas: *font.sprite.Canvas, cp: u32) !v
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
canvas.triangle(.{
|
||||
.p1 = .{ .x = @as(i32, @intCast(p1_x)), .y = @as(i32, @intCast(p1_y)) },
|
||||
.p2 = .{ .x = @as(i32, @intCast(p2_x)), .y = @as(i32, @intCast(p2_y)) },
|
||||
.p3 = .{ .x = @as(i32, @intCast(p3_x)), .y = @as(i32, @intCast(p3_y)) },
|
||||
try canvas.triangle(.{
|
||||
.p0 = .{ .x = @floatFromInt(p1_x), .y = @floatFromInt(p1_y) },
|
||||
.p1 = .{ .x = @floatFromInt(p2_x), .y = @floatFromInt(p2_y) },
|
||||
.p2 = .{ .x = @floatFromInt(p3_x), .y = @floatFromInt(p3_y) },
|
||||
}, .on);
|
||||
}
|
||||
|
||||
@ -391,8 +391,8 @@ fn draw_half_circle(self: Powerline, alloc: Allocator, canvas: *font.sprite.Canv
|
||||
const average = @as(u8, @intCast(@min(total / (supersample * supersample), 0xFF)));
|
||||
canvas.rect(
|
||||
.{
|
||||
.x = @intCast(c),
|
||||
.y = @intCast(r),
|
||||
.x = @floatFromInt(c),
|
||||
.y = @floatFromInt(r),
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
},
|
||||
@ -404,110 +404,86 @@ fn draw_half_circle(self: Powerline, alloc: Allocator, canvas: *font.sprite.Canv
|
||||
}
|
||||
|
||||
fn draw_trapezoid_top_bottom(self: Powerline, canvas: *font.sprite.Canvas, cp: u32) !void {
|
||||
const t_top: Trapezoid = if (cp == 0xE0D4)
|
||||
const t_top: Quad = if (cp == 0xE0D4)
|
||||
.{
|
||||
.top = 0,
|
||||
.bottom = @intCast(self.height / 2 - self.height / 20),
|
||||
.left = .{
|
||||
.p1 = .{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @intCast(self.width - self.width / 3),
|
||||
.y = @intCast(self.height / 2 - self.height / 20),
|
||||
},
|
||||
.p0 = .{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
},
|
||||
.right = .{
|
||||
.p1 = .{
|
||||
.x = @intCast(self.width),
|
||||
.y = 0,
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @intCast(self.width),
|
||||
.y = @intCast(self.height / 2 - self.height / 20),
|
||||
},
|
||||
.p1 = .{
|
||||
.x = @floatFromInt(self.width - self.width / 3),
|
||||
.y = @floatFromInt(self.height / 2 - self.height / 20),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @floatFromInt(self.width),
|
||||
.y = @floatFromInt(self.height / 2 - self.height / 20),
|
||||
},
|
||||
.p3 = .{
|
||||
.x = @floatFromInt(self.width),
|
||||
.y = 0,
|
||||
},
|
||||
}
|
||||
else
|
||||
.{
|
||||
.top = 0,
|
||||
.bottom = @intCast(self.height / 2 - self.height / 20),
|
||||
.left = .{
|
||||
.p1 = .{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
},
|
||||
.p2 = .{
|
||||
.x = 0,
|
||||
.y = @intCast(self.height / 2 - self.height / 20),
|
||||
},
|
||||
.p0 = .{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
},
|
||||
.right = .{
|
||||
.p1 = .{
|
||||
.x = @intCast(self.width),
|
||||
.y = 0,
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @intCast(self.width / 3),
|
||||
.y = @intCast(self.height / 2 - self.height / 20),
|
||||
},
|
||||
.p1 = .{
|
||||
.x = 0,
|
||||
.y = @floatFromInt(self.height / 2 - self.height / 20),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @floatFromInt(self.width / 3),
|
||||
.y = @floatFromInt(self.height / 2 - self.height / 20),
|
||||
},
|
||||
.p3 = .{
|
||||
.x = @floatFromInt(self.width),
|
||||
.y = 0,
|
||||
},
|
||||
};
|
||||
|
||||
const t_bottom: Trapezoid = if (cp == 0xE0D4)
|
||||
const t_bottom: Quad = if (cp == 0xE0D4)
|
||||
.{
|
||||
.top = @intCast(self.height / 2 + self.height / 20),
|
||||
.bottom = @intCast(self.height),
|
||||
.left = .{
|
||||
.p1 = .{
|
||||
.x = @intCast(self.width - self.width / 3),
|
||||
.y = @intCast(self.height / 2 + self.height / 20),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = 0,
|
||||
.y = @intCast(self.height),
|
||||
},
|
||||
.p0 = .{
|
||||
.x = @floatFromInt(self.width - self.width / 3),
|
||||
.y = @floatFromInt(self.height / 2 + self.height / 20),
|
||||
},
|
||||
.right = .{
|
||||
.p1 = .{
|
||||
.x = @intCast(self.width),
|
||||
.y = @intCast(self.height / 2 + self.height / 20),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @intCast(self.width),
|
||||
.y = @intCast(self.height),
|
||||
},
|
||||
.p1 = .{
|
||||
.x = 0,
|
||||
.y = @floatFromInt(self.height),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @floatFromInt(self.width),
|
||||
.y = @floatFromInt(self.height),
|
||||
},
|
||||
.p3 = .{
|
||||
.x = @floatFromInt(self.width),
|
||||
.y = @floatFromInt(self.height / 2 + self.height / 20),
|
||||
},
|
||||
}
|
||||
else
|
||||
.{
|
||||
.top = @intCast(self.height / 2 + self.height / 20),
|
||||
.bottom = @intCast(self.height),
|
||||
.left = .{
|
||||
.p1 = .{
|
||||
.x = 0,
|
||||
.y = @intCast(self.height / 2 + self.height / 20),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = 0,
|
||||
.y = @intCast(self.height),
|
||||
},
|
||||
.p0 = .{
|
||||
.x = 0,
|
||||
.y = @floatFromInt(self.height / 2 + self.height / 20),
|
||||
},
|
||||
.right = .{
|
||||
.p1 = .{
|
||||
.x = @intCast(self.width / 3),
|
||||
.y = @intCast(self.height / 2 + self.height / 20),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @intCast(self.width),
|
||||
.y = @intCast(self.height),
|
||||
},
|
||||
.p1 = .{
|
||||
.x = 0,
|
||||
.y = @floatFromInt(self.height),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = @floatFromInt(self.width),
|
||||
.y = @floatFromInt(self.height),
|
||||
},
|
||||
.p3 = .{
|
||||
.x = @floatFromInt(self.width / 3),
|
||||
.y = @floatFromInt(self.height / 2 + self.height / 20),
|
||||
},
|
||||
};
|
||||
|
||||
canvas.trapezoid(t_top);
|
||||
canvas.trapezoid(t_bottom);
|
||||
try canvas.quad(t_top, .on);
|
||||
try canvas.quad(t_bottom, .on);
|
||||
}
|
||||
|
||||
test "all" {
|
||||
|
@ -3,340 +3,88 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const js = @import("zig-js");
|
||||
const pixman = @import("pixman");
|
||||
const z2d = @import("z2d");
|
||||
const font = @import("../main.zig");
|
||||
|
||||
pub const Point = struct {
|
||||
x: i32,
|
||||
y: i32,
|
||||
x: f64,
|
||||
y: f64,
|
||||
};
|
||||
|
||||
pub const Line = struct {
|
||||
p0: Point,
|
||||
p1: Point,
|
||||
p2: Point,
|
||||
};
|
||||
|
||||
pub const Box = struct {
|
||||
x1: i32,
|
||||
y1: i32,
|
||||
x2: i32,
|
||||
y2: i32,
|
||||
p0: Point,
|
||||
p1: Point,
|
||||
|
||||
pub fn rect(self: Box) Rect {
|
||||
const tl_x = @min(self.x1, self.x2);
|
||||
const tl_y = @min(self.y1, self.y2);
|
||||
const br_x = @max(self.x1, self.x2);
|
||||
const br_y = @max(self.y1, self.y2);
|
||||
const tl_x = @min(self.p0.x, self.p1.x);
|
||||
const tl_y = @min(self.p0.y, self.p1.y);
|
||||
const br_x = @max(self.p0.x, self.p1.x);
|
||||
const br_y = @max(self.p0.y, self.p1.y);
|
||||
return .{
|
||||
.x = tl_x,
|
||||
.y = tl_y,
|
||||
.width = @intCast(br_x - tl_x),
|
||||
.height = @intCast(br_y - tl_y),
|
||||
.width = br_x - tl_x,
|
||||
.height = br_y - tl_y,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Rect = struct {
|
||||
x: i32,
|
||||
y: i32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
x: f64,
|
||||
y: f64,
|
||||
width: f64,
|
||||
height: f64,
|
||||
};
|
||||
|
||||
pub const Triangle = struct {
|
||||
p0: Point,
|
||||
p1: Point,
|
||||
p2: Point,
|
||||
};
|
||||
|
||||
pub const Quad = struct {
|
||||
p0: Point,
|
||||
p1: Point,
|
||||
p2: Point,
|
||||
p3: Point,
|
||||
};
|
||||
|
||||
pub const Trapezoid = struct {
|
||||
top: i32,
|
||||
bottom: i32,
|
||||
left: Line,
|
||||
right: Line,
|
||||
};
|
||||
|
||||
/// We only use alpha-channel so a pixel can only be "on" or "off".
|
||||
pub const Color = enum(u8) {
|
||||
const CSS_BUF_MAX = 24;
|
||||
|
||||
on = 255,
|
||||
off = 0,
|
||||
_,
|
||||
|
||||
fn pixmanColor(self: Color) pixman.Color {
|
||||
// pixman uses u16 for color while our color value is u8 so we
|
||||
// scale it up proportionally.
|
||||
const max = @as(f32, @floatFromInt(std.math.maxInt(u8)));
|
||||
const max_u16 = @as(f32, @floatFromInt(std.math.maxInt(u16)));
|
||||
const unscaled = @as(f32, @floatFromInt(@intFromEnum(self)));
|
||||
const scaled = @as(u16, @intFromFloat((unscaled * max_u16) / max));
|
||||
return .{ .red = 0, .green = 0, .blue = 0, .alpha = scaled };
|
||||
}
|
||||
|
||||
fn cssColor(self: Color, buf: []u8) ![]u8 {
|
||||
return try std.fmt.bufPrint(buf, "rgba(0, 0, 0, {:.2})", .{
|
||||
@as(f32, @floatFromInt(@intFromEnum(self))) / 255,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/// Composition operations that are supported.
|
||||
pub const CompositionOp = enum {
|
||||
// Note: more can be added here as needed.
|
||||
pub const Canvas = struct {
|
||||
/// The underlying z2d surface.
|
||||
sfc: z2d.Surface,
|
||||
|
||||
source_out,
|
||||
|
||||
fn pixmanOp(self: CompositionOp) pixman.Op {
|
||||
return switch (self) {
|
||||
.source_out => .out,
|
||||
};
|
||||
}
|
||||
|
||||
fn jsOp(self: CompositionOp) js.String {
|
||||
return switch (self) {
|
||||
.source_out => js.string("source-out"),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Canvas = switch (font.options.backend) {
|
||||
.web_canvas => WebCanvasImpl,
|
||||
else => PixmanImpl,
|
||||
};
|
||||
|
||||
const WebCanvasImpl = struct {
|
||||
/// The canvas element that is our final image.
|
||||
canvas: js.Object,
|
||||
|
||||
/// Store the dimensions for easy access later.
|
||||
width: u32,
|
||||
height: u32,
|
||||
|
||||
pub fn init(alloc: Allocator, width: u32, height: u32) !WebCanvasImpl {
|
||||
_ = alloc;
|
||||
|
||||
// Create our canvas that we're going to continue to reuse.
|
||||
const doc = try js.global.get(js.Object, "document");
|
||||
defer doc.deinit();
|
||||
const canvas = try doc.call(js.Object, "createElement", .{js.string("canvas")});
|
||||
errdefer canvas.deinit();
|
||||
|
||||
// Set our dimensions.
|
||||
try canvas.set("width", width);
|
||||
try canvas.set("height", height);
|
||||
|
||||
return WebCanvasImpl{
|
||||
.canvas = canvas,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *WebCanvasImpl, alloc: Allocator) void {
|
||||
_ = alloc;
|
||||
self.canvas.deinit();
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn pixel(self: *WebCanvasImpl, x: u32, y: u32, color: Color) void {
|
||||
const ctx = self.context(color) catch return;
|
||||
defer ctx.deinit();
|
||||
ctx.call(void, "fillRect", .{ x, y, 1, 1 }) catch return;
|
||||
}
|
||||
|
||||
pub fn rect(self: *WebCanvasImpl, v: Rect, color: Color) void {
|
||||
const ctx = self.context(color) catch return;
|
||||
defer ctx.deinit();
|
||||
ctx.call(void, "fillRect", .{
|
||||
@as(u32, @intCast(v.x)),
|
||||
@as(u32, @intCast(v.y)),
|
||||
v.width,
|
||||
v.height,
|
||||
}) catch return;
|
||||
}
|
||||
|
||||
pub fn trapezoid(self: *WebCanvasImpl, t: Trapezoid) void {
|
||||
const ctx = self.context(.on) catch return;
|
||||
defer ctx.deinit();
|
||||
|
||||
ctx.call(void, "beginPath", .{}) catch return;
|
||||
ctx.call(void, "moveTo", .{ t.left.p1.x, t.left.p1.y }) catch return;
|
||||
ctx.call(void, "lineTo", .{ t.right.p1.x, t.right.p1.y }) catch return;
|
||||
ctx.call(void, "lineTo", .{ t.right.p2.x, t.right.p2.y }) catch return;
|
||||
ctx.call(void, "lineTo", .{ t.left.p2.x, t.left.p2.y }) catch return;
|
||||
ctx.call(void, "fill", .{}) catch return;
|
||||
}
|
||||
|
||||
pub fn triangle(self: *WebCanvasImpl, t: Triangle, color: Color) void {
|
||||
const ctx = self.context(color) catch return;
|
||||
defer ctx.deinit();
|
||||
|
||||
ctx.call(void, "beginPath", .{}) catch return;
|
||||
ctx.call(void, "moveTo", .{ t.p1.x, t.p1.y }) catch return;
|
||||
ctx.call(void, "lineTo", .{ t.p2.x, t.p2.y }) catch return;
|
||||
ctx.call(void, "lineTo", .{ t.p3.x, t.p3.y }) catch return;
|
||||
ctx.call(void, "fill", .{}) catch return;
|
||||
}
|
||||
|
||||
pub fn composite(
|
||||
self: *WebCanvasImpl,
|
||||
op: CompositionOp,
|
||||
src: *const WebCanvasImpl,
|
||||
dest: Rect,
|
||||
) void {
|
||||
const ctx = self.context(Color.on) catch return;
|
||||
defer ctx.deinit();
|
||||
|
||||
// Set our compositing operation
|
||||
ctx.set("globalCompositeOperation", op.jsOp()) catch return;
|
||||
|
||||
// Composite
|
||||
ctx.call(void, "drawImage", .{
|
||||
src.canvas,
|
||||
dest.x,
|
||||
dest.y,
|
||||
dest.width,
|
||||
dest.height,
|
||||
}) catch return;
|
||||
}
|
||||
|
||||
fn context(self: WebCanvasImpl, fill: ?Color) !js.Object {
|
||||
const ctx = try self.canvas.call(js.Object, "getContext", .{js.string("2d")});
|
||||
errdefer ctx.deinit();
|
||||
|
||||
// Reset our composite operation
|
||||
try ctx.set("globalCompositeOperation", js.string("source-over"));
|
||||
|
||||
// Set our fill color
|
||||
if (fill) |c| {
|
||||
var buf: [Color.CSS_BUF_MAX]u8 = undefined;
|
||||
const color = try c.cssColor(&buf);
|
||||
try ctx.set("fillStyle", js.string(color));
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
pub fn writeAtlas(self: *WebCanvasImpl, alloc: Allocator, atlas: *font.Atlas) !font.Atlas.Region {
|
||||
assert(atlas.format == .grayscale);
|
||||
|
||||
// Reload our context since we resized the canvas
|
||||
const ctx = try self.context(null);
|
||||
defer ctx.deinit();
|
||||
|
||||
// Set our width/height. Set to vars in case we just query the canvas later.
|
||||
const width = self.width;
|
||||
const height = self.height;
|
||||
|
||||
// Read the image data and get it into a []u8 on our side
|
||||
const bitmap: []u8 = bitmap: {
|
||||
// Read the raw bitmap data and get the "data" value which is a
|
||||
// Uint8ClampedArray.
|
||||
const data = try ctx.call(js.Object, "getImageData", .{ 0, 0, width, height });
|
||||
defer data.deinit();
|
||||
const src_array = try data.get(js.Object, "data");
|
||||
defer src_array.deinit();
|
||||
|
||||
// Allocate our local memory to copy the data to.
|
||||
const len = try src_array.get(u32, "length");
|
||||
const bitmap = try alloc.alloc(u8, @intCast(len));
|
||||
errdefer alloc.free(bitmap);
|
||||
|
||||
// Create our target Uint8Array that we can use to copy from src.
|
||||
const mem_array = mem_array: {
|
||||
// Get our runtime memory
|
||||
const mem = try js.runtime.get(js.Object, "memory");
|
||||
defer mem.deinit();
|
||||
const buf = try mem.get(js.Object, "buffer");
|
||||
defer buf.deinit();
|
||||
|
||||
// Construct our array to peer into our memory
|
||||
const Uint8Array = try js.global.get(js.Object, "Uint8Array");
|
||||
defer Uint8Array.deinit();
|
||||
const mem_array = try Uint8Array.new(.{ buf, bitmap.ptr });
|
||||
errdefer mem_array.deinit();
|
||||
|
||||
break :mem_array mem_array;
|
||||
};
|
||||
defer mem_array.deinit();
|
||||
|
||||
// Copy
|
||||
try mem_array.call(void, "set", .{src_array});
|
||||
|
||||
break :bitmap bitmap;
|
||||
};
|
||||
errdefer alloc.free(bitmap);
|
||||
|
||||
// Convert the format of the bitmap to A8 since the raw canvas data
|
||||
// is in RGBA.
|
||||
// NOTE(mitchellh): do we need a 1px buffer to avoid artifacts?
|
||||
const bitmap_a8: []u8 = a8: {
|
||||
assert(@mod(bitmap.len, 4) == 0);
|
||||
assert(bitmap.len == width * height * 4);
|
||||
var bitmap_a8 = try alloc.alloc(u8, bitmap.len / 4);
|
||||
errdefer alloc.free(bitmap_a8);
|
||||
var i: usize = 0;
|
||||
while (i < bitmap_a8.len) : (i += 1) {
|
||||
bitmap_a8[i] = bitmap[(i * 4) + 3];
|
||||
}
|
||||
|
||||
break :a8 bitmap_a8;
|
||||
};
|
||||
defer alloc.free(bitmap_a8);
|
||||
|
||||
// Write the glyph information into the atlas
|
||||
const region = try atlas.reserve(alloc, width, height);
|
||||
if (region.width > 0 and region.height > 0) {
|
||||
assert(region.width == width);
|
||||
assert(region.height == height);
|
||||
atlas.set(region, bitmap_a8);
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
};
|
||||
|
||||
const PixmanImpl = struct {
|
||||
/// The underlying image.
|
||||
image: *pixman.Image,
|
||||
|
||||
/// The raw data buffer.
|
||||
data: []u32,
|
||||
alloc: Allocator,
|
||||
|
||||
pub fn init(alloc: Allocator, width: u32, height: u32) !Canvas {
|
||||
// Determine the config for our image buffer. The images we draw
|
||||
// for boxes are always 8bpp
|
||||
const format: pixman.FormatCode = .a8;
|
||||
const stride = format.strideForWidth(width);
|
||||
const len = @as(usize, @intCast(stride * @as(c_int, @intCast(height))));
|
||||
|
||||
// Allocate our buffer. pixman uses []u32 so we divide our length
|
||||
// by 4 since u32 / u8 = 4.
|
||||
const data = try alloc.alloc(u32, len / 4);
|
||||
errdefer alloc.free(data);
|
||||
@memset(data, 0);
|
||||
|
||||
// Create the image we'll draw to
|
||||
const img = try pixman.Image.createBitsNoClear(
|
||||
format,
|
||||
// Create the surface we'll be using.
|
||||
const sfc = try z2d.Surface.initPixel(
|
||||
.{ .alpha8 = .{ .a = 0 } },
|
||||
alloc,
|
||||
@intCast(width),
|
||||
@intCast(height),
|
||||
data.ptr,
|
||||
stride,
|
||||
);
|
||||
errdefer _ = img.unref();
|
||||
|
||||
return Canvas{
|
||||
.image = img,
|
||||
.data = data,
|
||||
return .{
|
||||
.sfc = sfc,
|
||||
.alloc = alloc,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Canvas, alloc: Allocator) void {
|
||||
alloc.free(self.data);
|
||||
_ = self.image.unref();
|
||||
_ = alloc;
|
||||
self.sfc.deinit();
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
@ -344,8 +92,8 @@ const PixmanImpl = struct {
|
||||
pub fn writeAtlas(self: *Canvas, alloc: Allocator, atlas: *font.Atlas) !font.Atlas.Region {
|
||||
assert(atlas.format == .grayscale);
|
||||
|
||||
const width = @as(u32, @intCast(self.image.getWidth()));
|
||||
const height = @as(u32, @intCast(self.image.getHeight()));
|
||||
const width = @as(u32, @intCast(self.sfc.getWidth()));
|
||||
const height = @as(u32, @intCast(self.sfc.getHeight()));
|
||||
|
||||
// Allocate our texture atlas region
|
||||
const region = region: {
|
||||
@ -372,31 +120,7 @@ const PixmanImpl = struct {
|
||||
};
|
||||
|
||||
if (region.width > 0 and region.height > 0) {
|
||||
const depth = atlas.format.depth();
|
||||
|
||||
// Convert our []u32 to []u8 since we use 8bpp formats
|
||||
const stride = self.image.getStride();
|
||||
const data = @as([*]u8, @ptrCast(self.data.ptr))[0 .. self.data.len * 4];
|
||||
|
||||
// We can avoid a buffer copy if our atlas width and bitmap
|
||||
// width match and the bitmap pitch is just the width (meaning
|
||||
// the data is tightly packed).
|
||||
const needs_copy = !(width * depth == stride);
|
||||
|
||||
// If we need to copy the data, we copy it into a temporary buffer.
|
||||
const buffer = if (needs_copy) buffer: {
|
||||
const temp = try alloc.alloc(u8, width * height * depth);
|
||||
var dst_ptr = temp;
|
||||
var src_ptr = data.ptr;
|
||||
var i: usize = 0;
|
||||
while (i < height) : (i += 1) {
|
||||
@memcpy(dst_ptr[0 .. width * depth], src_ptr[0 .. width * depth]);
|
||||
dst_ptr = dst_ptr[width * depth ..];
|
||||
src_ptr += @as(usize, @intCast(stride));
|
||||
}
|
||||
break :buffer temp;
|
||||
} else data[0..(width * height * depth)];
|
||||
defer if (buffer.ptr != data.ptr) alloc.free(buffer);
|
||||
const buffer: []u8 = @ptrCast(self.sfc.image_surface_alpha8.buf);
|
||||
|
||||
// Write the glyph information into the atlas
|
||||
assert(region.width == width);
|
||||
@ -409,102 +133,105 @@ const PixmanImpl = struct {
|
||||
|
||||
/// Draw and fill a single pixel
|
||||
pub fn pixel(self: *Canvas, x: u32, y: u32, color: Color) void {
|
||||
if (comptime std.debug.runtime_safety) {
|
||||
assert(x < self.image.getWidth());
|
||||
assert(y < self.image.getHeight());
|
||||
}
|
||||
|
||||
const boxes = &[_]pixman.Box32{
|
||||
.{
|
||||
.x1 = @intCast(x),
|
||||
.y1 = @intCast(y),
|
||||
.x2 = @intCast(x + 1),
|
||||
.y2 = @intCast(y + 1),
|
||||
},
|
||||
self.sfc.putPixel(
|
||||
@intCast(x),
|
||||
@intCast(y),
|
||||
.{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||
) catch {
|
||||
// If we try to set out of range this will fail.
|
||||
// We just silently ignore that.
|
||||
};
|
||||
|
||||
self.image.fillBoxes(.src, color.pixmanColor(), boxes) catch {};
|
||||
}
|
||||
|
||||
/// Draw and fill a rectangle. This is the main primitive for drawing
|
||||
/// lines as well (which are just generally skinny rectangles...)
|
||||
pub fn rect(self: *Canvas, v: Rect, color: Color) void {
|
||||
const boxes = &[_]pixman.Box32{
|
||||
.{
|
||||
.x1 = @intCast(v.x),
|
||||
.y1 = @intCast(v.y),
|
||||
.x2 = @intCast(v.x + @as(i32, @intCast(v.width))),
|
||||
.y2 = @intCast(v.y + @as(i32, @intCast(v.height))),
|
||||
const x0: usize = @intFromFloat(v.x);
|
||||
const x1: usize = @intFromFloat(v.x + v.width);
|
||||
const y0: usize = @intFromFloat(v.y);
|
||||
const y1: usize = @intFromFloat(v.y + v.height);
|
||||
|
||||
for (y0..y1) |y| {
|
||||
for (x0..x1) |x| {
|
||||
self.pixel(
|
||||
@intCast(x),
|
||||
@intCast(y),
|
||||
color,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw and fill a quad.
|
||||
pub fn quad(self: *Canvas, q: Quad, color: Color) !void {
|
||||
var ctx: z2d.Context = .{
|
||||
.surface = self.sfc,
|
||||
.pattern = .{
|
||||
.opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (comptime std.debug.runtime_safety) {
|
||||
assert(boxes[0].x1 >= 0);
|
||||
assert(boxes[0].y1 >= 0);
|
||||
assert(boxes[0].x2 <= @as(i32, @intCast(self.image.getWidth())));
|
||||
assert(boxes[0].y2 <= @as(i32, @intCast(self.image.getHeight())));
|
||||
}
|
||||
var path = z2d.Path.init(self.alloc);
|
||||
defer path.deinit();
|
||||
|
||||
self.image.fillBoxes(.src, color.pixmanColor(), boxes) catch {};
|
||||
}
|
||||
try path.moveTo(q.p0.x, q.p0.y);
|
||||
try path.lineTo(q.p1.x, q.p1.y);
|
||||
try path.lineTo(q.p2.x, q.p2.y);
|
||||
try path.lineTo(q.p3.x, q.p3.y);
|
||||
try path.close();
|
||||
|
||||
/// Draw and fill a trapezoid.
|
||||
pub fn trapezoid(self: *Canvas, t: Trapezoid) void {
|
||||
self.image.rasterizeTrapezoid(.{
|
||||
.top = pixman.Fixed.init(t.top),
|
||||
.bottom = pixman.Fixed.init(t.bottom),
|
||||
.left = .{
|
||||
.p1 = .{
|
||||
.x = pixman.Fixed.init(t.left.p1.x),
|
||||
.y = pixman.Fixed.init(t.left.p1.y),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = pixman.Fixed.init(t.left.p2.x),
|
||||
.y = pixman.Fixed.init(t.left.p2.y),
|
||||
},
|
||||
},
|
||||
.right = .{
|
||||
.p1 = .{
|
||||
.x = pixman.Fixed.init(t.right.p1.x),
|
||||
.y = pixman.Fixed.init(t.right.p1.y),
|
||||
},
|
||||
.p2 = .{
|
||||
.x = pixman.Fixed.init(t.right.p2.x),
|
||||
.y = pixman.Fixed.init(t.right.p2.y),
|
||||
},
|
||||
},
|
||||
}, 0, 0);
|
||||
try ctx.fill(self.alloc, path);
|
||||
}
|
||||
|
||||
/// Draw and fill a triangle.
|
||||
pub fn triangle(self: *Canvas, t: Triangle, color: Color) void {
|
||||
const tris = &[_]pixman.Triangle{
|
||||
.{
|
||||
.p1 = .{ .x = pixman.Fixed.init(t.p1.x), .y = pixman.Fixed.init(t.p1.y) },
|
||||
.p2 = .{ .x = pixman.Fixed.init(t.p2.x), .y = pixman.Fixed.init(t.p2.y) },
|
||||
.p3 = .{ .x = pixman.Fixed.init(t.p3.x), .y = pixman.Fixed.init(t.p3.y) },
|
||||
pub fn triangle(self: *Canvas, t: Triangle, color: Color) !void {
|
||||
var ctx: z2d.Context = .{
|
||||
.surface = self.sfc,
|
||||
.pattern = .{
|
||||
.opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const src = pixman.Image.createSolidFill(color.pixmanColor()) catch return;
|
||||
defer _ = src.unref();
|
||||
self.image.compositeTriangles(.over, src, .a8, 0, 0, 0, 0, tris);
|
||||
var path = z2d.Path.init(self.alloc);
|
||||
defer path.deinit();
|
||||
|
||||
try path.moveTo(t.p0.x, t.p0.y);
|
||||
try path.lineTo(t.p1.x, t.p1.y);
|
||||
try path.lineTo(t.p2.x, t.p2.y);
|
||||
try path.close();
|
||||
|
||||
try ctx.fill(self.alloc, path);
|
||||
}
|
||||
|
||||
/// Composite one image on another.
|
||||
pub fn composite(self: *Canvas, op: CompositionOp, src: *const Canvas, dest: Rect) void {
|
||||
self.image.composite(
|
||||
op.pixmanOp(),
|
||||
src.image,
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
@intCast(dest.x),
|
||||
@intCast(dest.y),
|
||||
@intCast(dest.width),
|
||||
@intCast(dest.height),
|
||||
);
|
||||
/// Stroke a line.
|
||||
pub fn line(self: *Canvas, l: Line, thickness: f64, color: Color) !void {
|
||||
var ctx: z2d.Context = .{
|
||||
.surface = self.sfc,
|
||||
.pattern = .{
|
||||
.opaque_pattern = .{
|
||||
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(color) } },
|
||||
},
|
||||
},
|
||||
.line_width = thickness,
|
||||
.line_cap_mode = .round,
|
||||
};
|
||||
|
||||
var path = z2d.Path.init(self.alloc);
|
||||
defer path.deinit();
|
||||
|
||||
try path.moveTo(l.p0.x, l.p0.y);
|
||||
try path.lineTo(l.p1.x, l.p1.y);
|
||||
|
||||
try ctx.stroke(self.alloc, path);
|
||||
}
|
||||
|
||||
pub fn invert(self: *Canvas) void {
|
||||
for (std.mem.sliceAsBytes(self.sfc.image_surface_alpha8.buf)) |*v| {
|
||||
v.* = 255 - v.*;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
BIN
src/font/sprite/testdata/Box.ppm
vendored
BIN
src/font/sprite/testdata/Box.ppm
vendored
Binary file not shown.
@ -70,8 +70,8 @@ fn drawSingle(alloc: Allocator, width: u32, thickness: u32) !CanvasAndOffset {
|
||||
canvas.rect(.{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = width,
|
||||
.height = thickness,
|
||||
.width = @floatFromInt(width),
|
||||
.height = @floatFromInt(thickness),
|
||||
}, .on);
|
||||
|
||||
const offset_y: i32 = 0;
|
||||
@ -91,15 +91,15 @@ fn drawDouble(alloc: Allocator, width: u32, thickness: u32) !CanvasAndOffset {
|
||||
canvas.rect(.{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = width,
|
||||
.height = thickness,
|
||||
.width = @floatFromInt(width),
|
||||
.height = @floatFromInt(thickness),
|
||||
}, .on);
|
||||
|
||||
canvas.rect(.{
|
||||
.x = 0,
|
||||
.y = @intCast(thickness + gap),
|
||||
.width = width,
|
||||
.height = thickness,
|
||||
.y = @floatFromInt(thickness * 2),
|
||||
.width = @floatFromInt(width),
|
||||
.height = @floatFromInt(thickness),
|
||||
}, .on);
|
||||
|
||||
const offset_y: i32 = -@as(i32, @intCast(thickness));
|
||||
@ -121,10 +121,10 @@ fn drawDotted(alloc: Allocator, width: u32, thickness: u32) !CanvasAndOffset {
|
||||
const x = @min(i * (dot_width + gap_width), width - 1);
|
||||
const rect_width = @min(width - x, dot_width);
|
||||
canvas.rect(.{
|
||||
.x = @intCast(x),
|
||||
.x = @floatFromInt(x),
|
||||
.y = 0,
|
||||
.width = rect_width,
|
||||
.height = thickness,
|
||||
.width = @floatFromInt(rect_width),
|
||||
.height = @floatFromInt(thickness),
|
||||
}, .on);
|
||||
}
|
||||
|
||||
@ -146,10 +146,10 @@ fn drawDashed(alloc: Allocator, width: u32, thickness: u32) !CanvasAndOffset {
|
||||
const x = @min(i * dash_width, width - 1);
|
||||
const rect_width = @min(width - x, dash_width);
|
||||
canvas.rect(.{
|
||||
.x = @intCast(x),
|
||||
.x = @floatFromInt(x),
|
||||
.y = 0,
|
||||
.width = rect_width,
|
||||
.height = thickness,
|
||||
.width = @floatFromInt(rect_width),
|
||||
.height = @floatFromInt(thickness),
|
||||
}, .on);
|
||||
}
|
||||
|
||||
|
14
vendor/pixman/.editorconfig
vendored
14
vendor/pixman/.editorconfig
vendored
@ -1,14 +0,0 @@
|
||||
# To use this config on you editor, follow the instructions at:
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
tab_width = 8
|
||||
|
||||
[Makefile.*]
|
||||
indent_style = tab
|
||||
|
||||
[meson.build,meson_options.txt]
|
||||
indent_style = space
|
||||
indent_size = 2
|
56
vendor/pixman/.gitignore
vendored
56
vendor/pixman/.gitignore
vendored
@ -1,56 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
.msg
|
||||
*.pc
|
||||
*.lo
|
||||
*.la
|
||||
*.a
|
||||
*.o
|
||||
*~
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
stamp-h?
|
||||
config.h
|
||||
config.h.in
|
||||
.*.swp
|
||||
demos/*-test
|
||||
demos/checkerboard
|
||||
demos/clip-in
|
||||
demos/linear-gradient
|
||||
demos/quad2quad
|
||||
demos/scale
|
||||
demos/dither
|
||||
pixman/pixman-srgb.c
|
||||
pixman/pixman-version.h
|
||||
test/*-test
|
||||
test/affine-bench
|
||||
test/alpha-loop
|
||||
test/alphamap
|
||||
test/check-formats
|
||||
test/clip-in
|
||||
test/composite
|
||||
test/infinite-loop
|
||||
test/lowlevel-blt-bench
|
||||
test/radial-invalid
|
||||
test/region-translate
|
||||
test/scaling-bench
|
||||
test/trap-crasher
|
||||
*.pdb
|
||||
*.dll
|
||||
*.lib
|
||||
*.ilk
|
||||
*.obj
|
||||
*.exe
|
19
vendor/pixman/.gitlab-ci.yml
vendored
19
vendor/pixman/.gitlab-ci.yml
vendored
@ -1,19 +0,0 @@
|
||||
image: fedora:28
|
||||
|
||||
autotools-build:
|
||||
script:
|
||||
- dnf -y install dnf-plugins-core
|
||||
- dnf -y groupinstall buildsys-build
|
||||
- dnf -y builddep pixman
|
||||
- ./autogen.sh
|
||||
- make -sj4 check
|
||||
|
||||
meson-build:
|
||||
script:
|
||||
- dnf -y install dnf-plugins-core
|
||||
- dnf -y groupinstall buildsys-build
|
||||
- dnf -y builddep pixman
|
||||
- dnf -y install ninja-build
|
||||
- python3 -m pip install meson>=0.52.1
|
||||
- meson build
|
||||
- ninja -C build test
|
0
vendor/pixman/AUTHORS
vendored
0
vendor/pixman/AUTHORS
vendored
199
vendor/pixman/CODING_STYLE
vendored
199
vendor/pixman/CODING_STYLE
vendored
@ -1,199 +0,0 @@
|
||||
Pixman coding style.
|
||||
====================
|
||||
|
||||
The pixman coding style is close to cairo's with one exception: braces
|
||||
go on their own line, rather than on the line of the if/while/for:
|
||||
|
||||
if (condition)
|
||||
{
|
||||
do_something();
|
||||
do_something_else();
|
||||
}
|
||||
|
||||
not
|
||||
|
||||
if (condition) {
|
||||
do_something();
|
||||
do_something_else();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Indentation
|
||||
===========
|
||||
|
||||
Each new level is indented four spaces:
|
||||
|
||||
if (condition)
|
||||
do_something();
|
||||
|
||||
This may be achieved with space characters or with a combination of
|
||||
tab characters and space characters. Tab characters are interpreted as
|
||||
|
||||
Advance to the next column which is a multiple of 8.
|
||||
|
||||
|
||||
Names
|
||||
=====
|
||||
|
||||
In all names, words are separated with underscores. Do not use
|
||||
CamelCase for any names.
|
||||
|
||||
Macros have ALL_CAPITAL_NAMES
|
||||
|
||||
Type names are in lower case and end with "_t". For example
|
||||
pixman_image_t.
|
||||
|
||||
Labels, functions and variables have lower case names.
|
||||
|
||||
|
||||
Braces
|
||||
======
|
||||
|
||||
Braces always go on their own line:
|
||||
|
||||
if (condition)
|
||||
{
|
||||
do_this ();
|
||||
do_that ();
|
||||
}
|
||||
else
|
||||
{
|
||||
do_the_other ();
|
||||
}
|
||||
|
||||
Rules for braces and substatements of if/while/for/do:
|
||||
|
||||
* If a substatement spans multiple lines, then there must be braces
|
||||
around it.
|
||||
|
||||
* If the condition of an if/while/for spans multiple lines, then
|
||||
braces must be used for the substatements.
|
||||
|
||||
* If one substatement of an if statement has braces, then the other
|
||||
must too.
|
||||
|
||||
* Otherwise, don't add braces.
|
||||
|
||||
|
||||
Comments
|
||||
========
|
||||
|
||||
For comments either like this:
|
||||
|
||||
/* One line comment */
|
||||
|
||||
or like this:
|
||||
|
||||
/* This is a multi-line comment
|
||||
*
|
||||
* It extends over multiple lines
|
||||
*/
|
||||
|
||||
Generally comments should say things that aren't clear from the code
|
||||
itself. If too many comments say obvious things, then people will just
|
||||
stop reading all comments, including the good ones.
|
||||
|
||||
|
||||
Whitespace
|
||||
==========
|
||||
|
||||
* Put a single space after commas
|
||||
|
||||
* Put spaces around arithmetic operators such a +, -, *, /:
|
||||
|
||||
y * stride + x
|
||||
|
||||
x / unit_x
|
||||
|
||||
* Do not put spaces after the address-of operator, the * when used as
|
||||
a pointer derefernce or the ! and ~ operators:
|
||||
|
||||
&foo;
|
||||
|
||||
~0x00000000
|
||||
|
||||
!condition
|
||||
|
||||
*result = 100
|
||||
|
||||
* Break up long lines (> ~80 characters) and use whitespace to align
|
||||
things nicely. This is one way:
|
||||
|
||||
some_very_long_function name (
|
||||
implementation, op, src, mask, dest,
|
||||
src_x, src_y, mask_x, mask_y, dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
This is another:
|
||||
|
||||
some_very_long_function_name (implementation, op,
|
||||
src, mask, dest,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
* Separate logically distinct chunks with a single newline. This
|
||||
obviously applies between functions, but also applies within a
|
||||
function or block or structure definition.
|
||||
|
||||
* Use a newline after a block of variable declarations.
|
||||
|
||||
* Use a single space before a left parenthesis, except where the
|
||||
standard will not allow it, (eg. when defining a parameterized macro).
|
||||
|
||||
* Don't eliminate newlines just because things would still fit on one
|
||||
line. This breaks the expected visual structure of the code making
|
||||
it much harder to read and understand:
|
||||
|
||||
if (condition) foo (); else bar (); /* Yuck! */
|
||||
|
||||
|
||||
Function Definitions
|
||||
====================
|
||||
|
||||
Function definitions should take the following form:
|
||||
|
||||
void
|
||||
my_function (int argument)
|
||||
{
|
||||
do_my_things ();
|
||||
}
|
||||
|
||||
If all the parameters to a function fit naturally on one line, format
|
||||
them that way. Otherwise, put one argument on each line, adding
|
||||
whitespace so that the parameter names are aligned with each other.
|
||||
|
||||
I.e., do either this:
|
||||
|
||||
void
|
||||
short_arguments (const char *str, int x, int y, int z)
|
||||
{
|
||||
}
|
||||
|
||||
or this:
|
||||
|
||||
void
|
||||
long_arguments (const char *char_star_arg,
|
||||
int int_arg,
|
||||
double *double_star_arg,
|
||||
double double_arg)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Mode lines
|
||||
==========
|
||||
|
||||
Given the rules above, what is the best way to simplify one's life as
|
||||
a code monkey? Get your editor to do most of the tedious work of
|
||||
beautifying your code!
|
||||
|
||||
As a reward for reading this far, here are some mode lines for the more
|
||||
popular editors:
|
||||
/*
|
||||
* vim:sw=4:sts=4:ts=8:tw=78:fo=tcroq:cindent:cino=\:0,(0
|
||||
* vim:isk=a-z,A-Z,48-57,_,.,-,>
|
||||
*/
|
||||
|
42
vendor/pixman/COPYING
vendored
42
vendor/pixman/COPYING
vendored
@ -1,42 +0,0 @@
|
||||
The following is the MIT license, agreed upon by most contributors.
|
||||
Copyright holders of new code should use this license statement where
|
||||
possible. They may also add themselves to the list below.
|
||||
|
||||
/*
|
||||
* Copyright 1987, 1988, 1989, 1998 The Open Group
|
||||
* Copyright 1987, 1988, 1989 Digital Equipment Corporation
|
||||
* Copyright 1999, 2004, 2008 Keith Packard
|
||||
* Copyright 2000 SuSE, Inc.
|
||||
* Copyright 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
* Copyright 2004 Nicholas Miell
|
||||
* Copyright 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
* Copyright 2005 Trolltech AS
|
||||
* Copyright 2007 Luca Barbato
|
||||
* Copyright 2008 Aaron Plattner, NVIDIA Corporation
|
||||
* Copyright 2008 Rodrigo Kumpera
|
||||
* Copyright 2008 André Tupinambá
|
||||
* Copyright 2008 Mozilla Corporation
|
||||
* Copyright 2008 Frederic Plourde
|
||||
* Copyright 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2009, 2010 Nokia Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
0
vendor/pixman/ChangeLog
vendored
0
vendor/pixman/ChangeLog
vendored
234
vendor/pixman/INSTALL
vendored
234
vendor/pixman/INSTALL
vendored
@ -1,234 +0,0 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
143
vendor/pixman/Makefile.am
vendored
143
vendor/pixman/Makefile.am
vendored
@ -1,143 +0,0 @@
|
||||
SUBDIRS = pixman demos test
|
||||
|
||||
pkgconfigdir=$(libdir)/pkgconfig
|
||||
pkgconfig_DATA=pixman-1.pc
|
||||
|
||||
$(pkgconfig_DATA): pixman-1.pc.in
|
||||
|
||||
snapshot:
|
||||
distdir="$(distdir)-`date '+%Y%m%d'`"; \
|
||||
test -d "$(srcdir)/.git" && distdir=$$distdir-`cd "$(srcdir)" && git rev-parse HEAD | cut -c 1-6`; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" dist
|
||||
|
||||
GPGKEY=3892336E
|
||||
USERNAME=$$USER
|
||||
RELEASE_OR_SNAPSHOT = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo release; else echo snapshot; fi)
|
||||
RELEASE_CAIRO_HOST = $(USERNAME)@cairographics.org
|
||||
RELEASE_CAIRO_DIR = /srv/cairo.freedesktop.org/www/$(RELEASE_OR_SNAPSHOT)s
|
||||
RELEASE_CAIRO_URL = https://cairographics.org/$(RELEASE_OR_SNAPSHOT)s
|
||||
RELEASE_XORG_URL = https://www.x.org/releases/individual/lib
|
||||
RELEASE_XORG_HOST = $(USERNAME)@xorg.freedesktop.org
|
||||
RELEASE_XORG_DIR = /srv/xorg.freedesktop.org/archive/individual/lib
|
||||
RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org, xorg-announce@lists.freedesktop.org, pixman@lists.freedesktop.org
|
||||
|
||||
EXTRA_DIST = \
|
||||
Makefile.win32 \
|
||||
Makefile.win32.common \
|
||||
meson.build \
|
||||
meson_options.txt \
|
||||
neon-test.S \
|
||||
a64-neon-test.S \
|
||||
arm-simd-test.S \
|
||||
$(NULL)
|
||||
|
||||
tar_gz = $(PACKAGE)-$(VERSION).tar.gz
|
||||
tar_xz = $(PACKAGE)-$(VERSION).tar.xz
|
||||
|
||||
sha512_tgz = $(tar_gz).sha512
|
||||
sha256_tgz = $(tar_gz).sha256
|
||||
|
||||
sha512_txz = $(tar_xz).sha512
|
||||
sha256_txz = $(tar_xz).sha256
|
||||
|
||||
gpg_file = $(sha512_tgz).asc
|
||||
|
||||
$(sha512_tgz): $(tar_gz)
|
||||
sha512sum $^ > $@
|
||||
|
||||
$(sha256_tgz): $(tar_gz)
|
||||
sha256sum $^ > $@
|
||||
|
||||
$(sha512_txz): $(tar_xz)
|
||||
sha512sum $^ > $@
|
||||
|
||||
$(sha256_txz): $(tar_xz)
|
||||
sha256sum $^ > $@
|
||||
|
||||
$(gpg_file): $(sha512_tgz)
|
||||
@echo "Please enter your GPG password to sign the checksum."
|
||||
gpg --armor --sign $^
|
||||
|
||||
HASHFILES = $(sha512_tgz) $(sha512_txz) $(sha256_tgz) $(sha256_txz)
|
||||
|
||||
release-verify-newer:
|
||||
@echo -n "Checking that no $(VERSION) release already exists at $(RELEASE_XORG_HOST)..."
|
||||
@ssh $(RELEASE_XORG_HOST) test ! -e $(RELEASE_XORG_DIR)/$(tar_gz) \
|
||||
|| (echo "Ouch." && echo "Found: $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)/$(tar_gz)" \
|
||||
&& echo "Refusing to try to generate a new release of the same name." \
|
||||
&& false)
|
||||
@ssh $(RELEASE_CAIRO_HOST) test ! -e $(RELEASE_CAIRO_DIR)/$(tar_gz) \
|
||||
|| (echo "Ouch." && echo "Found: $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR)/$(tar_gz)" \
|
||||
&& echo "Refusing to try to generate a new release of the same name." \
|
||||
&& false)
|
||||
@echo "Good."
|
||||
|
||||
release-remove-old:
|
||||
$(RM) $(tar_gz) $(tar_xz) $(HASHFILES) $(gpg_file)
|
||||
|
||||
ensure-prev:
|
||||
@if [ "$(PREV)" = "" ]; then \
|
||||
echo "" && \
|
||||
echo "You must set the PREV variable on the make command line to" && \
|
||||
echo "the last version." && \
|
||||
echo "" && \
|
||||
echo "For example:" && \
|
||||
echo " make PREV=0.7.3" && \
|
||||
echo "" && \
|
||||
false; \
|
||||
fi
|
||||
|
||||
release-check: ensure-prev release-verify-newer release-remove-old distcheck
|
||||
|
||||
release-tag:
|
||||
git tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION)
|
||||
|
||||
release-upload: release-check $(tar_gz) $(tar_xz) $(sha512_tgz) $(sha512_txz) $(sha256_tgz) $(gpg_file)
|
||||
scp $(tar_gz) $(sha512_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR)
|
||||
scp $(tar_gz) $(tar_xz) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)
|
||||
ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)"
|
||||
|
||||
RELEASE_TYPE = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo "stable release in the" ; else echo "development snapshot leading up to a stable"; fi)
|
||||
|
||||
release-publish-message: $(HASHFILES) ensure-prev
|
||||
@echo "Please follow the instructions in RELEASING to push stuff out and"
|
||||
@echo "send out the announcement mails. Here is the excerpt you need:"
|
||||
@echo ""
|
||||
@echo "Lists: $(RELEASE_ANNOUNCE_LIST)"
|
||||
@echo "Subject: [ANNOUNCE] $(PACKAGE) release $(VERSION) now available"
|
||||
@echo "============================== CUT HERE =============================="
|
||||
@echo "A new $(PACKAGE) release $(VERSION) is now available. This is a $(RELEASE_TYPE)"
|
||||
@echo ""
|
||||
@echo "tar.gz:"
|
||||
@echo " $(RELEASE_CAIRO_URL)/$(tar_gz)"
|
||||
@echo " $(RELEASE_XORG_URL)/$(tar_gz)"
|
||||
@echo ""
|
||||
@echo "tar.xz:"
|
||||
@echo " $(RELEASE_XORG_URL)/$(tar_xz)"
|
||||
@echo ""
|
||||
@echo "Hashes:"
|
||||
@echo -n " SHA256: "
|
||||
@cat $(sha256_tgz)
|
||||
@echo -n " SHA256: "
|
||||
@cat $(sha256_txz)
|
||||
@echo -n " SHA512: "
|
||||
@cat $(sha512_tgz)
|
||||
@echo -n " SHA512: "
|
||||
@cat $(sha512_txz)
|
||||
@echo ""
|
||||
@echo "GPG signature:"
|
||||
@echo " $(RELEASE_CAIRO_URL)/$(gpg_file)"
|
||||
@echo " (signed by`gpg --list-keys $(GPGKEY) | grep uid | cut -b4- | tr -s " "`)"
|
||||
@echo ""
|
||||
@echo "Git:"
|
||||
@echo " https://gitlab.freedesktop.org/pixman/pixman.git"
|
||||
@echo " tag: $(PACKAGE)-$(VERSION)"
|
||||
@echo ""
|
||||
@echo "Log:"
|
||||
@git log --no-merges "$(PACKAGE)-$(PREV)".."$(PACKAGE)-$(VERSION)" | git shortlog | awk '{ printf "\t"; print ; }' | cut -b1-80
|
||||
@echo "============================== CUT HERE =============================="
|
||||
@echo ""
|
||||
|
||||
release-publish: release-upload release-tag release-publish-message
|
||||
|
||||
.PHONY: release-upload release-publish release-publish-message release-tag
|
25
vendor/pixman/Makefile.win32
vendored
25
vendor/pixman/Makefile.win32
vendored
@ -1,25 +0,0 @@
|
||||
default: all
|
||||
|
||||
top_srcdir = .
|
||||
include $(top_srcdir)/Makefile.win32.common
|
||||
|
||||
all: pixman test
|
||||
|
||||
pixman:
|
||||
@$(MAKE) -C pixman -f Makefile.win32
|
||||
|
||||
test:
|
||||
@$(MAKE) -C test -f Makefile.win32
|
||||
|
||||
clean_r:
|
||||
@$(MAKE) -C pixman -f Makefile.win32 clean
|
||||
@$(MAKE) -C test -f Makefile.win32 clean
|
||||
|
||||
check:
|
||||
@$(MAKE) -C test -f Makefile.win32 check
|
||||
|
||||
|
||||
clean: clean_r
|
||||
|
||||
|
||||
.PHONY: all pixman test clean check
|
73
vendor/pixman/Makefile.win32.common
vendored
73
vendor/pixman/Makefile.win32.common
vendored
@ -1,73 +0,0 @@
|
||||
LIBRARY = pixman-1
|
||||
|
||||
ifeq ($(shell echo ""),)
|
||||
# POSIX style shell
|
||||
mkdir_p = mkdir -p $1
|
||||
rm = $(RM) $1
|
||||
echo = echo "$1"
|
||||
else
|
||||
# DOS/Windows style shell
|
||||
mkdir_p = if not exist $(subst /,\,$1) md $(subst /,\,$1)
|
||||
echo = echo $1
|
||||
rm = del $(subst /,\,$1)
|
||||
endif
|
||||
|
||||
CC = cl
|
||||
LD = link
|
||||
AR = lib
|
||||
PERL = perl
|
||||
|
||||
ifneq ($(shell echo ""),)
|
||||
RM = del
|
||||
endif
|
||||
|
||||
ifeq ($(top_builddir),)
|
||||
top_builddir = $(top_srcdir)
|
||||
endif
|
||||
|
||||
CFG_VAR = $(CFG)
|
||||
ifeq ($(CFG_VAR),)
|
||||
CFG_VAR = release
|
||||
endif
|
||||
|
||||
ifeq ($(CFG_VAR),debug)
|
||||
CFG_CFLAGS = -MDd -Od -Zi
|
||||
CFG_LDFLAGS = -DEBUG
|
||||
else
|
||||
CFG_CFLAGS = -MD -O2
|
||||
CFG_LDFLAGS =
|
||||
endif
|
||||
|
||||
# Package definitions, to be used instead of those provided in config.h
|
||||
PKG_CFLAGS = -DPACKAGE=$(LIBRARY) -DPACKAGE_VERSION="" -DPACKAGE_BUGREPORT=""
|
||||
|
||||
BASE_CFLAGS = -nologo -I. -I$(top_srcdir) -I$(top_srcdir)/pixman
|
||||
|
||||
PIXMAN_CFLAGS = $(BASE_CFLAGS) $(PKG_CFLAGS) $(CFG_CFLAGS) $(CFLAGS)
|
||||
PIXMAN_LDFLAGS = -nologo $(CFG_LDFLAGS) $(LDFLAGS)
|
||||
PIXMAN_ARFLAGS = -nologo $(LDFLAGS)
|
||||
|
||||
|
||||
inform:
|
||||
ifneq ($(CFG),release)
|
||||
ifneq ($(CFG),debug)
|
||||
ifneq ($(CFG),)
|
||||
@echo "Invalid specified configuration option: "$(CFG)"."
|
||||
@echo
|
||||
@echo "Possible choices for configuration are 'release' and 'debug'"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Using default RELEASE configuration... (use CFG=release or CFG=debug)"
|
||||
endif
|
||||
endif
|
||||
|
||||
$(CFG_VAR):
|
||||
@$(call mkdir_p,$@)
|
||||
|
||||
$(CFG_VAR)/%.obj: %.c $(libpixman_headers) | $(CFG_VAR)
|
||||
$(CC) -c $(PIXMAN_CFLAGS) -Fo"$@" $<
|
||||
|
||||
clean: inform $(CFG_VAR)
|
||||
-$(call rm,$(CFG_VAR)/*.exe $(CFG_VAR)/*.ilk $(CFG_VAR)/*.lib $(CFG_VAR)/*.obj $(CFG_VAR)/*.pdb)
|
||||
|
||||
.PHONY: inform clean
|
0
vendor/pixman/NEWS
vendored
0
vendor/pixman/NEWS
vendored
140
vendor/pixman/README
vendored
140
vendor/pixman/README
vendored
@ -1,140 +0,0 @@
|
||||
Pixman
|
||||
======
|
||||
|
||||
Pixman is a library that provides low-level pixel manipulation
|
||||
features such as image compositing and trapezoid rasterization.
|
||||
|
||||
Questions should be directed to the pixman mailing list:
|
||||
|
||||
https://lists.freedesktop.org/mailman/listinfo/pixman
|
||||
|
||||
You can also file bugs at
|
||||
|
||||
https://gitlab.freedesktop.org/pixman/pixman/-/issues/new
|
||||
|
||||
or submit improvements in form of a Merge Request via
|
||||
|
||||
https://gitlab.freedesktop.org/pixman/pixman/-/merge_requests
|
||||
|
||||
For real time discussions about pixman, feel free to join the IRC
|
||||
channels #cairo and #xorg-devel on the FreeNode IRC network.
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
In order to contribute to pixman, you will need a working knowledge of
|
||||
the git version control system. For a quick getting started guide,
|
||||
there is the "Everyday Git With 20 Commands Or So guide"
|
||||
|
||||
https://www.kernel.org/pub/software/scm/git/docs/everyday.html
|
||||
|
||||
from the Git homepage. For more in depth git documentation, see the
|
||||
resources on the Git community documentation page:
|
||||
|
||||
https://git-scm.com/documentation
|
||||
|
||||
Pixman uses the infrastructure from the freedesktop.org umbrella
|
||||
project. For instructions about how to use the git service on
|
||||
freedesktop.org, see:
|
||||
|
||||
https://www.freedesktop.org/wiki/Infrastructure/git/Developers
|
||||
|
||||
The Pixman master repository can be found at:
|
||||
|
||||
https://gitlab.freedesktop.org/pixman/pixman
|
||||
|
||||
|
||||
Sending patches
|
||||
---------------
|
||||
|
||||
Patches should be submitted in form of Merge Requests via Gitlab.
|
||||
|
||||
You will first need to create a fork of the main pixman repository at
|
||||
|
||||
https://gitlab.freedesktop.org/pixman/pixman
|
||||
|
||||
via the Fork button on the top right. Once that is done you can add your
|
||||
personal repository as a remote to your local pixman development git checkout:
|
||||
|
||||
git remote add my-gitlab git@gitlab.freedesktop.org:YOURUSERNAME/pixman.git
|
||||
|
||||
git fetch my-gitlab
|
||||
|
||||
Make sure to have added ssh keys to your gitlab profile at
|
||||
|
||||
https://gitlab.freedesktop.org/profile/keys
|
||||
|
||||
Once that is set up, the general workflow for sending patches is to create a
|
||||
new local branch with your improvements and once it's ready push it to your
|
||||
personal pixman fork:
|
||||
|
||||
git checkout -b fix-some-bug
|
||||
...
|
||||
git push my-gitlab
|
||||
|
||||
The output of the `git push` command will include a link that allows you to
|
||||
create a Merge Request against the official pixman repository.
|
||||
|
||||
Whenever you make changes to your branch (add new commits or fix up commits)
|
||||
you push them back to your personal pixman fork:
|
||||
|
||||
git push -f my-gitlab
|
||||
|
||||
If there is an open Merge Request Gitlab will automatically pick up the
|
||||
changes from your branch and pixman developers can review them anew.
|
||||
|
||||
In order for your patches to be accepted, please consider the
|
||||
following guidelines:
|
||||
|
||||
- At each point in the series, pixman should compile and the test
|
||||
suite should pass.
|
||||
|
||||
The exception here is if you are changing the test suite to
|
||||
demonstrate a bug. In this case, make one commit that makes the
|
||||
test suite fail due to the bug, and then another commit that fixes
|
||||
the bug.
|
||||
|
||||
You can run the test suite with
|
||||
|
||||
make check
|
||||
|
||||
if you built pixman with autotools or
|
||||
|
||||
meson test -C builddir
|
||||
|
||||
if you built pixman with meson.
|
||||
|
||||
It will take around two minutes to run on a modern PC.
|
||||
|
||||
- Follow the coding style described in the CODING_STYLE file
|
||||
|
||||
- For bug fixes, include an update to the test suite to make sure
|
||||
the bug doesn't reappear.
|
||||
|
||||
- For new features, add tests of the feature to the test
|
||||
suite. Also, add a program demonstrating the new feature to the
|
||||
demos/ directory.
|
||||
|
||||
- Write descriptive commit messages. Useful information to include:
|
||||
- Benchmark results, before and after
|
||||
- Description of the bug that was fixed
|
||||
- Detailed rationale for any new API
|
||||
- Alternative approaches that were rejected (and why they
|
||||
don't work)
|
||||
- If review comments were incorporated, a brief version
|
||||
history describing what those changes were.
|
||||
|
||||
- For big patch series, write an introductory post with an overall
|
||||
description of the patch series, including benchmarks and
|
||||
motivation. Each commit message should still be descriptive and
|
||||
include enough information to understand why this particular commit
|
||||
was necessary.
|
||||
|
||||
Pixman has high standards for code quality and so almost everybody
|
||||
should expect to have the first versions of their patches rejected.
|
||||
|
||||
If you think that the reviewers are wrong about something, or that the
|
||||
guidelines above are wrong, feel free to discuss the issue. The purpose
|
||||
of the guidelines and code review is to ensure high code quality; it is
|
||||
not an exercise in compliance.
|
59
vendor/pixman/RELEASING
vendored
59
vendor/pixman/RELEASING
vendored
@ -1,59 +0,0 @@
|
||||
Here are the steps to follow to create a new pixman release:
|
||||
|
||||
1) Ensure that there are no uncommitted changes or unpushed commits,
|
||||
and that you are up to date with the latest commits in the central
|
||||
repository. Here are a couple of useful commands:
|
||||
|
||||
git diff (no output)
|
||||
|
||||
git status (should report "nothing to commit")
|
||||
|
||||
git log master...origin (no output; note: *3* dots)
|
||||
|
||||
2) Increment pixman_(major|minor|micro) in configure.ac and meson.build
|
||||
according to the directions in those files.
|
||||
|
||||
3) Make sure that new version works, including
|
||||
|
||||
- make distcheck passes
|
||||
|
||||
- the X server still works with the new pixman version
|
||||
installed
|
||||
|
||||
- the cairo test suite hasn't gained any new failures compared
|
||||
to last pixman version.
|
||||
|
||||
4) Use "git commit" to record the changes made in step 2 and 3.
|
||||
|
||||
5) Generate and publish the tar files by running
|
||||
|
||||
make PREV=<last version> GPGKEY=<your gpg key id> release-publish
|
||||
|
||||
If your freedesktop user name is different from your local one,
|
||||
then also set the variable USER to your freedesktop user name.
|
||||
|
||||
6) Run
|
||||
|
||||
make release-publish-message
|
||||
|
||||
to generate a draft release announcement. Edit it as appropriate and
|
||||
send it to
|
||||
|
||||
cairo-announce@cairographics.org
|
||||
|
||||
pixman@lists.freedesktop.org
|
||||
|
||||
xorg-announce@lists.freedesktop.org
|
||||
|
||||
7) Increment pixman_micro to the next larger (odd) number in
|
||||
configure.ac. Commit this change, and push all commits created
|
||||
during this process using
|
||||
|
||||
git push
|
||||
git push --tags
|
||||
|
||||
You must use "--tags" here; otherwise the new tag will not
|
||||
be pushed out.
|
||||
|
||||
8) Change the topic of the #cairo IRC channel on freenode to advertise
|
||||
the new version.
|
5
vendor/pixman/a64-neon-test.S
vendored
5
vendor/pixman/a64-neon-test.S
vendored
@ -1,5 +0,0 @@
|
||||
.text
|
||||
.arch armv8-a
|
||||
.altmacro
|
||||
prfm pldl2strm, [x0]
|
||||
xtn v0.8b, v0.8h
|
10
vendor/pixman/arm-simd-test.S
vendored
10
vendor/pixman/arm-simd-test.S
vendored
@ -1,10 +0,0 @@
|
||||
.text
|
||||
.arch armv6
|
||||
.object_arch armv4
|
||||
.arm
|
||||
.altmacro
|
||||
#ifndef __ARM_EABI__
|
||||
#error EABI is required (to be sure that calling conventions are compatible)
|
||||
#endif
|
||||
pld [r0]
|
||||
uqadd8 r0, r0, r0
|
14
vendor/pixman/autogen.sh
vendored
14
vendor/pixman/autogen.sh
vendored
@ -1,14 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
ORIGDIR=`pwd`
|
||||
cd $srcdir
|
||||
|
||||
autoreconf -v --install || exit 1
|
||||
cd $ORIGDIR || exit $?
|
||||
|
||||
if test -z "$NOCONFIGURE"; then
|
||||
$srcdir/configure "$@"
|
||||
fi
|
1199
vendor/pixman/configure.ac
vendored
1199
vendor/pixman/configure.ac
vendored
File diff suppressed because it is too large
Load Diff
581
vendor/pixman/meson.build
vendored
581
vendor/pixman/meson.build
vendored
@ -1,581 +0,0 @@
|
||||
# Copyright © 2018 Intel Corporation
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
project(
|
||||
'pixman',
|
||||
['c'],
|
||||
version : '0.42.3',
|
||||
license : 'MIT',
|
||||
meson_version : '>= 0.52.0',
|
||||
default_options : ['c_std=gnu99', 'buildtype=debugoptimized'],
|
||||
)
|
||||
|
||||
config = configuration_data()
|
||||
cc = meson.get_compiler('c')
|
||||
null_dep = dependency('', required : false)
|
||||
|
||||
add_project_arguments(
|
||||
cc.get_supported_arguments([
|
||||
'-Wdeclaration-after-statement',
|
||||
'-fno-strict-aliasing',
|
||||
'-fvisibility=hidden',
|
||||
'-Wundef',
|
||||
# -ftrapping-math is the default for gcc, but -fno-trapping-math is the
|
||||
# default for clang. The FLOAT_IS_ZERO macro is used to guard against
|
||||
# floating-point exceptions, however with -fno-trapping-math, the compiler
|
||||
# can reorder floating-point operations so that they occur before the guard.
|
||||
# Note, this function is ignored in clang < 10.0.0.
|
||||
'-ftrapping-math'
|
||||
]),
|
||||
language : ['c']
|
||||
)
|
||||
|
||||
# GCC and Clang both ignore -Wno options that they don't recognize, so test for
|
||||
# -W<opt>, then add -Wno-<opt> if it's ignored
|
||||
foreach opt : ['unused-local-typedefs']
|
||||
if cc.has_argument('-W' + opt)
|
||||
add_project_arguments(['-Wno-' + opt], language : ['c'])
|
||||
endif
|
||||
endforeach
|
||||
|
||||
use_loongson_mmi = get_option('loongson-mmi')
|
||||
have_loongson_mmi = false
|
||||
loongson_mmi_flags = ['-mloongson-mmi']
|
||||
if not use_loongson_mmi.disabled()
|
||||
if host_machine.cpu_family() == 'mips64' and cc.compiles('''
|
||||
#ifndef __mips_loongson_vector_rev
|
||||
#error "Loongson Multimedia Instructions are only available on Loongson"
|
||||
#endif
|
||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
|
||||
#error "Need GCC >= 4.4 for Loongson MMI compilation"
|
||||
#endif
|
||||
#include "pixman/loongson-mmintrin.h"
|
||||
int main () {
|
||||
union {
|
||||
__m64 v;
|
||||
char c[8];
|
||||
} a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} };
|
||||
int b = 4;
|
||||
__m64 c = _mm_srli_pi16 (a.v, b);
|
||||
return 0;
|
||||
}''',
|
||||
args : loongson_mmi_flags,
|
||||
include_directories : include_directories('.'),
|
||||
name : 'Loongson MMI Intrinsic Support')
|
||||
have_loongson_mmi = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_loongson_mmi
|
||||
config.set10('USE_LOONGSON_MMI', true)
|
||||
elif use_loongson_mmi.enabled()
|
||||
error('Loongson MMI Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_mmx = get_option('mmx')
|
||||
have_mmx = false
|
||||
mmx_flags = []
|
||||
|
||||
if cc.get_id() == 'msvc'
|
||||
mmx_flags = ['/w14710', '/w14714', '/wd4244']
|
||||
elif cc.get_id() == 'sun'
|
||||
mmx_flags = ['-xarch=sse']
|
||||
else
|
||||
mmx_flags = ['-mmmx', '-Winline']
|
||||
endif
|
||||
if not use_mmx.disabled()
|
||||
if host_machine.cpu_family() == 'x86_64' or cc.get_id() == 'msvc'
|
||||
have_mmx = true
|
||||
elif host_machine.cpu_family() == 'x86' and cc.compiles('''
|
||||
#include <mmintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Check support for block expressions */
|
||||
#define _mm_shuffle_pi16(A, N) \
|
||||
({ \
|
||||
__m64 ret; \
|
||||
\
|
||||
/* Some versions of clang will choke on K */ \
|
||||
asm ("pshufw %2, %1, %0\n\t" \
|
||||
: "=y" (ret) \
|
||||
: "y" (A), "K" ((const int8_t)N) \
|
||||
); \
|
||||
\
|
||||
ret; \
|
||||
})
|
||||
|
||||
int main () {
|
||||
__m64 v = _mm_cvtsi32_si64 (1);
|
||||
__m64 w;
|
||||
|
||||
w = _mm_shuffle_pi16(v, 5);
|
||||
|
||||
/* Some versions of clang will choke on this */
|
||||
asm ("pmulhuw %1, %0\n\t"
|
||||
: "+y" (w)
|
||||
: "y" (v)
|
||||
);
|
||||
|
||||
return _mm_cvtsi64_si32 (v);
|
||||
}''',
|
||||
args : mmx_flags,
|
||||
name : 'MMX Intrinsic Support')
|
||||
have_mmx = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_mmx
|
||||
# Inline assembly do not work on X64 MSVC, so we use
|
||||
# compatibility intrinsics there
|
||||
if cc.get_id() != 'msvc' or host_machine.cpu_family() != 'x86_64'
|
||||
config.set10('USE_X86_MMX', true)
|
||||
endif
|
||||
elif use_mmx.enabled()
|
||||
error('MMX Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_sse2 = get_option('sse2')
|
||||
have_sse2 = false
|
||||
sse2_flags = []
|
||||
if cc.get_id() == 'sun'
|
||||
sse2_flags = ['-xarch=sse2']
|
||||
elif cc.get_id() != 'msvc'
|
||||
sse2_flags = ['-msse2', '-Winline']
|
||||
endif
|
||||
if not use_sse2.disabled()
|
||||
if host_machine.cpu_family() == 'x86'
|
||||
if cc.compiles('''
|
||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
|
||||
# if !defined(__amd64__) && !defined(__x86_64__)
|
||||
# error "Need GCC >= 4.2 for SSE2 intrinsics on x86"
|
||||
# endif
|
||||
#endif
|
||||
#include <mmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
int param;
|
||||
int main () {
|
||||
__m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c;
|
||||
c = _mm_xor_si128 (a, b);
|
||||
return _mm_cvtsi128_si32(c);
|
||||
}''',
|
||||
args : sse2_flags,
|
||||
name : 'SSE2 Intrinsic Support')
|
||||
have_sse2 = true
|
||||
endif
|
||||
elif host_machine.cpu_family() == 'x86_64'
|
||||
have_sse2 = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_sse2
|
||||
config.set10('USE_SSE2', true)
|
||||
elif use_sse2.enabled()
|
||||
error('sse2 Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_ssse3 = get_option('ssse3')
|
||||
have_ssse3 = false
|
||||
ssse3_flags = []
|
||||
if cc.get_id() != 'msvc'
|
||||
ssse3_flags = ['-mssse3', '-Winline']
|
||||
endif
|
||||
|
||||
# x64 pre-2010 MSVC compilers crashes when building the ssse3 code
|
||||
if not use_ssse3.disabled() and not (cc.get_id() == 'msvc' and cc.version().version_compare('<16') and host_machine.cpu_family() == 'x86_64')
|
||||
if host_machine.cpu_family().startswith('x86')
|
||||
if cc.compiles('''
|
||||
#include <mmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
int param;
|
||||
int main () {
|
||||
__m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c;
|
||||
c = _mm_xor_si128 (a, b);
|
||||
return _mm_cvtsi128_si32(c);
|
||||
}''',
|
||||
args : ssse3_flags,
|
||||
name : 'SSSE3 Intrinsic Support')
|
||||
have_ssse3 = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_ssse3
|
||||
config.set10('USE_SSSE3', true)
|
||||
elif use_ssse3.enabled()
|
||||
error('ssse3 Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_vmx = get_option('vmx')
|
||||
have_vmx = false
|
||||
vmx_flags = ['-maltivec', '-mabi=altivec']
|
||||
if not use_vmx.disabled()
|
||||
if host_machine.cpu_family().startswith('ppc')
|
||||
if cc.compiles('''
|
||||
#include <altivec.h>
|
||||
int main () {
|
||||
vector unsigned int v = vec_splat_u32 (1);
|
||||
v = vec_sub (v, v);
|
||||
return 0;
|
||||
}''',
|
||||
args : vmx_flags,
|
||||
name : 'VMX/Altivec Intrinsic Support')
|
||||
have_vmx = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_vmx
|
||||
config.set10('USE_VMX', true)
|
||||
elif use_vmx.enabled()
|
||||
error('vmx Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_armv6_simd = get_option('arm-simd')
|
||||
have_armv6_simd = false
|
||||
if not use_armv6_simd.disabled()
|
||||
if host_machine.cpu_family() == 'arm'
|
||||
if cc.compiles(files('arm-simd-test.S'), name : 'ARMv6 SIMD Intrinsic Support')
|
||||
have_armv6_simd = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_armv6_simd
|
||||
config.set10('USE_ARM_SIMD', true)
|
||||
elif use_armv6_simd.enabled()
|
||||
error('ARMv6 SIMD Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_neon = get_option('neon')
|
||||
have_neon = false
|
||||
if not use_neon.disabled()
|
||||
if host_machine.cpu_family() == 'arm'
|
||||
if cc.compiles(files('neon-test.S'), name : 'NEON Intrinsic Support')
|
||||
have_neon = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_neon
|
||||
config.set10('USE_ARM_NEON', true)
|
||||
elif use_neon.enabled()
|
||||
error('NEON Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_a64neon = get_option('a64-neon')
|
||||
have_a64neon = false
|
||||
if not use_a64neon.disabled()
|
||||
if host_machine.cpu_family() == 'aarch64'
|
||||
if cc.compiles(files('a64-neon-test.S'), name : 'NEON A64 Intrinsic Support')
|
||||
have_a64neon = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_a64neon
|
||||
config.set10('USE_ARM_A64_NEON', true)
|
||||
elif use_a64neon.enabled()
|
||||
error('A64 NEON Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_iwmmxt = get_option('iwmmxt')
|
||||
have_iwmmxt = false
|
||||
iwmmxt_flags = ['-flax-vector-conversions', '-Winline']
|
||||
if not use_iwmmxt.disabled()
|
||||
if get_option('iwmmxt2')
|
||||
iwmmxt_flags += '-march=iwmmxt2'
|
||||
else
|
||||
iwmmxt_flags += '-march=iwmmxt'
|
||||
endif
|
||||
|
||||
if host_machine.cpu_family() == 'arm'
|
||||
if cc.compiles('''
|
||||
#ifndef __IWMMXT__
|
||||
#error "IWMMXT not enabled (with -march=iwmmxt)"
|
||||
#endif
|
||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
|
||||
#error "Need GCC >= 4.8 for IWMMXT intrinsics"
|
||||
#endif
|
||||
#include <mmintrin.h>
|
||||
int main () {
|
||||
union {
|
||||
__m64 v;
|
||||
char c[8];
|
||||
} a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} };
|
||||
int b = 4;
|
||||
__m64 c = _mm_srli_si64 (a.v, b);
|
||||
}
|
||||
''',
|
||||
args : iwmmxt_flags,
|
||||
name : 'IWMMXT Intrinsic Support')
|
||||
have_iwmmxt = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_iwmmxt
|
||||
config.set10('USE_ARM_IWMMXT', true)
|
||||
elif use_iwmmxt.enabled()
|
||||
error('IWMMXT Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_mips_dspr2 = get_option('mips-dspr2')
|
||||
have_mips_dspr2 = false
|
||||
mips_dspr2_flags = ['-mdspr2']
|
||||
if not use_mips_dspr2.disabled()
|
||||
if host_machine.cpu_family() == 'mips32'
|
||||
if cc.compiles('''
|
||||
#if !(defined(__mips__) && __mips_isa_rev >= 2)
|
||||
#error MIPS DSPr2 is currently only available on MIPS32r2 platforms.
|
||||
#endif
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int c = 0, a = 0, b = 0;
|
||||
__asm__ __volatile__ (
|
||||
"precr.qb.ph %[c], %[a], %[b] \n\t"
|
||||
: [c] "=r" (c)
|
||||
: [a] "r" (a), [b] "r" (b)
|
||||
);
|
||||
return c;
|
||||
}''',
|
||||
args : mipds_dspr2_flags,
|
||||
name : 'DSPr2 Intrinsic Support')
|
||||
have_mips_dspr2 = true
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_mips_dspr2
|
||||
config.set10('USE_MIPS_DSPR2', true)
|
||||
elif use_mips_dspr2.enabled()
|
||||
error('MIPS DSPr2 Support unavailable, but required')
|
||||
endif
|
||||
|
||||
use_gnu_asm = get_option('gnu-inline-asm')
|
||||
if not use_gnu_asm.disabled()
|
||||
if cc.compiles('''
|
||||
int main () {
|
||||
/* Most modern architectures have a NOP instruction, so this is a fairly generic test. */
|
||||
asm volatile ( "\tnop\n" : : : "cc", "memory" );
|
||||
return 0;
|
||||
}
|
||||
''',
|
||||
name : 'GNU Inline ASM support.')
|
||||
config.set10('USE_GCC_INLINE_ASM', true)
|
||||
elif use_gnu_asm.enabled()
|
||||
error('GNU inline assembly support missing but required.')
|
||||
endif
|
||||
endif
|
||||
|
||||
if get_option('timers')
|
||||
config.set('PIXMAN_TIMERS', 1)
|
||||
endif
|
||||
if get_option('gnuplot')
|
||||
config.set('PIXMAN_GNUPLOT', 1)
|
||||
endif
|
||||
|
||||
if cc.get_id() != 'msvc'
|
||||
dep_openmp = dependency('openmp', required : get_option('openmp'))
|
||||
if dep_openmp.found()
|
||||
config.set10('USE_OPENMP', true)
|
||||
elif meson.version().version_compare('<0.51.0')
|
||||
# In versions of meson before 0.51 the openmp dependency can still
|
||||
# inject arguments in the the auto case when it is not found, the
|
||||
# detection does work correctly in that case however, so we just
|
||||
# replace dep_openmp with null_dep to work around this.
|
||||
dep_openmp = null_dep
|
||||
endif
|
||||
else
|
||||
# the MSVC implementation of openmp is not compliant enough for our
|
||||
# uses here, so we disable it here.
|
||||
# Please see: https://stackoverflow.com/questions/12560243/using-threadprivate-directive-in-visual-studio
|
||||
dep_openmp = null_dep
|
||||
endif
|
||||
|
||||
dep_gtk = dependency('gtk+-3.0', required : get_option('gtk'), required: get_option('demos'))
|
||||
dep_glib = dependency('glib-2.0', required : get_option('gtk'), required: get_option('demos'))
|
||||
|
||||
dep_png = null_dep
|
||||
if not get_option('libpng').disabled()
|
||||
dep_png = dependency('libpng', required : false)
|
||||
|
||||
# We need to look for the right library to link to for libpng,
|
||||
# when looking for libpng manually
|
||||
foreach png_ver : [ '16', '15', '14', '13', '12', '10' ]
|
||||
if not dep_png.found()
|
||||
dep_png = cc.find_library('libpng@0@'.format(png_ver), has_headers : ['png.h'], required : false)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if get_option('libpng').enabled() and not dep_png.found()
|
||||
error('libpng support requested but libpng library not found')
|
||||
endif
|
||||
endif
|
||||
|
||||
if dep_png.found()
|
||||
config.set('HAVE_LIBPNG', 1)
|
||||
endif
|
||||
dep_m = cc.find_library('m', required : false)
|
||||
dep_threads = dependency('threads')
|
||||
|
||||
# MSVC-style compilers do not come with pthreads, so we must link
|
||||
# to it explicitly, currently pthreads-win32 is supported
|
||||
pthreads_found = false
|
||||
|
||||
if dep_threads.found() and cc.has_header('pthread.h')
|
||||
if cc.get_argument_syntax() == 'msvc'
|
||||
pthread_lib = null_dep
|
||||
foreach pthread_type : ['VC3', 'VSE3', 'VCE3', 'VC2', 'VSE2', 'VCE2']
|
||||
if not pthread_lib.found()
|
||||
pthread_lib = cc.find_library('pthread@0@'.format(pthread_type), required : false)
|
||||
endif
|
||||
endforeach
|
||||
if pthread_lib.found()
|
||||
pthreads_found = true
|
||||
dep_threads = pthread_lib
|
||||
endif
|
||||
else
|
||||
pthreads_found = true
|
||||
endif
|
||||
endif
|
||||
|
||||
if pthreads_found
|
||||
config.set('HAVE_PTHREADS', 1)
|
||||
endif
|
||||
|
||||
funcs = ['sigaction', 'alarm', 'mprotect', 'getpagesize', 'mmap', 'getisax', 'gettimeofday']
|
||||
# mingw claimes to have posix_memalign, but it doesn't
|
||||
if host_machine.system() != 'windows'
|
||||
funcs += 'posix_memalign'
|
||||
endif
|
||||
|
||||
foreach f : funcs
|
||||
if cc.has_function(f)
|
||||
config.set('HAVE_@0@'.format(f.to_upper()), 1)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
# This is only used in one test, that defines _GNU_SOURCE
|
||||
if cc.has_function('feenableexcept',
|
||||
prefix : '#define _GNU_SOURCE\n#include <fenv.h>',
|
||||
dependencies : dep_m)
|
||||
config.set('HAVE_FEENABLEEXCEPT', 1)
|
||||
endif
|
||||
|
||||
if cc.has_header_symbol('fenv.h', 'FE_DIVBYZERO')
|
||||
config.set('HAVE_FEDIVBYZERO', 1)
|
||||
endif
|
||||
|
||||
foreach h : ['sys/mman.h', 'fenv.h', 'unistd.h']
|
||||
if cc.check_header(h)
|
||||
config.set('HAVE_@0@'.format(h.underscorify().to_upper()), 1)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
use_tls = get_option('tls')
|
||||
have_tls = ''
|
||||
if not use_tls.disabled()
|
||||
# gcc on Windows only warns that __declspec(thread) isn't supported,
|
||||
# passing -Werror=attributes makes it fail.
|
||||
if (host_machine.system() == 'windows' and
|
||||
cc.compiles('int __declspec(thread) foo;',
|
||||
args : cc.get_supported_arguments(['-Werror=attributes']),
|
||||
name : 'TLS via __declspec(thread)'))
|
||||
have_tls = '__declspec(thread)'
|
||||
elif cc.compiles('int __thread foo;', name : 'TLS via __thread')
|
||||
have_tls = '__thread'
|
||||
endif
|
||||
endif
|
||||
|
||||
if have_tls != ''
|
||||
config.set('TLS', have_tls)
|
||||
elif use_tls.enabled()
|
||||
error('Compiler TLS Support unavailable, but required')
|
||||
endif
|
||||
|
||||
if cc.links('''
|
||||
static int x = 1;
|
||||
static void __attribute__((constructor)) constructor_function () { x = 0; }
|
||||
int main (void) { return x; }
|
||||
''',
|
||||
name : '__attribute__((constructor))')
|
||||
config.set('TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR', 1)
|
||||
endif
|
||||
|
||||
if cc.links(
|
||||
' __float128 a = 1.0Q, b = 2.0Q; int main (void) { return a + b; }',
|
||||
name : 'Has float128 support')
|
||||
config.set('HAVE_FLOAT128', 1)
|
||||
endif
|
||||
|
||||
if cc.has_function('clz')
|
||||
config.set('HAVE_BUILTIN_CLZ', 1)
|
||||
endif
|
||||
|
||||
if cc.links('''
|
||||
unsigned int __attribute__ ((vector_size(16))) e, a, b;
|
||||
int main (void) { e = a - ((b << 27) + (b >> (32 - 27))) + 1; return e[0]; }
|
||||
''',
|
||||
name : 'Support for GCC vector extensions')
|
||||
config.set('HAVE_GCC_VECTOR_EXTENSIONS', 1)
|
||||
endif
|
||||
|
||||
if host_machine.endian() == 'big'
|
||||
config.set('WORDS_BIGENDIAN', 1)
|
||||
endif
|
||||
|
||||
config.set('SIZEOF_LONG', cc.sizeof('long'))
|
||||
|
||||
# Required to make pixman-private.h
|
||||
config.set('PACKAGE', 'foo')
|
||||
|
||||
version_conf = configuration_data()
|
||||
split = meson.project_version().split('.')
|
||||
version_conf.set('PIXMAN_VERSION_MAJOR', split[0])
|
||||
version_conf.set('PIXMAN_VERSION_MINOR', split[1])
|
||||
version_conf.set('PIXMAN_VERSION_MICRO', split[2])
|
||||
|
||||
add_project_arguments('-DHAVE_CONFIG_H', language : ['c'])
|
||||
|
||||
subdir('pixman')
|
||||
|
||||
if not get_option('tests').disabled() or not get_option('demos').disabled()
|
||||
subdir(join_paths('test', 'utils'))
|
||||
endif
|
||||
|
||||
if not get_option('demos').disabled()
|
||||
subdir('demos')
|
||||
endif
|
||||
|
||||
if not get_option('tests').disabled()
|
||||
subdir('test')
|
||||
endif
|
||||
|
||||
pkg = import('pkgconfig')
|
||||
pkg.generate(libpixman,
|
||||
name : 'Pixman',
|
||||
filebase : 'pixman-1',
|
||||
description : 'The pixman library (version 1)',
|
||||
subdirs: 'pixman-1',
|
||||
version : meson.project_version(),
|
||||
)
|
128
vendor/pixman/meson_options.txt
vendored
128
vendor/pixman/meson_options.txt
vendored
@ -1,128 +0,0 @@
|
||||
# Copyright © 2018 Intel Corporation
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
option(
|
||||
'loongson-mmi',
|
||||
type : 'feature',
|
||||
description : 'Use Loongson MMI intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'mmx',
|
||||
type : 'feature',
|
||||
description : 'Use X86 MMX intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'sse2',
|
||||
type : 'feature',
|
||||
description : 'Use X86 SSE2 intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'ssse3',
|
||||
type : 'feature',
|
||||
description : 'Use X86 SSSE3 intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'vmx',
|
||||
type : 'feature',
|
||||
description : 'Use PPC VMX/Altivec intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'arm-simd',
|
||||
type : 'feature',
|
||||
description : 'Use ARMv6 SIMD intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'neon',
|
||||
type : 'feature',
|
||||
description : 'Use ARM NEON intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'a64-neon',
|
||||
type : 'feature',
|
||||
description : 'Use ARM A64 NEON intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'iwmmxt',
|
||||
type : 'feature',
|
||||
description : 'Use ARM IWMMXT intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'iwmmxt2',
|
||||
type : 'boolean',
|
||||
value : true,
|
||||
description : 'Use ARM IWMMXT2 intrinsic instead of IWMMXT',
|
||||
)
|
||||
option(
|
||||
'mips-dspr2',
|
||||
type : 'feature',
|
||||
description : 'Use MIPS32 DSPr2 intrinsic optimized paths',
|
||||
)
|
||||
option(
|
||||
'gnu-inline-asm',
|
||||
type : 'feature',
|
||||
description : 'Use GNU style inline assembler',
|
||||
)
|
||||
option(
|
||||
'tls',
|
||||
type : 'feature',
|
||||
description : 'Use compiler support for thread-local storage',
|
||||
)
|
||||
option(
|
||||
'cpu-features-path',
|
||||
type : 'string',
|
||||
description : 'Path to platform-specific cpu-features.[ch] for systems that do not provide it (e.g. Android)',
|
||||
)
|
||||
option(
|
||||
'openmp',
|
||||
type : 'feature',
|
||||
description : 'Enable OpenMP for tests',
|
||||
)
|
||||
option(
|
||||
'timers',
|
||||
type : 'boolean',
|
||||
value : false,
|
||||
description : 'Enable TIMER_* macros',
|
||||
)
|
||||
option(
|
||||
'gnuplot',
|
||||
type : 'boolean',
|
||||
value : false,
|
||||
description : 'Enable output of filters that can be piped to gnuplot',
|
||||
)
|
||||
option(
|
||||
'gtk',
|
||||
type : 'feature',
|
||||
description : 'Enable demos using GTK',
|
||||
)
|
||||
option(
|
||||
'libpng',
|
||||
type : 'feature',
|
||||
description : 'Use libpng in tests'
|
||||
)
|
||||
option(
|
||||
'tests',
|
||||
type : 'feature',
|
||||
description : 'Build tests'
|
||||
)
|
||||
option(
|
||||
'demos',
|
||||
type : 'feature',
|
||||
description : 'Build demos'
|
||||
)
|
12
vendor/pixman/neon-test.S
vendored
12
vendor/pixman/neon-test.S
vendored
@ -1,12 +0,0 @@
|
||||
.text
|
||||
.fpu neon
|
||||
.arch armv7a
|
||||
.object_arch armv4
|
||||
.eabi_attribute 10, 0
|
||||
.arm
|
||||
.altmacro
|
||||
#ifndef __ARM_EABI__
|
||||
#error EABI is required (to be sure that calling conventions are compatible)
|
||||
#endif
|
||||
pld [r0]
|
||||
vmovn.u16 d0, q0
|
5
vendor/pixman/pixman-1-uninstalled.pc.in
vendored
5
vendor/pixman/pixman-1-uninstalled.pc.in
vendored
@ -1,5 +0,0 @@
|
||||
Name: Pixman
|
||||
Description: The pixman library (version 1)
|
||||
Version: @PACKAGE_VERSION@
|
||||
Cflags: -I${pc_top_builddir}/${pcfiledir}/pixman
|
||||
Libs: ${pc_top_builddir}/${pcfiledir}/pixman/libpixman-1.la
|
11
vendor/pixman/pixman-1.pc.in
vendored
11
vendor/pixman/pixman-1.pc.in
vendored
@ -1,11 +0,0 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: Pixman
|
||||
Description: The pixman library (version 1)
|
||||
Version: @PACKAGE_VERSION@
|
||||
Cflags: -I${includedir}/pixman-1
|
||||
Libs: -L${libdir} -lpixman-1
|
||||
|
158
vendor/pixman/pixman/Makefile.am
vendored
158
vendor/pixman/pixman/Makefile.am
vendored
@ -1,158 +0,0 @@
|
||||
include $(top_srcdir)/pixman/Makefile.sources
|
||||
|
||||
lib_LTLIBRARIES = libpixman-1.la
|
||||
|
||||
libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined @PTHREAD_LDFLAGS@
|
||||
libpixman_1_la_LIBADD = @PTHREAD_LIBS@ -lm
|
||||
libpixman_1_la_SOURCES = $(libpixman_sources) $(libpixman_headers)
|
||||
|
||||
libpixmanincludedir = $(includedir)/pixman-1
|
||||
libpixmaninclude_HEADERS = pixman.h pixman-version.h
|
||||
noinst_LTLIBRARIES =
|
||||
|
||||
EXTRA_DIST = \
|
||||
Makefile.win32 \
|
||||
dither/make-blue-noise.c \
|
||||
pixman-region.c \
|
||||
solaris-hwcap.mapfile \
|
||||
meson.build \
|
||||
$(NULL)
|
||||
|
||||
# mmx code
|
||||
if USE_X86_MMX
|
||||
noinst_LTLIBRARIES += libpixman-mmx.la
|
||||
libpixman_mmx_la_SOURCES = \
|
||||
pixman-mmx.c
|
||||
libpixman_mmx_la_CFLAGS = $(MMX_CFLAGS)
|
||||
libpixman_1_la_LDFLAGS += $(MMX_LDFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-mmx.la
|
||||
|
||||
ASM_CFLAGS_mmx=$(MMX_CFLAGS)
|
||||
endif
|
||||
|
||||
# vmx code
|
||||
if USE_VMX
|
||||
noinst_LTLIBRARIES += libpixman-vmx.la
|
||||
libpixman_vmx_la_SOURCES = \
|
||||
pixman-vmx.c \
|
||||
pixman-combine32.h
|
||||
libpixman_vmx_la_CFLAGS = $(VMX_CFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-vmx.la
|
||||
|
||||
ASM_CFLAGS_vmx=$(VMX_CFLAGS)
|
||||
endif
|
||||
|
||||
# sse2 code
|
||||
if USE_SSE2
|
||||
noinst_LTLIBRARIES += libpixman-sse2.la
|
||||
libpixman_sse2_la_SOURCES = \
|
||||
pixman-sse2.c
|
||||
libpixman_sse2_la_CFLAGS = $(SSE2_CFLAGS)
|
||||
libpixman_1_la_LDFLAGS += $(SSE2_LDFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-sse2.la
|
||||
|
||||
ASM_CFLAGS_sse2=$(SSE2_CFLAGS)
|
||||
endif
|
||||
|
||||
# ssse3 code
|
||||
if USE_SSSE3
|
||||
noinst_LTLIBRARIES += libpixman-ssse3.la
|
||||
libpixman_ssse3_la_SOURCES = \
|
||||
pixman-ssse3.c
|
||||
libpixman_ssse3_la_CFLAGS = $(SSSE3_CFLAGS)
|
||||
libpixman_1_la_LDFLAGS += $(SSSE3_LDFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-ssse3.la
|
||||
|
||||
ASM_CFLAGS_ssse3=$(SSSE3_CFLAGS)
|
||||
endif
|
||||
|
||||
# arm simd code
|
||||
if USE_ARM_SIMD
|
||||
noinst_LTLIBRARIES += libpixman-arm-simd.la
|
||||
libpixman_arm_simd_la_SOURCES = \
|
||||
pixman-arm-simd.c \
|
||||
pixman-arm-common.h \
|
||||
pixman-arm-simd-asm.S \
|
||||
pixman-arm-simd-asm-scaled.S \
|
||||
pixman-arm-asm.h \
|
||||
pixman-arm-simd-asm.h
|
||||
libpixman_1_la_LIBADD += libpixman-arm-simd.la
|
||||
|
||||
ASM_CFLAGS_arm_simd=
|
||||
endif
|
||||
|
||||
# arm neon code
|
||||
if USE_ARM_NEON
|
||||
noinst_LTLIBRARIES += libpixman-arm-neon.la
|
||||
libpixman_arm_neon_la_SOURCES = \
|
||||
pixman-arm-neon.c \
|
||||
pixman-arm-common.h \
|
||||
pixman-arm-neon-asm.S \
|
||||
pixman-arm-neon-asm-bilinear.S \
|
||||
pixman-arm-asm.h \
|
||||
pixman-arm-neon-asm.h
|
||||
libpixman_1_la_LIBADD += libpixman-arm-neon.la
|
||||
|
||||
ASM_CFLAGS_arm_neon=
|
||||
endif
|
||||
|
||||
# arm a64 neon code
|
||||
if USE_ARM_A64_NEON
|
||||
noinst_LTLIBRARIES += libpixman-arma64-neon.la
|
||||
libpixman_arma64_neon_la_SOURCES = \
|
||||
pixman-arm-neon.c \
|
||||
pixman-arm-common.h \
|
||||
pixman-arma64-neon-asm.S \
|
||||
pixman-arma64-neon-asm-bilinear.S \
|
||||
pixman-arm-asm.h \
|
||||
pixman-arma64-neon-asm.h
|
||||
libpixman_1_la_LIBADD += libpixman-arma64-neon.la
|
||||
|
||||
ASM_CFLAGS_arm_neon=
|
||||
endif
|
||||
|
||||
# iwmmxt code
|
||||
if USE_ARM_IWMMXT
|
||||
libpixman_iwmmxt_la_SOURCES = pixman-mmx.c
|
||||
noinst_LTLIBRARIES += libpixman-iwmmxt.la
|
||||
libpixman_1_la_LIBADD += libpixman-iwmmxt.la
|
||||
|
||||
libpixman_iwmmxt_la-pixman-mmx.lo: pixman-mmx.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(IWMMXT_CFLAGS) -MT libpixman_iwmmxt_la-pixman-mmx.lo -MD -MP -MF $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Tpo -c -o libpixman_iwmmxt_la-pixman-mmx.lo `test -f 'pixman-mmx.c' || echo '$(srcdir)/'`pixman-mmx.c
|
||||
$(AM_V_at)$(am__mv) $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Tpo $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Plo
|
||||
|
||||
libpixman_iwmmxt_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
|
||||
libpixman_iwmmxt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
|
||||
$(CFLAGS) $(IWMMXT_CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
|
||||
libpixman-iwmmxt.la: libpixman_iwmmxt_la-pixman-mmx.lo $(libpixman_iwmmxt_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libpixman_iwmmxt_la_LINK) libpixman_iwmmxt_la-pixman-mmx.lo $(libpixman_iwmmxt_la_LIBADD) $(LIBS)
|
||||
endif
|
||||
|
||||
# mips dspr2 code
|
||||
if USE_MIPS_DSPR2
|
||||
noinst_LTLIBRARIES += libpixman-mips-dspr2.la
|
||||
libpixman_mips_dspr2_la_SOURCES = \
|
||||
pixman-mips-dspr2.c \
|
||||
pixman-mips-dspr2.h \
|
||||
pixman-mips-dspr2-asm.S \
|
||||
pixman-mips-dspr2-asm.h \
|
||||
pixman-mips-memcpy-asm.S
|
||||
libpixman_1_la_LIBADD += libpixman-mips-dspr2.la
|
||||
|
||||
ASM_CFLAGS_mips_dspr2=
|
||||
endif
|
||||
|
||||
# loongson code
|
||||
if USE_LOONGSON_MMI
|
||||
noinst_LTLIBRARIES += libpixman-loongson-mmi.la
|
||||
libpixman_loongson_mmi_la_SOURCES = pixman-mmx.c loongson-mmintrin.h
|
||||
libpixman_loongson_mmi_la_CFLAGS = $(LS_CFLAGS)
|
||||
libpixman_1_la_LDFLAGS += $(LS_LDFLAGS)
|
||||
libpixman_1_la_LIBADD += libpixman-loongson-mmi.la
|
||||
endif
|
||||
|
||||
.c.s : $(libpixmaninclude_HEADERS)
|
||||
$(CC) $(CFLAGS) $(ASM_CFLAGS_$(@:pixman-%.s=%)) $(ASM_CFLAGS_$(@:pixman-arm-%.s=arm_%)) -DHAVE_CONFIG_H -I$(srcdir) -I$(builddir) -I$(top_builddir) -S -o $@ $<
|
43
vendor/pixman/pixman/Makefile.sources
vendored
43
vendor/pixman/pixman/Makefile.sources
vendored
@ -1,43 +0,0 @@
|
||||
libpixman_sources = \
|
||||
pixman.c \
|
||||
pixman-access.c \
|
||||
pixman-access-accessors.c \
|
||||
pixman-bits-image.c \
|
||||
pixman-combine32.c \
|
||||
pixman-combine-float.c \
|
||||
pixman-conical-gradient.c \
|
||||
pixman-filter.c \
|
||||
pixman-x86.c \
|
||||
pixman-mips.c \
|
||||
pixman-arm.c \
|
||||
pixman-ppc.c \
|
||||
pixman-edge.c \
|
||||
pixman-edge-accessors.c \
|
||||
pixman-fast-path.c \
|
||||
pixman-glyph.c \
|
||||
pixman-general.c \
|
||||
pixman-gradient-walker.c \
|
||||
pixman-image.c \
|
||||
pixman-implementation.c \
|
||||
pixman-linear-gradient.c \
|
||||
pixman-matrix.c \
|
||||
pixman-noop.c \
|
||||
pixman-radial-gradient.c \
|
||||
pixman-region16.c \
|
||||
pixman-region32.c \
|
||||
pixman-solid-fill.c \
|
||||
pixman-timer.c \
|
||||
pixman-trap.c \
|
||||
pixman-utils.c \
|
||||
$(NULL)
|
||||
|
||||
libpixman_headers = \
|
||||
dither/blue-noise-64x64.h \
|
||||
pixman.h \
|
||||
pixman-accessor.h \
|
||||
pixman-combine32.h \
|
||||
pixman-compiler.h \
|
||||
pixman-edge-imp.h \
|
||||
pixman-inlines.h \
|
||||
pixman-private.h \
|
||||
$(NULL)
|
93
vendor/pixman/pixman/Makefile.win32
vendored
93
vendor/pixman/pixman/Makefile.win32
vendored
@ -1,93 +0,0 @@
|
||||
default: all
|
||||
|
||||
top_srcdir = ..
|
||||
include $(top_srcdir)/pixman/Makefile.sources
|
||||
include $(top_srcdir)/Makefile.win32.common
|
||||
|
||||
MMX_VAR = $(MMX)
|
||||
ifeq ($(MMX_VAR),)
|
||||
MMX_VAR=on
|
||||
endif
|
||||
|
||||
SSE2_VAR = $(SSE2)
|
||||
ifeq ($(SSE2_VAR),)
|
||||
SSE2_VAR=on
|
||||
endif
|
||||
|
||||
SSSE3_VAR = $(SSSE3)
|
||||
ifeq ($(SSSE3_VAR),)
|
||||
SSSE3_VAR=on
|
||||
endif
|
||||
|
||||
MMX_CFLAGS = -DUSE_X86_MMX -w14710 -w14714
|
||||
SSE2_CFLAGS = -DUSE_SSE2
|
||||
SSSE3_CFLAGS = -DUSE_SSSE3
|
||||
|
||||
# MMX compilation flags
|
||||
ifeq ($(MMX_VAR),on)
|
||||
PIXMAN_CFLAGS += $(MMX_CFLAGS)
|
||||
libpixman_sources += pixman-mmx.c
|
||||
endif
|
||||
|
||||
# SSE2 compilation flags
|
||||
ifeq ($(SSE2_VAR),on)
|
||||
PIXMAN_CFLAGS += $(SSE2_CFLAGS)
|
||||
libpixman_sources += pixman-sse2.c
|
||||
endif
|
||||
|
||||
# SSSE3 compilation flags
|
||||
ifeq ($(SSSE3_VAR),on)
|
||||
PIXMAN_CFLAGS += $(SSSE3_CFLAGS)
|
||||
libpixman_sources += pixman-ssse3.c
|
||||
endif
|
||||
|
||||
OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libpixman_sources))
|
||||
|
||||
# targets
|
||||
all: inform informMMX informSSE2 informSSSE3 $(CFG_VAR)/$(LIBRARY).lib
|
||||
|
||||
informMMX:
|
||||
ifneq ($(MMX),off)
|
||||
ifneq ($(MMX),on)
|
||||
ifneq ($(MMX),)
|
||||
@echo "Invalid specified MMX option : "$(MMX_VAR)"."
|
||||
@echo
|
||||
@echo "Possible choices for MMX are 'on' or 'off'"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Setting MMX flag to default value 'on'... (use MMX=on or MMX=off)"
|
||||
endif
|
||||
endif
|
||||
|
||||
informSSE2:
|
||||
ifneq ($(SSE2),off)
|
||||
ifneq ($(SSE2),on)
|
||||
ifneq ($(SSE2),)
|
||||
@echo "Invalid specified SSE option : "$(SSE2)"."
|
||||
@echo
|
||||
@echo "Possible choices for SSE2 are 'on' or 'off'"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Setting SSE2 flag to default value 'on'... (use SSE2=on or SSE2=off)"
|
||||
endif
|
||||
endif
|
||||
|
||||
informSSSE3:
|
||||
ifneq ($(SSSE3),off)
|
||||
ifneq ($(SSSE3),on)
|
||||
ifneq ($(SSSE3),)
|
||||
@echo "Invalid specified SSE option : "$(SSSE3)"."
|
||||
@echo
|
||||
@echo "Possible choices for SSSE3 are 'on' or 'off'"
|
||||
@exit 1
|
||||
endif
|
||||
@echo "Setting SSSE3 flag to default value 'on'... (use SSSE3=on or SSSE3=off)"
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# pixman linking
|
||||
$(CFG_VAR)/$(LIBRARY).lib: $(OBJECTS)
|
||||
@$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^
|
||||
|
||||
.PHONY: all informMMX informSSE2 informSSSE3
|
77
vendor/pixman/pixman/dither/blue-noise-64x64.h
vendored
77
vendor/pixman/pixman/dither/blue-noise-64x64.h
vendored
@ -1,77 +0,0 @@
|
||||
/* WARNING: This file is generated by make-blue-noise.c
|
||||
* Please edit that file instead of this one.
|
||||
*/
|
||||
|
||||
#ifndef BLUE_NOISE_64X64_H
|
||||
#define BLUE_NOISE_64X64_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint16_t dither_blue_noise_64x64[4096] = {
|
||||
3039, 1368, 3169, 103, 2211, 1248, 2981, 668, 2633, 37, 3963, 2903, 384, 2564, 3115, 1973, 3348, 830, 2505, 1293, 3054, 1060, 1505, 3268, 400, 1341, 593, 3802, 3384, 429, 4082, 1411, 2503, 3863, 126, 1292, 1887, 2855, 205, 2094, 2977, 1899, 3924, 356, 3088, 2500, 3942, 1409, 2293, 1734, 3732, 1291, 3227, 277, 2054, 786, 2871, 411, 2425, 1678, 3986, 455, 2879, 2288,
|
||||
388, 1972, 3851, 778, 2768, 3697, 944, 2123, 1501, 3533, 937, 1713, 1381, 3888, 156, 1242, 516, 2888, 1607, 3676, 632, 2397, 3804, 2673, 1898, 3534, 2593, 1777, 1170, 2299, 3013, 1838, 523, 3053, 1647, 3601, 3197, 959, 1520, 3633, 893, 2437, 3367, 2187, 1258, 137, 1965, 401, 3546, 643, 3087, 2498, 733, 2786, 3371, 4053, 1266, 1977, 3663, 183, 2570, 2107, 1183, 3708,
|
||||
907, 2473, 1151, 3363, 1527, 1902, 232, 3903, 3060, 496, 2486, 3206, 2165, 861, 2387, 3653, 2101, 3972, 132, 2162, 3437, 1827, 215, 895, 3114, 271, 969, 2932, 197, 1598, 878, 3696, 1140, 2120, 904, 2431, 302, 3846, 2675, 481, 3187, 66, 1440, 650, 3833, 2826, 3435, 901, 2936, 2111, 250, 1875, 3609, 1174, 1747, 162, 2346, 3420, 913, 3172, 1383, 752, 3298, 1735,
|
||||
3540, 2938, 249, 2324, 526, 3099, 2561, 1324, 2347, 1861, 1200, 3702, 257, 3442, 1514, 2999, 992, 1766, 2735, 1163, 478, 2943, 1279, 3635, 2177, 1464, 3672, 2386, 3871, 3340, 2690, 64, 3489, 2811, 3999, 633, 1948, 1243, 2269, 1807, 1143, 2750, 3729, 1790, 2363, 1053, 1537, 2636, 4065, 1076, 1476, 3869, 450, 2200, 2676, 658, 2979, 1548, 544, 1913, 2838, 3911, 116, 2698,
|
||||
517, 1295, 3997, 1739, 3665, 1083, 3509, 599, 3400, 118, 2956, 720, 2689, 1907, 567, 2523, 284, 3397, 711, 3219, 2450, 3985, 1665, 2549, 562, 3011, 1855, 729, 1355, 528, 1908, 2456, 1384, 337, 1540, 2654, 3138, 3513, 703, 4080, 3314, 2047, 855, 3037, 209, 3317, 577, 1828, 17, 2336, 3193, 2748, 962, 3441, 1450, 3246, 1075, 3878, 2615, 3497, 1033, 2310, 1442, 2183,
|
||||
1654, 3254, 2061, 738, 2832, 148, 2030, 1670, 909, 3850, 2109, 1533, 4046, 1085, 3098, 3897, 1378, 2248, 3829, 1495, 1966, 23, 797, 3427, 1124, 4057, 95, 2787, 2190, 3074, 3950, 742, 3194, 1999, 3386, 1113, 16, 1657, 2804, 201, 1543, 383, 2559, 1325, 3604, 2068, 2493, 3771, 1284, 3460, 710, 1716, 2447, 80, 3811, 2032, 347, 2227, 15, 1689, 397, 3084, 662, 3798,
|
||||
973, 43, 2608, 3143, 1459, 2423, 4066, 2770, 3191, 1283, 2630, 314, 3235, 2289, 72, 1822, 2840, 924, 350, 2653, 1057, 3715, 2235, 2775, 346, 2083, 1553, 3292, 1081, 274, 1686, 1188, 2327, 3743, 578, 2234, 3916, 2519, 1011, 3056, 2207, 3438, 3890, 537, 1617, 837, 3094, 373, 2795, 1980, 276, 3951, 1353, 3015, 844, 1724, 3651, 2923, 1316, 4092, 2504, 3627, 1936, 2854,
|
||||
2461, 3929, 1193, 421, 3746, 820, 1180, 286, 2261, 532, 3625, 1812, 802, 1327, 3527, 670, 3730, 2025, 3124, 3565, 529, 2960, 1769, 1390, 3196, 2494, 3756, 796, 3618, 2602, 3463, 2847, 166, 953, 1745, 2900, 438, 2070, 1418, 3741, 639, 1205, 1891, 2882, 2282, 4012, 1182, 1696, 3630, 951, 2904, 2170, 3530, 375, 2320, 2742, 1132, 701, 3216, 2023, 847, 1230, 310, 3431,
|
||||
770, 1961, 3531, 1702, 2181, 3370, 1877, 3072, 1571, 3389, 1071, 2415, 3782, 2803, 1610, 2454, 1211, 182, 1655, 2322, 1282, 3372, 287, 3935, 704, 1232, 415, 1910, 2286, 1399, 556, 1964, 4068, 2444, 3605, 1272, 3345, 816, 3526, 256, 2402, 2777, 955, 345, 3289, 111, 2727, 635, 2396, 1488, 3331, 600, 1032, 1575, 4026, 515, 3507, 2433, 1605, 460, 3364, 2783, 1810, 1397,
|
||||
2334, 223, 2945, 688, 2533, 99, 2705, 624, 3944, 2073, 46, 2978, 508, 2132, 269, 3173, 3453, 2631, 4076, 694, 1892, 2586, 972, 2178, 3470, 1695, 2849, 3141, 77, 3884, 994, 3029, 1536, 673, 3083, 124, 2583, 1722, 2821, 1944, 4027, 1661, 3176, 3728, 1337, 1813, 3503, 2035, 3930, 157, 2537, 1865, 3096, 2646, 1941, 3252, 1449, 135, 2836, 3758, 2139, 84, 3678, 3106,
|
||||
3862, 1545, 3307, 1320, 3955, 1031, 3664, 1306, 2460, 776, 1487, 3294, 1187, 3990, 1903, 1021, 549, 1484, 943, 3027, 97, 3853, 1499, 2880, 198, 2575, 3995, 1089, 1587, 2475, 3282, 339, 2657, 1158, 2105, 1493, 3943, 580, 3232, 1287, 846, 48, 2480, 2112, 771, 2534, 459, 3134, 850, 1298, 3790, 325, 3652, 1249, 193, 940, 2202, 3895, 1829, 911, 1366, 2577, 1069, 534,
|
||||
2104, 1009, 2667, 392, 1983, 2917, 1645, 324, 3439, 2869, 3705, 1767, 2592, 756, 2916, 3683, 2276, 2850, 2053, 3594, 2403, 3181, 634, 3699, 1933, 906, 519, 2150, 3673, 764, 1770, 2220, 3795, 3336, 502, 3547, 2339, 1110, 301, 2210, 3354, 3643, 569, 1518, 2940, 3973, 1138, 1613, 2773, 2127, 2983, 1671, 769, 2161, 3800, 2730, 3127, 1179, 533, 3259, 2284, 4014, 1651, 2820,
|
||||
3566, 653, 1839, 3455, 2399, 789, 3149, 2244, 1863, 1099, 474, 2307, 158, 3541, 1312, 1711, 0, 3902, 360, 1629, 1091, 395, 1781, 1191, 2374, 3353, 1419, 3225, 206, 2931, 3553, 1046, 54, 1646, 2470, 910, 1860, 3137, 3770, 2635, 1562, 2809, 1215, 3788, 222, 2199, 3335, 67, 3606, 524, 1001, 3309, 2410, 3473, 591, 1619, 291, 2502, 3629, 2891, 335, 741, 3378, 168,
|
||||
2384, 3129, 4051, 22, 1444, 3613, 543, 3893, 186, 2665, 4062, 933, 3058, 2142, 449, 2711, 3224, 849, 1330, 3349, 2195, 2670, 3484, 2993, 32, 3774, 2722, 1859, 2548, 1268, 583, 2027, 3165, 2807, 4029, 227, 2897, 1434, 721, 1816, 195, 905, 2066, 3258, 1754, 970, 2674, 1880, 2338, 3915, 1485, 2660, 14, 1313, 2914, 2046, 4074, 791, 1917, 1301, 1725, 2687, 2019, 1443,
|
||||
418, 1186, 1664, 2859, 1049, 2056, 2741, 1226, 1589, 3186, 2042, 1377, 3449, 1574, 3941, 1063, 1930, 2501, 3751, 2930, 671, 4031, 888, 2081, 1544, 684, 1117, 351, 4052, 1698, 2393, 3881, 1439, 785, 1277, 2013, 3488, 441, 2459, 3980, 3061, 3481, 2543, 419, 3020, 609, 3515, 1350, 799, 2878, 348, 2034, 3966, 1824, 950, 3281, 1394, 2239, 3452, 55, 3922, 3119, 892, 3785,
|
||||
3023, 2140, 782, 2492, 3817, 241, 3355, 2424, 856, 3639, 612, 2556, 245, 2858, 705, 2316, 3562, 495, 1748, 128, 1912, 1454, 280, 2552, 3905, 3130, 2274, 3472, 834, 3055, 240, 2692, 471, 2272, 3301, 2632, 1080, 3693, 2136, 1029, 1364, 590, 1611, 4067, 1190, 2360, 3827, 261, 3180, 1768, 3471, 1103, 3003, 520, 3674, 151, 2571, 555, 3033, 982, 2353, 504, 1259, 2555,
|
||||
149, 3889, 3380, 493, 3178, 1681, 663, 1924, 2990, 49, 1792, 3861, 1192, 1987, 3273, 297, 1457, 3043, 1177, 2292, 3249, 2829, 3682, 1154, 1758, 428, 2872, 1993, 1500, 3703, 1129, 3421, 1840, 3754, 163, 659, 1733, 3182, 38, 2875, 1957, 3614, 2237, 78, 1873, 2801, 1513, 2121, 1074, 2516, 667, 3710, 1429, 2430, 2088, 2830, 1072, 3557, 1531, 2733, 1955, 3286, 3590, 1826,
|
||||
2778, 1068, 1932, 1452, 2279, 1185, 3564, 3952, 1391, 2726, 3313, 2331, 870, 3709, 1674, 2772, 4085, 808, 2596, 3848, 927, 538, 2335, 3334, 773, 3597, 1347, 109, 2663, 608, 2108, 2994, 936, 1524, 2922, 3968, 2422, 1467, 845, 3870, 321, 2704, 1073, 3308, 3680, 823, 430, 3375, 4030, 112, 2171, 2695, 267, 3374, 731, 1627, 3919, 1871, 352, 3839, 1370, 234, 794, 1532,
|
||||
3245, 647, 3575, 74, 3045, 2766, 285, 2174, 498, 1059, 1551, 385, 3125, 2598, 143, 1128, 2095, 3395, 318, 1590, 3524, 1345, 1969, 242, 2759, 2092, 947, 3926, 3244, 2356, 1658, 6, 3593, 2554, 1172, 1995, 371, 2755, 3417, 2294, 1570, 3164, 748, 2517, 1401, 3111, 2420, 1662, 2910, 1276, 3276, 854, 1804, 4000, 1253, 2987, 229, 2344, 3184, 649, 2196, 2921, 4095, 2389,
|
||||
1289, 2193, 2579, 4023, 757, 1858, 986, 3199, 2514, 3475, 4021, 2154, 651, 1432, 3468, 2404, 574, 1799, 3105, 2145, 86, 2614, 3218, 1565, 4088, 2481, 3079, 1815, 323, 1212, 3837, 759, 2159, 435, 3223, 784, 3659, 1114, 1888, 550, 1221, 3786, 1803, 499, 2117, 185, 3763, 942, 589, 2001, 3838, 1483, 3154, 2256, 468, 2544, 3403, 898, 1208, 2610, 3622, 967, 1929, 378,
|
||||
3781, 220, 1656, 1115, 3347, 2428, 3822, 1577, 712, 1959, 110, 2765, 1762, 3854, 979, 2928, 3714, 1371, 746, 3969, 2884, 975, 3779, 641, 1142, 159, 1460, 702, 3485, 2866, 2495, 3330, 1305, 3937, 1635, 2229, 2962, 146, 4055, 3091, 2417, 100, 3508, 2933, 4006, 1167, 1920, 2760, 3552, 2545, 433, 2845, 142, 1056, 1886, 3616, 1435, 2099, 3803, 1749, 27, 1446, 3350, 2843,
|
||||
884, 3310, 2948, 2103, 447, 1351, 187, 2895, 3655, 1256, 3036, 932, 3325, 2257, 451, 1915, 40, 2780, 2438, 1112, 1814, 423, 2290, 1905, 2898, 3419, 2306, 3760, 1938, 486, 1019, 1791, 3010, 2628, 203, 3408, 1269, 2507, 1606, 862, 2779, 2078, 952, 1529, 2638, 708, 3332, 1413, 2, 1726, 1156, 3500, 2392, 3791, 3076, 812, 107, 2861, 501, 3050, 3487, 2455, 594, 1731,
|
||||
2685, 1498, 680, 3908, 2621, 3529, 1786, 2236, 342, 2569, 1526, 3722, 230, 1290, 3203, 3947, 1609, 3516, 467, 3267, 3685, 1461, 3140, 3569, 367, 1759, 928, 2754, 1332, 2219, 4034, 260, 655, 1984, 978, 3814, 617, 2086, 3525, 279, 3841, 1373, 3361, 319, 2251, 3066, 407, 2382, 3918, 3133, 2168, 762, 1523, 507, 2641, 1677, 4025, 2413, 1584, 793, 2049, 1109, 3962, 2218,
|
||||
1194, 3692, 266, 1687, 981, 3103, 740, 3983, 1005, 3434, 570, 2383, 1942, 2718, 676, 2462, 1007, 2089, 1308, 2222, 233, 2568, 829, 1241, 2669, 3987, 514, 3303, 69, 3142, 1603, 3560, 2295, 3288, 1497, 2696, 1764, 2865, 1058, 3271, 1914, 477, 2529, 3927, 1736, 1273, 3752, 2029, 1012, 565, 2798, 4078, 1949, 3305, 1175, 2179, 380, 3366, 1195, 3849, 2637, 416, 2959, 125,
|
||||
3396, 2467, 2036, 3234, 2340, 68, 2819, 1436, 2011, 3139, 1704, 4073, 860, 3582, 1468, 2969, 211, 3157, 4056, 866, 2935, 2000, 3923, 31, 2157, 1477, 2429, 1147, 3792, 2557, 774, 2802, 1153, 3747, 464, 3192, 42, 3904, 539, 1474, 2283, 803, 2876, 1061, 75, 3477, 747, 2893, 1538, 3626, 251, 1322, 2506, 189, 2791, 3667, 939, 2991, 1971, 175, 3195, 1416, 3648, 1857,
|
||||
3052, 454, 851, 3789, 1271, 1906, 3694, 2484, 406, 2757, 26, 1189, 2909, 296, 2215, 3784, 1864, 637, 2715, 1673, 3445, 581, 1572, 3059, 3469, 761, 2984, 1737, 2058, 440, 1414, 1921, 121, 2527, 894, 2223, 1302, 2377, 3077, 2666, 3759, 3198, 1811, 3661, 2166, 2731, 1883, 359, 3285, 2458, 1805, 3459, 926, 3834, 675, 1893, 1496, 2612, 657, 3523, 1763, 2354, 564, 961,
|
||||
1367, 3977, 1588, 2714, 322, 3446, 1088, 625, 3887, 1354, 3535, 2090, 3316, 1760, 1127, 483, 3491, 1421, 2301, 94, 1202, 3740, 2311, 1014, 1878, 3836, 180, 3412, 991, 2868, 3953, 3450, 3081, 1632, 4071, 1882, 3543, 726, 1719, 179, 1171, 364, 1420, 622, 3090, 1490, 946, 4007, 2212, 1102, 619, 2739, 2189, 1669, 2937, 3426, 39, 3940, 2191, 1264, 887, 4091, 2792, 2135,
|
||||
4, 2883, 2281, 631, 3044, 1641, 2232, 3243, 1773, 2319, 827, 2591, 629, 3938, 2426, 3222, 2629, 1044, 3879, 3293, 1952, 2749, 275, 2590, 472, 1372, 2496, 660, 3669, 2264, 208, 915, 2167, 561, 2828, 307, 3265, 1104, 3964, 2155, 3425, 1951, 4077, 2391, 283, 3387, 2581, 115, 1415, 3069, 3896, 141, 3158, 1214, 442, 2405, 1349, 3085, 425, 2528, 3002, 312, 1602, 3588,
|
||||
1137, 3323, 1963, 1002, 3578, 2521, 127, 925, 2970, 273, 3737, 1573, 167, 2863, 1509, 800, 147, 2059, 2942, 409, 921, 3151, 1451, 3909, 3333, 2844, 2096, 1512, 3136, 1210, 1798, 2709, 1331, 3586, 1034, 1521, 2441, 2926, 488, 2585, 775, 3031, 2693, 879, 3602, 1173, 2028, 3654, 2781, 841, 1975, 1507, 3646, 768, 3991, 2012, 996, 3544, 1666, 3810, 1990, 3360, 753, 2597,
|
||||
3736, 304, 1473, 3828, 485, 1334, 4008, 2072, 3495, 1136, 2806, 2004, 3236, 1010, 2130, 3819, 1750, 3567, 644, 2515, 1794, 3636, 698, 2137, 1162, 832, 3761, 326, 2613, 513, 3302, 3820, 357, 3163, 2259, 3733, 101, 1922, 1386, 3587, 1640, 28, 1286, 2141, 1761, 2918, 693, 1639, 457, 3250, 2434, 365, 2599, 1729, 3284, 2643, 306, 2793, 689, 1090, 104, 1309, 2305, 1831,
|
||||
2776, 859, 2446, 2915, 1778, 3337, 2677, 614, 1508, 2409, 469, 4033, 1321, 3563, 402, 3131, 2720, 1093, 1569, 4042, 1229, 2277, 216, 3046, 1817, 57, 3006, 1684, 4059, 2016, 795, 2440, 1652, 1960, 610, 2763, 920, 3864, 3110, 1026, 2326, 3762, 3233, 521, 3856, 173, 2457, 3939, 2138, 1262, 3572, 989, 3021, 2238, 119, 1445, 3832, 1809, 2297, 3467, 2700, 3684, 3102, 394,
|
||||
4036, 2050, 3256, 89, 2198, 1079, 248, 1845, 3805, 3104, 880, 1779, 2688, 717, 2373, 1375, 262, 2249, 3071, 13, 2813, 3429, 1600, 3984, 2416, 3603, 1299, 2298, 998, 3492, 1393, 2951, 10, 4009, 1247, 3462, 1679, 2204, 414, 2736, 316, 1894, 2816, 1050, 3373, 1462, 3107, 817, 3464, 21, 1835, 4070, 568, 1178, 3718, 875, 3168, 466, 2974, 1458, 2084, 616, 1564, 1018,
|
||||
1693, 546, 1244, 3899, 716, 3160, 3608, 2877, 1220, 334, 3443, 2270, 44, 3000, 1843, 3928, 3405, 766, 3686, 2040, 587, 993, 2647, 387, 930, 2753, 630, 3274, 150, 2808, 453, 3638, 1092, 2352, 3030, 239, 2562, 700, 3240, 1257, 4016, 730, 1515, 2203, 2551, 417, 1866, 1123, 2348, 2902, 1550, 2678, 2075, 3238, 1630, 2531, 2115, 1255, 4054, 840, 290, 3874, 2477, 3399,
|
||||
2250, 3577, 2817, 1626, 2576, 1356, 2315, 792, 2087, 2618, 1612, 3855, 1263, 3637, 1036, 494, 1535, 2553, 1198, 1715, 3867, 3170, 1359, 1954, 3483, 1539, 2069, 3886, 1772, 2487, 1534, 2045, 3242, 806, 1578, 2018, 3948, 1423, 3596, 2076, 2466, 3424, 139, 3688, 871, 4049, 2852, 3342, 547, 3719, 327, 852, 3505, 207, 2794, 542, 3600, 45, 2411, 3324, 1788, 3012, 1235, 61,
|
||||
2655, 917, 253, 1986, 3738, 313, 1706, 4072, 120, 3229, 957, 597, 2024, 3262, 2453, 2857, 2002, 3190, 210, 2784, 2206, 300, 2400, 3766, 553, 3152, 218, 1150, 2988, 883, 3753, 627, 2664, 3831, 437, 3385, 1008, 2957, 60, 1636, 891, 2899, 1776, 3062, 1315, 2026, 194, 1643, 2079, 1296, 3201, 2465, 1379, 1927, 3898, 1125, 1847, 2846, 1552, 1028, 2725, 2169, 787, 3202,
|
||||
1441, 3982, 3032, 1052, 3251, 605, 2639, 3073, 1431, 3642, 2329, 2949, 341, 1634, 833, 129, 4020, 916, 3571, 669, 1506, 3411, 821, 2856, 1207, 2337, 2683, 3448, 340, 2214, 3128, 235, 1738, 1288, 2833, 2419, 606, 1884, 2668, 552, 3765, 1176, 399, 2302, 596, 3591, 2634, 767, 3845, 2767, 995, 3967, 491, 3057, 814, 2300, 3422, 691, 3797, 254, 3645, 509, 3478, 1836,
|
||||
2119, 475, 2445, 1525, 2175, 3539, 914, 1926, 473, 1157, 1800, 3971, 2701, 3739, 2129, 3486, 1333, 1784, 2366, 2982, 1070, 4089, 1802, 73, 1642, 3958, 835, 1837, 1480, 4043, 1217, 2469, 3416, 2113, 88, 3668, 1240, 3255, 3920, 2355, 3167, 2003, 2645, 3936, 3228, 1592, 1144, 3474, 2394, 79, 1820, 2241, 1594, 3656, 2584, 153, 1448, 3034, 2005, 2511, 1692, 1335, 3913, 217,
|
||||
2822, 3391, 745, 3813, 192, 1274, 2941, 3847, 2489, 3440, 744, 161, 1422, 1086, 572, 3004, 2617, 338, 3807, 2031, 236, 2472, 3065, 2098, 3358, 362, 2163, 3574, 497, 2788, 1970, 948, 3885, 685, 3100, 1712, 2228, 292, 1408, 1016, 164, 3537, 1417, 941, 34, 2172, 3001, 358, 1491, 3147, 699, 3356, 258, 1149, 2946, 1787, 3931, 382, 1146, 3291, 818, 2890, 2379, 1096,
|
||||
3679, 1328, 1901, 3162, 2747, 1730, 2253, 5, 1556, 2818, 2093, 3166, 2522, 3410, 2287, 1701, 956, 3237, 620, 1596, 3300, 1307, 511, 3701, 1020, 2939, 1362, 2532, 3208, 749, 3641, 160, 1522, 2624, 1095, 4086, 826, 2841, 3583, 2173, 1727, 723, 2925, 1911, 2482, 3726, 863, 1962, 4028, 1111, 2835, 3773, 2449, 2022, 582, 3278, 923, 2619, 2152, 4039, 92, 1934, 3145, 677,
|
||||
2530, 53, 2303, 1003, 458, 3989, 739, 3321, 1064, 369, 3556, 877, 1900, 426, 3876, 1, 3617, 2106, 1197, 2805, 3634, 857, 2706, 1504, 2418, 682, 3868, 20, 1139, 1688, 2333, 3311, 2907, 1945, 265, 2385, 3433, 1601, 636, 2620, 3095, 4044, 386, 3382, 1184, 527, 2814, 3414, 2342, 465, 1889, 1343, 874, 3479, 1502, 2233, 3689, 1385, 559, 2745, 1463, 3465, 376, 1718,
|
||||
3217, 4045, 1580, 3612, 2525, 1228, 3018, 1958, 3725, 2358, 1361, 3996, 1581, 3063, 1224, 2737, 1475, 2442, 3946, 191, 1796, 2128, 3975, 134, 1916, 3318, 1597, 2071, 3749, 2672, 403, 1278, 602, 3745, 3220, 1374, 445, 2064, 3830, 243, 1252, 2390, 1563, 2724, 3875, 1818, 1346, 165, 1650, 3264, 2680, 117, 2998, 4081, 343, 2799, 9, 3122, 1743, 3724, 1040, 2231, 3842, 1209,
|
||||
900, 398, 2851, 697, 1797, 3482, 293, 2679, 1649, 566, 2954, 91, 2697, 714, 2060, 3211, 781, 480, 3040, 1038, 2611, 666, 2989, 3458, 1201, 2796, 548, 2975, 839, 3121, 1850, 4001, 2208, 1631, 790, 2558, 2972, 1148, 3213, 1849, 3624, 971, 2102, 108, 772, 3101, 2589, 3777, 1042, 656, 3907, 2097, 1615, 2540, 805, 1935, 1231, 3494, 2451, 268, 2995, 750, 2682, 2020,
|
||||
3024, 1392, 2124, 3279, 106, 2217, 1387, 822, 3214, 3825, 2160, 1000, 2395, 3691, 228, 4038, 1872, 3413, 1608, 2225, 3536, 303, 1653, 886, 2541, 224, 4037, 2252, 1428, 172, 3504, 958, 2848, 113, 3628, 1834, 3979, 19, 2317, 779, 2797, 518, 3174, 3549, 1482, 2266, 444, 2014, 3555, 2439, 1213, 3113, 535, 1135, 3204, 3858, 2309, 931, 623, 2009, 3359, 1566, 140, 3550,
|
||||
1808, 3872, 2488, 1152, 3764, 2892, 3960, 2412, 353, 1223, 1825, 3444, 3116, 1717, 1082, 2313, 1280, 2661, 82, 3852, 1389, 3200, 2330, 3812, 2038, 3581, 1728, 1039, 3339, 2427, 586, 2580, 1238, 3328, 2280, 1047, 595, 2662, 1363, 3338, 1620, 3934, 2497, 1881, 1054, 3954, 3215, 864, 2887, 1801, 320, 3519, 2378, 3704, 1753, 424, 2958, 1660, 4005, 2601, 1116, 3912, 2381, 573,
|
||||
2740, 200, 828, 1667, 432, 1931, 1035, 1616, 3598, 2640, 728, 264, 1437, 557, 3501, 2966, 372, 3734, 974, 1978, 758, 2719, 1145, 452, 1433, 725, 2681, 408, 3843, 1918, 1547, 3906, 1996, 503, 1456, 3019, 3493, 1700, 3742, 355, 2134, 176, 1311, 615, 2867, 315, 1680, 1314, 8, 3297, 1494, 783, 1950, 83, 2656, 1382, 3561, 138, 2834, 1404, 330, 1904, 3156, 1027,
|
||||
1357, 3381, 3041, 3666, 2729, 734, 3415, 177, 3051, 2021, 4079, 2823, 3775, 2186, 2616, 869, 1668, 3148, 2367, 3315, 393, 4075, 1870, 2920, 3343, 2362, 3188, 1303, 2782, 825, 3171, 259, 2905, 3717, 2538, 184, 2074, 838, 2860, 2407, 1024, 3496, 3008, 3706, 1985, 2349, 3623, 2582, 4058, 2184, 2694, 3873, 2964, 990, 3346, 690, 2033, 1066, 2201, 3490, 2971, 718, 3700, 2188,
|
||||
4061, 391, 1989, 2325, 1430, 3150, 2125, 2526, 592, 1403, 976, 2351, 1165, 1851, 114, 3921, 2063, 613, 1358, 2785, 1623, 2254, 25, 3542, 1045, 246, 1852, 3554, 87, 2243, 3615, 1169, 727, 1705, 968, 3957, 3185, 1251, 500, 4063, 1751, 2622, 842, 1519, 90, 3393, 819, 490, 1874, 999, 571, 1275, 2271, 1586, 4040, 2448, 3126, 3731, 436, 885, 1708, 2421, 24, 1599,
|
||||
889, 2563, 1199, 645, 70, 4013, 1237, 3723, 1694, 3499, 3, 3266, 484, 2997, 3390, 1233, 2842, 3687, 152, 3480, 1084, 3698, 881, 2490, 1542, 3992, 2209, 692, 1690, 3022, 1470, 2625, 2114, 3512, 2359, 381, 2684, 1897, 3368, 1395, 3080, 289, 2065, 3981, 2758, 1141, 3097, 1472, 2870, 3352, 3707, 225, 3159, 505, 1895, 214, 1222, 1774, 2686, 3978, 3275, 1196, 3518, 2825,
|
||||
3270, 1720, 3796, 3466, 2650, 1841, 298, 899, 2862, 2091, 2671, 1744, 3735, 801, 1560, 349, 2262, 903, 1833, 2524, 512, 3117, 1793, 2827, 476, 3038, 1216, 2550, 3826, 980, 431, 4048, 35, 2992, 1265, 1595, 765, 3675, 76, 2247, 696, 3456, 1254, 2452, 664, 1757, 2133, 3750, 145, 2332, 1554, 1981, 3580, 2712, 868, 3640, 2919, 638, 2275, 1427, 309, 2595, 2006, 492,
|
||||
2226, 178, 2911, 836, 1528, 3028, 2240, 3327, 404, 3970, 707, 1294, 2464, 2131, 4032, 2600, 3319, 1406, 2913, 3974, 2156, 1425, 221, 3877, 2017, 811, 3662, 272, 3287, 1988, 2408, 3357, 1746, 598, 3239, 3823, 2182, 2934, 1078, 2604, 3840, 1697, 2906, 413, 3210, 3880, 331, 2644, 1260, 848, 3042, 2535, 1077, 1438, 3261, 2365, 1561, 3799, 85, 3082, 1876, 674, 3932, 1101,
|
||||
3644, 1344, 1943, 2401, 390, 3835, 1048, 2572, 1541, 1133, 3075, 3584, 308, 2889, 1065, 1869, 601, 3783, 282, 1181, 736, 3312, 2368, 1126, 3383, 1675, 2734, 1426, 628, 2873, 1317, 843, 2717, 2048, 1004, 2536, 333, 1782, 3295, 1517, 219, 2153, 815, 3502, 1579, 2268, 987, 3409, 1780, 4018, 354, 665, 3914, 47, 1956, 456, 1006, 2010, 3406, 1130, 3621, 2894, 1549, 3092,
|
||||
2485, 640, 3993, 3179, 1270, 3436, 585, 1925, 3757, 2304, 136, 1976, 1486, 646, 3520, 50, 3155, 1637, 2435, 3522, 1937, 2756, 3748, 661, 2224, 58, 3230, 2357, 1830, 3892, 170, 3607, 1447, 3949, 190, 3392, 1336, 584, 4010, 918, 3016, 3670, 1155, 2406, 52, 1304, 3009, 607, 2085, 2699, 3205, 1848, 2291, 3402, 2764, 3865, 3048, 2508, 735, 2710, 443, 2341, 897, 263,
|
||||
1785, 2769, 983, 56, 2197, 1685, 2703, 202, 2944, 810, 3377, 2626, 3787, 3047, 2055, 1236, 2752, 2122, 945, 3093, 96, 1624, 439, 3014, 1388, 4015, 977, 448, 3506, 1098, 2242, 3026, 506, 2361, 2952, 1862, 3619, 2790, 1992, 2483, 525, 1868, 2652, 4093, 1998, 3595, 2478, 3816, 122, 1412, 929, 3716, 1166, 1648, 813, 1300, 199, 1489, 3998, 1771, 1310, 3808, 2052, 3423,
|
||||
434, 3712, 1625, 3558, 2955, 853, 4019, 1348, 3511, 1732, 1246, 487, 934, 1672, 2510, 3965, 788, 3711, 396, 1369, 4090, 1055, 2603, 1879, 3528, 2518, 2067, 3005, 1516, 2588, 751, 1740, 3418, 1131, 1576, 686, 2296, 1118, 18, 3263, 1365, 3401, 294, 737, 3177, 410, 867, 1633, 2963, 3579, 2375, 252, 2881, 479, 2471, 3576, 2180, 3306, 332, 2255, 3035, 41, 2648, 1396,
|
||||
2929, 2230, 1219, 2512, 446, 2008, 3189, 2388, 626, 2164, 2831, 4047, 2376, 174, 3272, 368, 1469, 3226, 2578, 1991, 2874, 2263, 3681, 876, 188, 1239, 683, 3776, 226, 3183, 4083, 2148, 63, 2649, 3859, 299, 3086, 3933, 1585, 2185, 3767, 988, 1707, 2908, 1407, 1844, 2771, 2245, 1161, 560, 1755, 3376, 2051, 4064, 3135, 1832, 652, 2853, 1051, 3649, 760, 3290, 1105, 3945,
|
||||
872, 154, 3207, 713, 3780, 1453, 281, 1087, 3695, 30, 3299, 1919, 1400, 3551, 1119, 1890, 2314, 618, 1703, 3428, 724, 295, 3146, 1557, 3341, 2896, 1683, 2723, 1974, 1017, 541, 1380, 3720, 804, 3280, 2082, 997, 2567, 777, 2961, 213, 2707, 2328, 3632, 1025, 3891, 3304, 255, 4003, 3108, 2587, 1323, 743, 1479, 105, 1013, 3901, 1618, 2044, 2627, 1465, 1846, 576, 1994,
|
||||
2560, 3521, 1742, 2118, 2800, 3404, 1783, 2609, 2968, 1582, 1022, 412, 2713, 687, 2976, 3857, 2761, 3620, 62, 1108, 3844, 1340, 2100, 540, 2345, 3925, 405, 3457, 1319, 2468, 3362, 2815, 1867, 2372, 1281, 1714, 3690, 482, 3498, 1842, 1285, 3994, 558, 2039, 81, 2499, 678, 1481, 1923, 964, 12, 3824, 2980, 2205, 2762, 3432, 2398, 181, 3247, 462, 4094, 2350, 3589, 3089,
|
||||
1555, 1094, 4041, 247, 1267, 908, 3959, 2041, 732, 3860, 2343, 3132, 3769, 2144, 1621, 237, 912, 1329, 3025, 2146, 2642, 1775, 3721, 2746, 1121, 1953, 902, 2285, 130, 3671, 1659, 278, 3153, 522, 2721, 123, 2996, 1466, 2380, 377, 3231, 873, 1510, 3476, 3123, 1250, 2147, 3650, 2839, 3451, 2323, 1122, 3545, 379, 1765, 1218, 603, 3768, 1360, 938, 2885, 133, 1245, 363,
|
||||
2364, 554, 2743, 3344, 2474, 530, 3112, 169, 1297, 3430, 536, 1741, 98, 1043, 2574, 3253, 2246, 1854, 4022, 510, 3283, 204, 858, 3398, 36, 3118, 1478, 3794, 2986, 706, 2176, 922, 3559, 1097, 3976, 3322, 2149, 1160, 2810, 3883, 2007, 2513, 2953, 328, 1721, 3793, 422, 2566, 807, 329, 1638, 1967, 648, 2520, 3727, 3109, 2116, 2927, 2491, 1939, 3365, 1709, 2728, 3815,
|
||||
2037, 3120, 831, 1405, 1896, 3592, 1622, 2369, 2864, 2151, 1107, 2542, 3532, 1410, 3917, 427, 3568, 709, 2509, 1503, 1037, 2973, 2436, 1604, 4035, 2594, 563, 1819, 2659, 1234, 4004, 2565, 1511, 2273, 1823, 336, 882, 3772, 575, 1628, 171, 3570, 1120, 2260, 2716, 935, 3064, 1806, 1342, 3144, 3900, 2744, 3296, 985, 1546, 238, 896, 1663, 305, 3660, 695, 2213, 960, 3407,
|
||||
144, 1795, 3894, 2267, 51, 2708, 1023, 3818, 366, 1821, 4087, 2985, 755, 2057, 2912, 949, 1583, 2774, 231, 3447, 2258, 3866, 1982, 672, 1225, 2077, 3320, 1062, 370, 3241, 1968, 7, 3068, 681, 3631, 2573, 1567, 3175, 2321, 1067, 3070, 722, 1856, 3744, 642, 1471, 4084, 131, 3514, 2443, 531, 1227, 155, 2265, 4024, 2658, 3326, 3910, 1168, 3078, 1530, 3956, 489, 1424,
|
||||
3647, 1203, 420, 2924, 3755, 719, 3248, 1376, 3067, 890, 196, 1559, 3269, 270, 2432, 1885, 3212, 1164, 3778, 1752, 579, 1338, 344, 3585, 3017, 288, 3658, 2371, 3882, 1691, 611, 2789, 3809, 1339, 389, 2950, 2015, 59, 3548, 2751, 2158, 4011, 1352, 29, 3388, 2370, 2812, 1946, 954, 2110, 1558, 2947, 3573, 1909, 1326, 679, 1853, 2312, 551, 2702, 33, 2414, 3209, 2824,
|
||||
2547, 2143, 3379, 966, 1492, 1979, 2479, 463, 2194, 3657, 2738, 2318, 1261, 3713, 604, 4002, 11, 2192, 2967, 919, 2607, 3369, 2837, 1676, 2539, 984, 1568, 93, 2901, 1318, 3538, 1041, 2216, 1756, 3454, 1030, 4050, 1402, 798, 1723, 311, 3277, 2546, 2886, 2043, 461, 1206, 3677, 361, 3260, 3988, 809, 2605, 470, 3007, 3517, 102, 3221, 1398, 2062, 3611, 1134, 1928, 865,
|
||||
4060, 621, 1710, 2606, 3510, 317, 4017, 1682, 3329, 1159, 1940, 654, 3461, 1789, 1015, 2691, 1455, 3599, 374, 1947, 4069, 71, 2126, 763, 3961, 2278, 3161, 1997, 824, 2623, 2080, 244, 3257, 780, 2732, 2308, 545, 3351, 2476, 3806, 1204, 588, 1591, 963, 3610, 1699, 754, 3049, 2651, 1106, 65, 2221, 1644, 3821, 1100, 2463, 1614, 3801, 965, 2965, 715, 3394, 1593, 212,
|
||||
};
|
||||
|
||||
#endif /* BLUE_NOISE_64X64_H */
|
679
vendor/pixman/pixman/dither/make-blue-noise.c
vendored
679
vendor/pixman/pixman/dither/make-blue-noise.c
vendored
@ -1,679 +0,0 @@
|
||||
/* Blue noise generation using the void-and-cluster method as described in
|
||||
*
|
||||
* The void-and-cluster method for dither array generation
|
||||
* Ulichney, Robert A (1993)
|
||||
*
|
||||
* http://cv.ulichney.com/papers/1993-void-cluster.pdf
|
||||
*
|
||||
* Note that running with openmp (-DUSE_OPENMP) will trigger additional
|
||||
* randomness due to computing reductions in parallel, and is not recommended
|
||||
* unless generating very large dither arrays.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Booleans and utility functions */
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
typedef int bool_t;
|
||||
|
||||
int
|
||||
imin (int x, int y)
|
||||
{
|
||||
return x < y ? x : y;
|
||||
}
|
||||
|
||||
/* Memory allocation */
|
||||
void *
|
||||
malloc_abc (unsigned int a, unsigned int b, unsigned int c)
|
||||
{
|
||||
if (a >= INT32_MAX / b)
|
||||
return NULL;
|
||||
else if (a * b >= INT32_MAX / c)
|
||||
return NULL;
|
||||
else
|
||||
return malloc (a * b * c);
|
||||
}
|
||||
|
||||
/* Random number generation */
|
||||
typedef uint32_t xorwow_state_t[5];
|
||||
|
||||
uint32_t
|
||||
xorwow_next (xorwow_state_t *state)
|
||||
{
|
||||
uint32_t s = (*state)[0],
|
||||
t = (*state)[3];
|
||||
(*state)[3] = (*state)[2];
|
||||
(*state)[2] = (*state)[1];
|
||||
(*state)[1] = s;
|
||||
|
||||
t ^= t >> 2;
|
||||
t ^= t << 1;
|
||||
t ^= s ^ (s << 4);
|
||||
|
||||
(*state)[0] = t;
|
||||
(*state)[4] += 362437;
|
||||
|
||||
return t + (*state)[4];
|
||||
}
|
||||
|
||||
float
|
||||
xorwow_float (xorwow_state_t *s)
|
||||
{
|
||||
return (xorwow_next (s) >> 9) / (float)((1 << 23) - 1);
|
||||
}
|
||||
|
||||
/* Floating point matrices
|
||||
*
|
||||
* Used to cache the cluster sizes.
|
||||
*/
|
||||
typedef struct matrix_t {
|
||||
int width;
|
||||
int height;
|
||||
float *buffer;
|
||||
} matrix_t;
|
||||
|
||||
bool_t
|
||||
matrix_init (matrix_t *matrix, int width, int height)
|
||||
{
|
||||
float *buffer;
|
||||
|
||||
if (!matrix)
|
||||
return FALSE;
|
||||
|
||||
buffer = malloc_abc (width, height, sizeof (float));
|
||||
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
matrix->buffer = buffer;
|
||||
matrix->width = width;
|
||||
matrix->height = height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
matrix_copy (matrix_t *dst, matrix_t const *src)
|
||||
{
|
||||
float *srcbuf = src->buffer,
|
||||
*srcend = src->buffer + src->width * src->height,
|
||||
*dstbuf = dst->buffer;
|
||||
|
||||
if (dst->width != src->width || dst->height != src->height)
|
||||
return FALSE;
|
||||
|
||||
while (srcbuf < srcend)
|
||||
*dstbuf++ = *srcbuf++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
float *
|
||||
matrix_get (matrix_t *matrix, int x, int y)
|
||||
{
|
||||
return &matrix->buffer[y * matrix->width + x];
|
||||
}
|
||||
|
||||
void
|
||||
matrix_destroy (matrix_t *matrix)
|
||||
{
|
||||
free (matrix->buffer);
|
||||
}
|
||||
|
||||
/* Binary patterns */
|
||||
typedef struct pattern_t {
|
||||
int width;
|
||||
int height;
|
||||
bool_t *buffer;
|
||||
} pattern_t;
|
||||
|
||||
bool_t
|
||||
pattern_init (pattern_t *pattern, int width, int height)
|
||||
{
|
||||
bool_t *buffer;
|
||||
|
||||
if (!pattern)
|
||||
return FALSE;
|
||||
|
||||
buffer = malloc_abc (width, height, sizeof (bool_t));
|
||||
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
pattern->buffer = buffer;
|
||||
pattern->width = width;
|
||||
pattern->height = height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
pattern_copy (pattern_t *dst, pattern_t const *src)
|
||||
{
|
||||
bool_t *srcbuf = src->buffer,
|
||||
*srcend = src->buffer + src->width * src->height,
|
||||
*dstbuf = dst->buffer;
|
||||
|
||||
if (dst->width != src->width || dst->height != src->height)
|
||||
return FALSE;
|
||||
|
||||
while (srcbuf < srcend)
|
||||
*dstbuf++ = *srcbuf++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t *
|
||||
pattern_get (pattern_t *pattern, int x, int y)
|
||||
{
|
||||
return &pattern->buffer[y * pattern->width + x];
|
||||
}
|
||||
|
||||
void
|
||||
pattern_fill_white_noise (pattern_t *pattern, float fraction,
|
||||
xorwow_state_t *s)
|
||||
{
|
||||
bool_t *buffer = pattern->buffer;
|
||||
bool_t *end = buffer + (pattern->width * pattern->height);
|
||||
|
||||
while (buffer < end)
|
||||
*buffer++ = xorwow_float (s) < fraction;
|
||||
}
|
||||
|
||||
void
|
||||
pattern_destroy (pattern_t *pattern)
|
||||
{
|
||||
free (pattern->buffer);
|
||||
}
|
||||
|
||||
/* Dither arrays */
|
||||
typedef struct array_t {
|
||||
int width;
|
||||
int height;
|
||||
uint32_t *buffer;
|
||||
} array_t;
|
||||
|
||||
bool_t
|
||||
array_init (array_t *array, int width, int height)
|
||||
{
|
||||
uint32_t *buffer;
|
||||
|
||||
if (!array)
|
||||
return FALSE;
|
||||
|
||||
buffer = malloc_abc (width, height, sizeof (uint32_t));
|
||||
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
array->buffer = buffer;
|
||||
array->width = width;
|
||||
array->height = height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
uint32_t *
|
||||
array_get (array_t *array, int x, int y)
|
||||
{
|
||||
return &array->buffer[y * array->width + x];
|
||||
}
|
||||
|
||||
bool_t
|
||||
array_save_ppm (array_t *array, const char *filename)
|
||||
{
|
||||
FILE *f = fopen(filename, "wb");
|
||||
|
||||
int i = 0;
|
||||
int bpp = 2;
|
||||
uint8_t buffer[1024];
|
||||
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
if (array->width * array->height - 1 < 256)
|
||||
bpp = 1;
|
||||
|
||||
fprintf(f, "P5 %d %d %d\n", array->width, array->height,
|
||||
array->width * array->height - 1);
|
||||
while (i < array->width * array->height)
|
||||
{
|
||||
int j = 0;
|
||||
for (; j < 1024 / bpp && j < array->width * array->height; ++j)
|
||||
{
|
||||
uint32_t v = array->buffer[i + j];
|
||||
if (bpp == 2)
|
||||
{
|
||||
buffer[2 * j] = v & 0xff;
|
||||
buffer[2 * j + 1] = (v & 0xff00) >> 8;
|
||||
} else {
|
||||
buffer[j] = v;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite((void *)buffer, bpp, j, f);
|
||||
i += j;
|
||||
}
|
||||
|
||||
if (fclose(f) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
array_save (array_t *array, const char *filename)
|
||||
{
|
||||
int x, y;
|
||||
FILE *f = fopen(filename, "wb");
|
||||
|
||||
if (!f)
|
||||
return FALSE;
|
||||
|
||||
fprintf (f,
|
||||
"/* WARNING: This file is generated by make-blue-noise.c\n"
|
||||
" * Please edit that file instead of this one.\n"
|
||||
" */\n"
|
||||
"\n"
|
||||
"#ifndef BLUE_NOISE_%dX%d_H\n"
|
||||
"#define BLUE_NOISE_%dX%d_H\n"
|
||||
"\n"
|
||||
"#include <stdint.h>\n"
|
||||
"\n", array->width, array->height, array->width, array->height);
|
||||
|
||||
fprintf (f, "static const uint16_t dither_blue_noise_%dx%d[%d] = {\n",
|
||||
array->width, array->height, array->width * array->height);
|
||||
|
||||
for (y = 0; y < array->height; ++y)
|
||||
{
|
||||
fprintf (f, " ");
|
||||
for (x = 0; x < array->width; ++x)
|
||||
{
|
||||
if (x != 0)
|
||||
fprintf (f, ", ");
|
||||
|
||||
fprintf (f, "%d", *array_get (array, x, y));
|
||||
}
|
||||
|
||||
fprintf (f, ",\n");
|
||||
}
|
||||
fprintf (f, "};\n");
|
||||
|
||||
fprintf (f, "\n#endif /* BLUE_NOISE_%dX%d_H */\n",
|
||||
array->width, array->height);
|
||||
|
||||
if (fclose(f) != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
array_destroy (array_t *array)
|
||||
{
|
||||
free (array->buffer);
|
||||
}
|
||||
|
||||
/* Dither array generation */
|
||||
bool_t
|
||||
compute_cluster_sizes (pattern_t *pattern, matrix_t *matrix)
|
||||
{
|
||||
int width = pattern->width,
|
||||
height = pattern->height;
|
||||
|
||||
if (matrix->width != width || matrix->height != height)
|
||||
return FALSE;
|
||||
|
||||
int px, py, qx, qy, dx, dy;
|
||||
float tsqsi = 2.f * 1.5f * 1.5f;
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp parallel for default (none) \
|
||||
private (py, px, qy, qx, dx, dy) \
|
||||
shared (height, width, pattern, matrix, tsqsi)
|
||||
#endif
|
||||
for (py = 0; py < height; ++py)
|
||||
{
|
||||
for (px = 0; px < width; ++px)
|
||||
{
|
||||
bool_t pixel = *pattern_get (pattern, px, py);
|
||||
float dist = 0.f;
|
||||
|
||||
for (qx = 0; qx < width; ++qx)
|
||||
{
|
||||
dx = imin (abs (qx - px), width - abs (qx - px));
|
||||
dx = dx * dx;
|
||||
|
||||
for (qy = 0; qy < height; ++qy)
|
||||
{
|
||||
dy = imin (abs (qy - py), height - abs (qy - py));
|
||||
dy = dy * dy;
|
||||
|
||||
dist += (pixel == *pattern_get (pattern, qx, qy))
|
||||
* expf (- (dx + dy) / tsqsi);
|
||||
}
|
||||
}
|
||||
|
||||
*matrix_get (matrix, px, py) = dist;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
swap_pixel (pattern_t *pattern, matrix_t *matrix, int x, int y)
|
||||
{
|
||||
int width = pattern->width,
|
||||
height = pattern->height;
|
||||
|
||||
bool_t new;
|
||||
|
||||
float f,
|
||||
dist = 0.f,
|
||||
tsqsi = 2.f * 1.5f * 1.5f;
|
||||
|
||||
int px, py, dx, dy;
|
||||
bool_t b;
|
||||
|
||||
new = !*pattern_get (pattern, x, y);
|
||||
*pattern_get (pattern, x, y) = new;
|
||||
|
||||
if (matrix->width != width || matrix->height != height)
|
||||
return FALSE;
|
||||
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp parallel for reduction (+:dist) default (none) \
|
||||
private (px, py, dx, dy, b, f) \
|
||||
shared (x, y, width, height, pattern, matrix, new, tsqsi)
|
||||
#endif
|
||||
for (py = 0; py < height; ++py)
|
||||
{
|
||||
dy = imin (abs (py - y), height - abs (py - y));
|
||||
dy = dy * dy;
|
||||
|
||||
for (px = 0; px < width; ++px)
|
||||
{
|
||||
dx = imin (abs (px - x), width - abs (px - x));
|
||||
dx = dx * dx;
|
||||
|
||||
b = (*pattern_get (pattern, px, py) == new);
|
||||
f = expf (- (dx + dy) / tsqsi);
|
||||
*matrix_get (matrix, px, py) += (2 * b - 1) * f;
|
||||
|
||||
dist += b * f;
|
||||
}
|
||||
}
|
||||
|
||||
*matrix_get (matrix, x, y) = dist;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
largest_cluster (pattern_t *pattern, matrix_t *matrix,
|
||||
bool_t pixel, int *xmax, int *ymax)
|
||||
{
|
||||
int width = pattern->width,
|
||||
height = pattern->height;
|
||||
|
||||
int x, y;
|
||||
|
||||
float vmax = -INFINITY;
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp parallel default (none) \
|
||||
private (x, y) \
|
||||
shared (height, width, pattern, matrix, pixel, xmax, ymax, vmax)
|
||||
#endif
|
||||
{
|
||||
int xbest = -1,
|
||||
ybest = -1;
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
float vbest = -INFINITY;
|
||||
|
||||
#pragma omp for reduction (max: vmax) collapse (2)
|
||||
#endif
|
||||
for (y = 0; y < height; ++y)
|
||||
{
|
||||
for (x = 0; x < width; ++x)
|
||||
{
|
||||
if (*pattern_get (pattern, x, y) != pixel)
|
||||
continue;
|
||||
|
||||
if (*matrix_get (matrix, x, y) > vmax)
|
||||
{
|
||||
vmax = *matrix_get (matrix, x, y);
|
||||
#ifdef USE_OPENMP
|
||||
vbest = vmax;
|
||||
#endif
|
||||
xbest = x;
|
||||
ybest = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_OPENMP
|
||||
#pragma omp barrier
|
||||
#pragma omp critical
|
||||
{
|
||||
if (vmax == vbest)
|
||||
{
|
||||
*xmax = xbest;
|
||||
*ymax = ybest;
|
||||
}
|
||||
}
|
||||
#else
|
||||
*xmax = xbest;
|
||||
*ymax = ybest;
|
||||
#endif
|
||||
}
|
||||
|
||||
assert (vmax > -INFINITY);
|
||||
}
|
||||
|
||||
void
|
||||
generate_initial_binary_pattern (pattern_t *pattern, matrix_t *matrix)
|
||||
{
|
||||
int xcluster = 0,
|
||||
ycluster = 0,
|
||||
xvoid = 0,
|
||||
yvoid = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
largest_cluster (pattern, matrix, TRUE, &xcluster, &ycluster);
|
||||
assert (*pattern_get (pattern, xcluster, ycluster) == TRUE);
|
||||
swap_pixel (pattern, matrix, xcluster, ycluster);
|
||||
|
||||
largest_cluster (pattern, matrix, FALSE, &xvoid, &yvoid);
|
||||
assert (*pattern_get (pattern, xvoid, yvoid) == FALSE);
|
||||
swap_pixel (pattern, matrix, xvoid, yvoid);
|
||||
|
||||
if (xcluster == xvoid && ycluster == yvoid)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool_t
|
||||
generate_dither_array (array_t *array,
|
||||
pattern_t const *prototype, matrix_t const *matrix,
|
||||
pattern_t *temp_pattern, matrix_t *temp_matrix)
|
||||
{
|
||||
int width = prototype->width,
|
||||
height = prototype->height;
|
||||
|
||||
int x, y, rank;
|
||||
|
||||
int initial_rank = 0;
|
||||
|
||||
if (array->width != width || array->height != height)
|
||||
return FALSE;
|
||||
|
||||
// Make copies of the prototype and associated sizes matrix since we will
|
||||
// trash them
|
||||
if (!pattern_copy (temp_pattern, prototype))
|
||||
return FALSE;
|
||||
|
||||
if (!matrix_copy (temp_matrix, matrix))
|
||||
return FALSE;
|
||||
|
||||
// Compute initial rank
|
||||
for (y = 0; y < height; ++y)
|
||||
{
|
||||
for (x = 0; x < width; ++x)
|
||||
{
|
||||
if (*pattern_get (temp_pattern, x, y))
|
||||
initial_rank += 1;
|
||||
|
||||
*array_get (array, x, y) = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 1
|
||||
for (rank = initial_rank; rank > 0; --rank)
|
||||
{
|
||||
largest_cluster (temp_pattern, temp_matrix, TRUE, &x, &y);
|
||||
swap_pixel (temp_pattern, temp_matrix, x, y);
|
||||
*array_get (array, x, y) = rank - 1;
|
||||
}
|
||||
|
||||
// Make copies again for phases 2 & 3
|
||||
if (!pattern_copy (temp_pattern, prototype))
|
||||
return FALSE;
|
||||
|
||||
if (!matrix_copy (temp_matrix, matrix))
|
||||
return FALSE;
|
||||
|
||||
// Phase 2 & 3
|
||||
for (rank = initial_rank; rank < width * height; ++rank)
|
||||
{
|
||||
largest_cluster (temp_pattern, temp_matrix, FALSE, &x, &y);
|
||||
swap_pixel (temp_pattern, temp_matrix, x, y);
|
||||
*array_get (array, x, y) = rank;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool_t
|
||||
generate (int size, xorwow_state_t *s,
|
||||
char const *c_filename, char const *ppm_filename)
|
||||
{
|
||||
bool_t ok = TRUE;
|
||||
|
||||
pattern_t prototype, temp_pattern;
|
||||
array_t array;
|
||||
matrix_t matrix, temp_matrix;
|
||||
|
||||
printf ("Generating %dx%d blue noise...\n", size, size);
|
||||
|
||||
if (!pattern_init (&prototype, size, size))
|
||||
return FALSE;
|
||||
|
||||
if (!pattern_init (&temp_pattern, size, size))
|
||||
{
|
||||
pattern_destroy (&prototype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!matrix_init (&matrix, size, size))
|
||||
{
|
||||
pattern_destroy (&temp_pattern);
|
||||
pattern_destroy (&prototype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!matrix_init (&temp_matrix, size, size))
|
||||
{
|
||||
matrix_destroy (&matrix);
|
||||
pattern_destroy (&temp_pattern);
|
||||
pattern_destroy (&prototype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!array_init (&array, size, size))
|
||||
{
|
||||
matrix_destroy (&temp_matrix);
|
||||
matrix_destroy (&matrix);
|
||||
pattern_destroy (&temp_pattern);
|
||||
pattern_destroy (&prototype);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
printf("Filling initial binary pattern with white noise...\n");
|
||||
pattern_fill_white_noise (&prototype, .1, s);
|
||||
|
||||
printf("Initializing cluster sizes...\n");
|
||||
if (!compute_cluster_sizes (&prototype, &matrix))
|
||||
{
|
||||
fprintf (stderr, "Error while computing cluster sizes\n");
|
||||
ok = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Generating initial binary pattern...\n");
|
||||
generate_initial_binary_pattern (&prototype, &matrix);
|
||||
|
||||
printf("Generating dither array...\n");
|
||||
if (!generate_dither_array (&array, &prototype, &matrix,
|
||||
&temp_pattern, &temp_matrix))
|
||||
{
|
||||
fprintf (stderr, "Error while generating dither array\n");
|
||||
ok = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Saving dither array...\n");
|
||||
if (!array_save (&array, c_filename))
|
||||
{
|
||||
fprintf (stderr, "Error saving dither array\n");
|
||||
ok = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if SAVE_PPM
|
||||
if (!array_save_ppm (&array, ppm_filename))
|
||||
{
|
||||
fprintf (stderr, "Error saving dither array PPM\n");
|
||||
ok = FALSE;
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
(void)ppm_filename;
|
||||
#endif
|
||||
|
||||
printf("All done!\n");
|
||||
|
||||
out:
|
||||
array_destroy (&array);
|
||||
matrix_destroy (&temp_matrix);
|
||||
matrix_destroy (&matrix);
|
||||
pattern_destroy (&temp_pattern);
|
||||
pattern_destroy (&prototype);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
xorwow_state_t s = {1185956906, 12385940, 983948, 349208051, 901842};
|
||||
|
||||
if (!generate (64, &s, "blue-noise-64x64.h", "blue-noise-64x64.ppm"))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
412
vendor/pixman/pixman/loongson-mmintrin.h
vendored
412
vendor/pixman/pixman/loongson-mmintrin.h
vendored
@ -1,412 +0,0 @@
|
||||
/* The gcc-provided loongson intrinsic functions are way too fucking broken
|
||||
* to be of any use, otherwise I'd use them.
|
||||
*
|
||||
* - The hardware instructions are very similar to MMX or iwMMXt. Certainly
|
||||
* close enough that they could have implemented the _mm_*-style intrinsic
|
||||
* interface and had a ton of optimized code available to them. Instead they
|
||||
* implemented something much, much worse.
|
||||
*
|
||||
* - pshuf takes a dead first argument, causing extra instructions to be
|
||||
* generated.
|
||||
*
|
||||
* - There are no 64-bit shift or logical intrinsics, which means you have
|
||||
* to implement them with inline assembly, but this is a nightmare because
|
||||
* gcc doesn't understand that the integer vector datatypes are actually in
|
||||
* floating-point registers, so you end up with braindead code like
|
||||
*
|
||||
* punpcklwd $f9,$f9,$f5
|
||||
* dmtc1 v0,$f8
|
||||
* punpcklwd $f19,$f19,$f5
|
||||
* dmfc1 t9,$f9
|
||||
* dmtc1 v0,$f9
|
||||
* dmtc1 t9,$f20
|
||||
* dmfc1 s0,$f19
|
||||
* punpcklbh $f20,$f20,$f2
|
||||
*
|
||||
* where crap just gets copied back and forth between integer and floating-
|
||||
* point registers ad nauseum.
|
||||
*
|
||||
* Instead of trying to workaround the problems from these crap intrinsics, I
|
||||
* just implement the _mm_* intrinsics needed for pixman-mmx.c using inline
|
||||
* assembly.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* vectors are stored in 64-bit floating-point registers */
|
||||
typedef double __m64;
|
||||
/* having a 32-bit datatype allows us to use 32-bit loads in places like load8888 */
|
||||
typedef float __m32;
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_setzero_si64 (void)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_add_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("paddh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_add_pi32 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("paddw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_adds_pu16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("paddush %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_adds_pu8 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("paddusb %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_and_si64 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("and %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_cmpeq_pi32 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pcmpeqw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_empty (void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_madd_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pmaddhw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_mulhi_pu16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pmulhuh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_mullo_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pmullh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_or_si64 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("or %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_packs_pu16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("packushb %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_packs_pi32 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("packsswh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \
|
||||
(((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0))
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_set_pi16 (uint16_t __w3, uint16_t __w2, uint16_t __w1, uint16_t __w0)
|
||||
{
|
||||
if (__builtin_constant_p (__w3) &&
|
||||
__builtin_constant_p (__w2) &&
|
||||
__builtin_constant_p (__w1) &&
|
||||
__builtin_constant_p (__w0))
|
||||
{
|
||||
uint64_t val = ((uint64_t)__w3 << 48)
|
||||
| ((uint64_t)__w2 << 32)
|
||||
| ((uint64_t)__w1 << 16)
|
||||
| ((uint64_t)__w0 << 0);
|
||||
return *(__m64 *)&val;
|
||||
}
|
||||
else if (__w3 == __w2 && __w2 == __w1 && __w1 == __w0)
|
||||
{
|
||||
/* TODO: handle other cases */
|
||||
uint64_t val = __w3;
|
||||
uint64_t imm = _MM_SHUFFLE (0, 0, 0, 0);
|
||||
__m64 ret;
|
||||
asm("pshufh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (*(__m64 *)&val), "f" (*(__m64 *)&imm)
|
||||
);
|
||||
return ret;
|
||||
} else {
|
||||
uint64_t val = ((uint64_t)__w3 << 48)
|
||||
| ((uint64_t)__w2 << 32)
|
||||
| ((uint64_t)__w1 << 16)
|
||||
| ((uint64_t)__w0 << 0);
|
||||
return *(__m64 *)&val;
|
||||
}
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_set_pi32 (unsigned __i1, unsigned __i0)
|
||||
{
|
||||
if (__builtin_constant_p (__i1) &&
|
||||
__builtin_constant_p (__i0))
|
||||
{
|
||||
uint64_t val = ((uint64_t)__i1 << 32)
|
||||
| ((uint64_t)__i0 << 0);
|
||||
return *(__m64 *)&val;
|
||||
}
|
||||
else if (__i1 == __i0)
|
||||
{
|
||||
uint64_t imm = _MM_SHUFFLE (1, 0, 1, 0);
|
||||
__m64 ret;
|
||||
asm("pshufh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (*(__m32 *)&__i1), "f" (*(__m64 *)&imm)
|
||||
);
|
||||
return ret;
|
||||
} else {
|
||||
uint64_t val = ((uint64_t)__i1 << 32)
|
||||
| ((uint64_t)__i0 << 0);
|
||||
return *(__m64 *)&val;
|
||||
}
|
||||
}
|
||||
#undef _MM_SHUFFLE
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_shuffle_pi16 (__m64 __m, int64_t __n)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pshufh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__n)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_slli_pi16 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("psllh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_slli_si64 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("dsll %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_srli_pi16 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("psrlh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_srli_pi32 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("psrlw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_srli_si64 (__m64 __m, int64_t __count)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("dsrl %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__count)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_sub_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("psubh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpackhi_pi8 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpckhbh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpackhi_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpckhhw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpacklo_pi8 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpcklbh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Since punpcklbh doesn't care about the high 32-bits, we use the __m32 datatype which
|
||||
* allows load8888 to use 32-bit loads */
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpacklo_pi8_f (__m32 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpcklbh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_unpacklo_pi16 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("punpcklhw %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
_mm_xor_si64 (__m64 __m1, __m64 __m2)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("xor %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
loongson_extract_pi16 (__m64 __m, int64_t __pos)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pextrh %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m), "f" (*(__m64 *)&__pos)
|
||||
);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||
loongson_insert_pi16 (__m64 __m1, __m64 __m2, int64_t __pos)
|
||||
{
|
||||
__m64 ret;
|
||||
asm("pinsrh_%3 %0, %1, %2\n\t"
|
||||
: "=f" (ret)
|
||||
: "f" (__m1), "f" (__m2), "i" (__pos)
|
||||
);
|
||||
return ret;
|
||||
}
|
115
vendor/pixman/pixman/make-srgb.pl
vendored
115
vendor/pixman/pixman/make-srgb.pl
vendored
@ -1,115 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use strict;
|
||||
|
||||
sub linear_to_srgb
|
||||
{
|
||||
my ($c) = @_;
|
||||
|
||||
if ($c < 0.0031308)
|
||||
{
|
||||
return $c * 12.92;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1.055 * $c ** (1.0/2.4) - 0.055;
|
||||
}
|
||||
}
|
||||
|
||||
sub srgb_to_linear
|
||||
{
|
||||
my ($c) = @_;
|
||||
|
||||
if ($c < 0.04045)
|
||||
{
|
||||
return $c / 12.92;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (($c + 0.055) / 1.055) ** 2.4
|
||||
}
|
||||
}
|
||||
|
||||
my @linear_to_srgb;
|
||||
for my $linear (0 .. 4095)
|
||||
{
|
||||
my $srgb = int(linear_to_srgb($linear / 4095.0) * 255.0 + 0.5);
|
||||
push @linear_to_srgb, $srgb;
|
||||
}
|
||||
|
||||
my @srgb_to_linear;
|
||||
for my $srgb (0 .. 255)
|
||||
{
|
||||
my $linear = int(srgb_to_linear($srgb / 255.0) * 65535.0 + 0.5);
|
||||
push @srgb_to_linear, $linear;
|
||||
}
|
||||
|
||||
# Ensure that we have a lossless sRGB and back conversion loop.
|
||||
# some of the darkest shades need a little bias -- maximum is just
|
||||
# 5 increments out of 16. This gives us useful property with
|
||||
# least amount of error in the sRGB-to-linear table, and keeps the actual
|
||||
# table lookup in the other direction as simple as possible.
|
||||
for my $srgb (0 .. $#srgb_to_linear)
|
||||
{
|
||||
my $add = 0;
|
||||
while (1)
|
||||
{
|
||||
my $linear = $srgb_to_linear[$srgb];
|
||||
my $srgb_lossy = $linear_to_srgb[$linear >> 4];
|
||||
last if $srgb == $srgb_lossy;
|
||||
|
||||
# Add slight bias to this component until it rounds correctly
|
||||
$srgb_to_linear[$srgb] ++;
|
||||
$add ++;
|
||||
}
|
||||
die "Too many adds at $srgb" if $add > 5;
|
||||
}
|
||||
|
||||
print <<"PROLOG";
|
||||
/* WARNING: This file is generated by $0.
|
||||
* Please edit that file instead of this one.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
PROLOG
|
||||
|
||||
print "const uint8_t linear_to_srgb[" . @linear_to_srgb . "] =\n";
|
||||
print "{\n";
|
||||
for my $linear (0 .. $#linear_to_srgb)
|
||||
{
|
||||
if (($linear % 10) == 0)
|
||||
{
|
||||
print "\t";
|
||||
}
|
||||
print sprintf("%d, ", $linear_to_srgb[$linear]);
|
||||
if (($linear % 10) == 9)
|
||||
{
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
print "\n};\n";
|
||||
print "\n";
|
||||
|
||||
print "const uint16_t srgb_to_linear[" . @srgb_to_linear . "] =\n";
|
||||
print "{\n";
|
||||
for my $srgb (0 .. $#srgb_to_linear)
|
||||
{
|
||||
if (($srgb % 10) == 0)
|
||||
{
|
||||
print "\t";
|
||||
}
|
||||
print sprintf("%d, ", $srgb_to_linear[$srgb]);
|
||||
if (($srgb % 10) == 9)
|
||||
{
|
||||
print "\n";
|
||||
}
|
||||
}
|
||||
print "\n};\n";
|
||||
|
143
vendor/pixman/pixman/meson.build
vendored
143
vendor/pixman/pixman/meson.build
vendored
@ -1,143 +0,0 @@
|
||||
# Copyright © 2018 Intel Corporation
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
config_h = configure_file(
|
||||
configuration : config,
|
||||
output : 'pixman-config.h'
|
||||
)
|
||||
|
||||
version_h = configure_file(
|
||||
configuration : version_conf,
|
||||
input : 'pixman-version.h.in',
|
||||
output : 'pixman-version.h',
|
||||
install_dir : join_paths(get_option('prefix'), get_option('includedir'), 'pixman-1')
|
||||
)
|
||||
|
||||
libpixman_extra_cargs = []
|
||||
default_library = get_option('default_library')
|
||||
if default_library != 'static' and cc.has_function_attribute('dllexport')
|
||||
libpixman_extra_cargs = ['-DPIXMAN_API=__declspec(dllexport)']
|
||||
endif
|
||||
|
||||
pixman_simd_libs = []
|
||||
simds = [
|
||||
# the mmx library can be compiled with mmx on x86/x86_64, iwmmxt on
|
||||
# some arm cores, or loongson mmi on loongson mips systems. The
|
||||
# libraries will all have the same name, "pixman-mmx", but there is
|
||||
# no chance of more than one version being built in the same build
|
||||
# because no system could have mmx, iwmmxt, and mmi, and it
|
||||
# simplifies the build logic to give them the same name.
|
||||
['mmx', have_mmx, mmx_flags, []],
|
||||
['mmx', have_loongson_mmi, loongson_mmi_flags, []],
|
||||
['mmx', have_iwmmxt, iwmmxt_flags, []],
|
||||
|
||||
['sse2', have_sse2, sse2_flags, []],
|
||||
['ssse3', have_ssse3, ssse3_flags, []],
|
||||
['vmx', have_vmx, vmx_flags, []],
|
||||
['arm-simd', have_armv6_simd, [],
|
||||
['pixman-arm-simd-asm.S', 'pixman-arm-simd-asm-scaled.S']],
|
||||
['arm-neon', have_neon, [],
|
||||
['pixman-arm-neon-asm.S', 'pixman-arm-neon-asm-bilinear.S']],
|
||||
['arm-neon', have_a64neon, [],
|
||||
['pixman-arma64-neon-asm.S', 'pixman-arma64-neon-asm-bilinear.S']],
|
||||
['mips-dspr2', have_mips_dspr2, mips_dspr2_flags,
|
||||
['pixman-mips-dspr2-asm.S', 'pixman-mips-memcpy-asm.S']],
|
||||
]
|
||||
|
||||
foreach simd : simds
|
||||
if simd[1]
|
||||
name = 'pixman-' + simd[0]
|
||||
pixman_simd_libs += static_library(
|
||||
name,
|
||||
[name + '.c', config_h, version_h, simd[3]],
|
||||
c_args : simd[2]
|
||||
)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
pixman_files = files(
|
||||
'pixman.c',
|
||||
'pixman-access.c',
|
||||
'pixman-access-accessors.c',
|
||||
'pixman-bits-image.c',
|
||||
'pixman-combine32.c',
|
||||
'pixman-combine-float.c',
|
||||
'pixman-conical-gradient.c',
|
||||
'pixman-filter.c',
|
||||
'pixman-x86.c',
|
||||
'pixman-mips.c',
|
||||
'pixman-arm.c',
|
||||
'pixman-ppc.c',
|
||||
'pixman-edge.c',
|
||||
'pixman-edge-accessors.c',
|
||||
'pixman-fast-path.c',
|
||||
'pixman-glyph.c',
|
||||
'pixman-general.c',
|
||||
'pixman-gradient-walker.c',
|
||||
'pixman-image.c',
|
||||
'pixman-implementation.c',
|
||||
'pixman-linear-gradient.c',
|
||||
'pixman-matrix.c',
|
||||
'pixman-noop.c',
|
||||
'pixman-radial-gradient.c',
|
||||
'pixman-region16.c',
|
||||
'pixman-region32.c',
|
||||
'pixman-solid-fill.c',
|
||||
'pixman-timer.c',
|
||||
'pixman-trap.c',
|
||||
'pixman-utils.c',
|
||||
)
|
||||
|
||||
# Android cpu-features
|
||||
cpu_features_path = get_option('cpu-features-path')
|
||||
cpu_features_sources = []
|
||||
cpu_features_inc = []
|
||||
if cpu_features_path != ''
|
||||
message('Using cpu-features.[ch] from ' + cpu_features_path)
|
||||
cpu_features_sources = files(
|
||||
cpu_features_path / 'cpu-features.h',
|
||||
cpu_features_path / 'cpu-features.c',
|
||||
)
|
||||
cpu_features_inc = include_directories(cpu_features_path)
|
||||
endif
|
||||
|
||||
libpixman = library(
|
||||
'pixman-1',
|
||||
[pixman_files, config_h, version_h, cpu_features_sources],
|
||||
link_with: pixman_simd_libs,
|
||||
c_args : libpixman_extra_cargs,
|
||||
dependencies : [dep_m, dep_threads],
|
||||
include_directories : cpu_features_inc,
|
||||
version : meson.project_version(),
|
||||
install : true,
|
||||
)
|
||||
|
||||
inc_pixman = include_directories('.')
|
||||
|
||||
idep_pixman = declare_dependency(
|
||||
link_with: libpixman,
|
||||
include_directories : inc_pixman,
|
||||
)
|
||||
|
||||
if meson.version().version_compare('>= 0.54.0')
|
||||
meson.override_dependency('pixman-1', idep_pixman)
|
||||
endif
|
||||
|
||||
install_headers('pixman.h', subdir : 'pixman-1')
|
@ -1,3 +0,0 @@
|
||||
#define PIXMAN_FB_ACCESSORS
|
||||
|
||||
#include "pixman-access.c"
|
1715
vendor/pixman/pixman/pixman-access.c
vendored
1715
vendor/pixman/pixman/pixman-access.c
vendored
File diff suppressed because it is too large
Load Diff
25
vendor/pixman/pixman/pixman-accessor.h
vendored
25
vendor/pixman/pixman/pixman-accessor.h
vendored
@ -1,25 +0,0 @@
|
||||
#ifdef PIXMAN_FB_ACCESSORS
|
||||
|
||||
#define READ(img, ptr) \
|
||||
(((bits_image_t *)(img))->read_func ((ptr), sizeof(*(ptr))))
|
||||
#define WRITE(img, ptr,val) \
|
||||
(((bits_image_t *)(img))->write_func ((ptr), (val), sizeof (*(ptr))))
|
||||
|
||||
#define MEMSET_WRAPPED(img, dst, val, size) \
|
||||
do { \
|
||||
size_t _i; \
|
||||
uint8_t *_dst = (uint8_t*)(dst); \
|
||||
for(_i = 0; _i < (size_t) size; _i++) { \
|
||||
WRITE((img), _dst +_i, (val)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define READ(img, ptr) (*(ptr))
|
||||
#define WRITE(img, ptr, val) (*(ptr) = (val))
|
||||
#define MEMSET_WRAPPED(img, dst, val, size) \
|
||||
memset(dst, val, size)
|
||||
|
||||
#endif
|
||||
|
37
vendor/pixman/pixman/pixman-arm-asm.h
vendored
37
vendor/pixman/pixman/pixman-arm-asm.h
vendored
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2008 Mozilla Corporation
|
||||
* Copyright © 2010 Nokia Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Mozilla Corporation not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Mozilla Corporation makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Jeff Muizelaar (jeff@infidigm.net)
|
||||
*
|
||||
*/
|
||||
|
||||
/* Supplementary macro for setting function attributes */
|
||||
.macro pixman_asm_function fname
|
||||
.func fname
|
||||
.global fname
|
||||
#ifdef __ELF__
|
||||
.hidden fname
|
||||
.type fname, %function
|
||||
#endif
|
||||
fname:
|
||||
.endm
|
419
vendor/pixman/pixman/pixman-arm-common.h
vendored
419
vendor/pixman/pixman/pixman-arm-common.h
vendored
@ -1,419 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2010 Nokia Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Siarhei Siamashka (siarhei.siamashka@nokia.com)
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_ARM_COMMON_H
|
||||
#define PIXMAN_ARM_COMMON_H
|
||||
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
/* Define some macros which can expand into proxy functions between
|
||||
* ARM assembly optimized functions and the rest of pixman fast path API.
|
||||
*
|
||||
* All the low level ARM assembly functions have to use ARM EABI
|
||||
* calling convention and take up to 8 arguments:
|
||||
* width, height, dst, dst_stride, src, src_stride, mask, mask_stride
|
||||
*
|
||||
* The arguments are ordered with the most important coming first (the
|
||||
* first 4 arguments are passed to function in registers, the rest are
|
||||
* on stack). The last arguments are optional, for example if the
|
||||
* function is not using mask, then 'mask' and 'mask_stride' can be
|
||||
* omitted when doing a function call.
|
||||
*
|
||||
* Arguments 'src' and 'mask' contain either a pointer to the top left
|
||||
* pixel of the composited rectangle or a pixel color value depending
|
||||
* on the function type. In the case of just a color value (solid source
|
||||
* or mask), the corresponding stride argument is unused.
|
||||
*/
|
||||
|
||||
#define SKIP_ZERO_SRC 1
|
||||
#define SKIP_ZERO_MASK 2
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_SRC_DST(cputype, name, \
|
||||
src_type, src_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
src_type *src, \
|
||||
int32_t src_stride); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
src_type *src_line; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src_line, src_stride); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_N_DST(flags, cputype, name, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
uint32_t src); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
int32_t dst_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST(flags, cputype, name, \
|
||||
mask_type, mask_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
uint32_t src, \
|
||||
int32_t unused, \
|
||||
mask_type *mask, \
|
||||
int32_t mask_stride); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
mask_type *mask_line; \
|
||||
int32_t dst_stride, mask_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
|
||||
mask_stride, mask_line, mask_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src, 0, \
|
||||
mask_line, mask_stride); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST(flags, cputype, name, \
|
||||
src_type, src_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
src_type *src, \
|
||||
int32_t src_stride, \
|
||||
uint32_t mask); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
src_type *src_line; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
uint32_t mask; \
|
||||
\
|
||||
mask = _pixman_image_get_solid ( \
|
||||
imp, mask_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_MASK) && mask == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src_line, src_stride, \
|
||||
mask); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST(cputype, name, \
|
||||
src_type, src_cnt, \
|
||||
mask_type, mask_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
int32_t h, \
|
||||
dst_type *dst, \
|
||||
int32_t dst_stride, \
|
||||
src_type *src, \
|
||||
int32_t src_stride, \
|
||||
mask_type *mask, \
|
||||
int32_t mask_stride); \
|
||||
\
|
||||
static void \
|
||||
cputype##_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
src_type *src_line; \
|
||||
mask_type *mask_line; \
|
||||
int32_t dst_stride, src_stride, mask_stride; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
|
||||
mask_stride, mask_line, mask_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
dst_line, dst_stride, \
|
||||
src_line, src_stride, \
|
||||
mask_line, mask_stride); \
|
||||
}
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST(cputype, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \
|
||||
int32_t w, \
|
||||
dst_type * dst, \
|
||||
const src_type * src, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \
|
||||
const src_type * ps, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \
|
||||
vx, unit_x, \
|
||||
max_vx); \
|
||||
} \
|
||||
\
|
||||
FAST_NEAREST_MAINLOOP (cputype##_##name##_cover_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op, \
|
||||
src_type, dst_type, COVER) \
|
||||
FAST_NEAREST_MAINLOOP (cputype##_##name##_none_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op, \
|
||||
src_type, dst_type, NONE) \
|
||||
FAST_NEAREST_MAINLOOP (cputype##_##name##_pad_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op, \
|
||||
src_type, dst_type, PAD) \
|
||||
FAST_NEAREST_MAINLOOP (cputype##_##name##_normal_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op, \
|
||||
src_type, dst_type, NORMAL)
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST(flags, cputype, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \
|
||||
int32_t w, \
|
||||
dst_type * dst, \
|
||||
const src_type * src, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
const uint8_t * mask); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op (const uint8_t * mask, \
|
||||
dst_type * pd, \
|
||||
const src_type * ps, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \
|
||||
vx, unit_x, \
|
||||
max_vx, \
|
||||
mask); \
|
||||
} \
|
||||
\
|
||||
FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op,\
|
||||
src_type, uint8_t, dst_type, COVER, TRUE, FALSE)\
|
||||
FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op,\
|
||||
src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \
|
||||
FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op,\
|
||||
src_type, uint8_t, dst_type, PAD, TRUE, FALSE) \
|
||||
FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
|
||||
scaled_nearest_scanline_##cputype##_##name##_##op,\
|
||||
src_type, uint8_t, dst_type, NORMAL, TRUE, FALSE)
|
||||
|
||||
/* Provide entries for the fast path table */
|
||||
#define PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func) \
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (op,s,d,func), \
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH_NORMAL (op,s,d,func)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST(flags, cputype, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \
|
||||
dst_type * dst, \
|
||||
const src_type * top, \
|
||||
const src_type * bottom, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t x, \
|
||||
pixman_fixed_t ux, \
|
||||
int width); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op ( \
|
||||
dst_type * dst, \
|
||||
const uint32_t * mask, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \
|
||||
dst, src_top, src_bottom, wt, wb, vx, unit_x, w); \
|
||||
} \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, COVER, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NONE, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, PAD, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NORMAL, \
|
||||
FLAG_NONE)
|
||||
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, cputype, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \
|
||||
dst_type * dst, \
|
||||
const uint8_t * mask, \
|
||||
const src_type * top, \
|
||||
const src_type * bottom, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t x, \
|
||||
pixman_fixed_t ux, \
|
||||
int width); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op ( \
|
||||
dst_type * dst, \
|
||||
const uint8_t * mask, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \
|
||||
dst, mask, src_top, src_bottom, wt, wb, vx, unit_x, w); \
|
||||
} \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, COVER, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NONE, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, PAD, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NORMAL, \
|
||||
FLAG_HAVE_NON_SOLID_MASK)
|
||||
|
||||
|
||||
#endif
|
21
vendor/pixman/pixman/pixman-arm-detect-win32.asm
vendored
21
vendor/pixman/pixman/pixman-arm-detect-win32.asm
vendored
@ -1,21 +0,0 @@
|
||||
area pixman_msvc, code, readonly
|
||||
|
||||
export pixman_msvc_try_arm_simd_op
|
||||
|
||||
pixman_msvc_try_arm_simd_op
|
||||
;; I don't think the msvc arm asm knows how to do SIMD insns
|
||||
;; uqadd8 r3,r3,r3
|
||||
dcd 0xe6633f93
|
||||
mov pc,lr
|
||||
endp
|
||||
|
||||
export pixman_msvc_try_arm_neon_op
|
||||
|
||||
pixman_msvc_try_arm_neon_op
|
||||
;; I don't think the msvc arm asm knows how to do NEON insns
|
||||
;; veor d0,d0,d0
|
||||
dcd 0xf3000110
|
||||
mov pc,lr
|
||||
endp
|
||||
|
||||
end
|
1358
vendor/pixman/pixman/pixman-arm-neon-asm-bilinear.S
vendored
1358
vendor/pixman/pixman/pixman-arm-neon-asm-bilinear.S
vendored
File diff suppressed because it is too large
Load Diff
3627
vendor/pixman/pixman/pixman-arm-neon-asm.S
vendored
3627
vendor/pixman/pixman/pixman-arm-neon-asm.S
vendored
File diff suppressed because it is too large
Load Diff
1184
vendor/pixman/pixman/pixman-arm-neon-asm.h
vendored
1184
vendor/pixman/pixman/pixman-arm-neon-asm.h
vendored
File diff suppressed because it is too large
Load Diff
493
vendor/pixman/pixman/pixman-arm-neon.c
vendored
493
vendor/pixman/pixman/pixman-arm-neon.c
vendored
@ -1,493 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 ARM Ltd, Movial Creative Technologies Oy
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of ARM Ltd not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. ARM Ltd makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Ian Rickards (ian.rickards@arm.com)
|
||||
* Author: Jonathan Morton (jonathan.morton@movial.com)
|
||||
* Author: Markku Vire (markku.vire@movial.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-arm-common.h"
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_x888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0565_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_0888,
|
||||
uint8_t, 3, uint8_t, 3)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_8888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0565_8888,
|
||||
uint16_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_8888_rev,
|
||||
uint8_t, 3, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_0565_rev,
|
||||
uint8_t, 3, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_pixbuf_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_rpixbuf_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, over_8888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, over_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_n_0565,
|
||||
uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_reverse_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (0, neon, in_n_8,
|
||||
uint8_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8888_8888_ca,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8888_0565_ca,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_8888_n_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_0565_n_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, add_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8_8_8,
|
||||
uint8_t, 1, uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_0565_8_0565,
|
||||
uint16_t, 1, uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8888_8_8888,
|
||||
uint32_t, 1, uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8888_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8_8888,
|
||||
uint32_t, 1, uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8_0565,
|
||||
uint32_t, 1, uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_0565_8_0565,
|
||||
uint16_t, 1, uint8_t, 1, uint16_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_0565, OVER,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 0565_8888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_0565,
|
||||
OVER, uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, neon, 0565_8_0565,
|
||||
OVER, uint16_t, uint16_t)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 8888_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 8888_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 0565_x888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 0565_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, neon, 8888_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, neon, 8888_8888, ADD,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 8888_8_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 8888_8_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 0565_8_x888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 0565_8_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_8888, ADD,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
void
|
||||
pixman_composite_src_n_8_asm_neon (int32_t w,
|
||||
int32_t h,
|
||||
uint8_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint8_t src);
|
||||
|
||||
void
|
||||
pixman_composite_src_n_0565_asm_neon (int32_t w,
|
||||
int32_t h,
|
||||
uint16_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint16_t src);
|
||||
|
||||
void
|
||||
pixman_composite_src_n_8888_asm_neon (int32_t w,
|
||||
int32_t h,
|
||||
uint32_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint32_t src);
|
||||
|
||||
static pixman_bool_t
|
||||
arm_neon_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t _xor)
|
||||
{
|
||||
/* stride is always multiple of 32bit units in pixman */
|
||||
int32_t byte_stride = stride * sizeof(uint32_t);
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 8:
|
||||
pixman_composite_src_n_8_asm_neon (
|
||||
width,
|
||||
height,
|
||||
(uint8_t *)(((char *) bits) + y * byte_stride + x),
|
||||
byte_stride,
|
||||
_xor & 0xff);
|
||||
return TRUE;
|
||||
case 16:
|
||||
pixman_composite_src_n_0565_asm_neon (
|
||||
width,
|
||||
height,
|
||||
(uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
|
||||
byte_stride / 2,
|
||||
_xor & 0xffff);
|
||||
return TRUE;
|
||||
case 32:
|
||||
pixman_composite_src_n_8888_asm_neon (
|
||||
width,
|
||||
height,
|
||||
(uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
|
||||
byte_stride / 4,
|
||||
_xor);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
arm_neon_blt (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (src_bpp != dst_bpp)
|
||||
return FALSE;
|
||||
|
||||
switch (src_bpp)
|
||||
{
|
||||
case 16:
|
||||
pixman_composite_src_0565_0565_asm_neon (
|
||||
width, height,
|
||||
(uint16_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2,
|
||||
(uint16_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 2), src_stride * 2);
|
||||
return TRUE;
|
||||
case 32:
|
||||
pixman_composite_src_8888_8888_asm_neon (
|
||||
width, height,
|
||||
(uint32_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 4), dst_stride,
|
||||
(uint32_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 4), src_stride);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t arm_neon_fast_paths[] =
|
||||
{
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, neon_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, neon_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, neon_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, neon_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, neon_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, neon_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, neon_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, neon_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, neon_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, neon_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, neon_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, neon_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, neon_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, neon_composite_src_0888_0888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, x8r8g8b8, neon_composite_src_0888_8888_rev),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, r5g6b5, neon_composite_src_0888_0565_rev),
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8r8g8b8, neon_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8b8g8r8, neon_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8r8g8b8, neon_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8b8g8r8, neon_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8, neon_composite_src_n_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8, neon_composite_over_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, neon_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, neon_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, neon_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, neon_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, neon_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, neon_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, neon_composite_over_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, neon_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, neon_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, neon_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, neon_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, neon_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, neon_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, neon_composite_over_n_8888_0565_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, neon_composite_over_n_8888_0565_ca),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, neon_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, neon_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, r5g6b5, neon_composite_over_8888_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, b5g6r5, neon_composite_over_8888_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, r5g6b5, solid, r5g6b5, neon_composite_over_0565_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, b5g6r5, solid, b5g6r5, neon_composite_over_0565_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, neon_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, neon_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, neon_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, neon_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, r5g6b5, neon_composite_over_8888_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, b5g6r5, neon_composite_over_8888_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, r5g6b5, a8, r5g6b5, neon_composite_over_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, b5g6r5, a8, b5g6r5, neon_composite_over_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, x8r8g8b8, neon_composite_over_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_over_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, neon_composite_over_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, neon_composite_over_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, neon_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, neon_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, neon_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, neon_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, a8r8g8b8, neon_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, a8b8g8r8, neon_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, neon_composite_add_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, x8r8g8b8, neon_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8r8g8b8, neon_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, x8b8g8r8, neon_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8b8g8r8, neon_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, a8, a8, neon_composite_add_8_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, r5g6b5, a8, r5g6b5, neon_composite_add_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, b5g6r5, a8, b5g6r5, neon_composite_add_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8r8g8b8, a8, x8r8g8b8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8, x8r8g8b8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8b8g8r8, a8, x8b8g8r8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, a8, x8b8g8r8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8, a8r8g8b8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, a8, a8b8g8r8, neon_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8r8g8b8, a8r8g8b8, x8r8g8b8, neon_composite_add_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, x8r8g8b8, neon_composite_add_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_add_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8r8g8b8, solid, x8r8g8b8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, solid, x8r8g8b8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8b8g8r8, solid, x8b8g8r8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, solid, x8b8g8r8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, solid, a8r8g8b8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, solid, a8b8g8r8, neon_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, neon_composite_add_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8r8g8b8, null, x8r8g8b8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, x8r8g8b8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, x8b8g8r8, null, x8b8g8r8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, x8b8g8r8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, neon_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN, solid, null, a8, neon_composite_in_n_8),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, neon_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, neon_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, r5g6b5, neon_composite_out_reverse_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, b5g6r5, neon_composite_out_reverse_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, x8r8g8b8, neon_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, neon_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, x8b8g8r8, neon_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, neon_composite_out_reverse_8_8888),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, neon_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, neon_8888_8888),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_0565),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, b5g6r5, neon_8888_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, b5g6r5, neon_8888_0565),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, neon_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8888),
|
||||
/* Note: NONE repeat is not supported yet */
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, r5g6b5, a8r8g8b8, neon_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, b5g6r5, a8b8g8r8, neon_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, r5g6b5, a8r8g8b8, neon_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, b5g6r5, a8b8g8r8, neon_0565_8888),
|
||||
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_8_0565),
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_8_0565),
|
||||
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, r5g6b5, r5g6b5, neon_0565_8_0565),
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, b5g6r5, b5g6r5, neon_0565_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_x888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, neon_0565_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, x8r8g8b8, x8r8g8b8, neon_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_8_0565),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8_x888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, r5g6b5, neon_0565_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, x8r8g8b8, x8r8g8b8, neon_8888_8_8888),
|
||||
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
#define BIND_COMBINE_U(name) \
|
||||
void \
|
||||
pixman_composite_scanline_##name##_mask_asm_neon (int32_t w, \
|
||||
const uint32_t *dst, \
|
||||
const uint32_t *src, \
|
||||
const uint32_t *mask); \
|
||||
\
|
||||
void \
|
||||
pixman_composite_scanline_##name##_asm_neon (int32_t w, \
|
||||
const uint32_t *dst, \
|
||||
const uint32_t *src); \
|
||||
\
|
||||
static void \
|
||||
neon_combine_##name##_u (pixman_implementation_t *imp, \
|
||||
pixman_op_t op, \
|
||||
uint32_t * dest, \
|
||||
const uint32_t * src, \
|
||||
const uint32_t * mask, \
|
||||
int width) \
|
||||
{ \
|
||||
if (mask) \
|
||||
pixman_composite_scanline_##name##_mask_asm_neon (width, dest, \
|
||||
src, mask); \
|
||||
else \
|
||||
pixman_composite_scanline_##name##_asm_neon (width, dest, src); \
|
||||
}
|
||||
|
||||
BIND_COMBINE_U (over)
|
||||
BIND_COMBINE_U (add)
|
||||
BIND_COMBINE_U (out_reverse)
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_arm_neon (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp =
|
||||
_pixman_implementation_create (fallback, arm_neon_fast_paths);
|
||||
|
||||
imp->combine_32[PIXMAN_OP_OVER] = neon_combine_over_u;
|
||||
imp->combine_32[PIXMAN_OP_ADD] = neon_combine_add_u;
|
||||
imp->combine_32[PIXMAN_OP_OUT_REVERSE] = neon_combine_out_reverse_u;
|
||||
|
||||
imp->blt = arm_neon_blt;
|
||||
imp->fill = arm_neon_fill;
|
||||
|
||||
return imp;
|
||||
}
|
156
vendor/pixman/pixman/pixman-arm-simd-asm-scaled.S
vendored
156
vendor/pixman/pixman/pixman-arm-simd-asm-scaled.S
vendored
@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2008 Mozilla Corporation
|
||||
* Copyright © 2010 Nokia Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Mozilla Corporation not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Mozilla Corporation makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Jeff Muizelaar (jeff@infidigm.net)
|
||||
*
|
||||
*/
|
||||
|
||||
/* Prevent the stack from becoming executable */
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
|
||||
.text
|
||||
.arch armv6
|
||||
.object_arch armv4
|
||||
.arm
|
||||
.altmacro
|
||||
.p2align 2
|
||||
|
||||
#include "pixman-arm-asm.h"
|
||||
|
||||
/*
|
||||
* Note: This code is only using armv5te instructions (not even armv6),
|
||||
* but is scheduled for ARM Cortex-A8 pipeline. So it might need to
|
||||
* be split into a few variants, tuned for each microarchitecture.
|
||||
*
|
||||
* TODO: In order to get good performance on ARM9/ARM11 cores (which don't
|
||||
* have efficient write combining), it needs to be changed to use 16-byte
|
||||
* aligned writes using STM instruction.
|
||||
*
|
||||
* Nearest scanline scaler macro template uses the following arguments:
|
||||
* fname - name of the function to generate
|
||||
* bpp_shift - (1 << bpp_shift) is the size of pixel in bytes
|
||||
* t - type suffix for LDR/STR instructions
|
||||
* prefetch_distance - prefetch in the source image by that many
|
||||
* pixels ahead
|
||||
* prefetch_braking_distance - stop prefetching when that many pixels are
|
||||
* remaining before the end of scanline
|
||||
*/
|
||||
|
||||
.macro generate_nearest_scanline_func fname, bpp_shift, t, \
|
||||
prefetch_distance, \
|
||||
prefetch_braking_distance
|
||||
|
||||
pixman_asm_function fname
|
||||
W .req r0
|
||||
DST .req r1
|
||||
SRC .req r2
|
||||
VX .req r3
|
||||
UNIT_X .req ip
|
||||
TMP1 .req r4
|
||||
TMP2 .req r5
|
||||
VXMASK .req r6
|
||||
PF_OFFS .req r7
|
||||
SRC_WIDTH_FIXED .req r8
|
||||
|
||||
ldr UNIT_X, [sp]
|
||||
push {r4, r5, r6, r7, r8, r10}
|
||||
mvn VXMASK, #((1 << bpp_shift) - 1)
|
||||
ldr SRC_WIDTH_FIXED, [sp, #28]
|
||||
|
||||
/* define helper macro */
|
||||
.macro scale_2_pixels
|
||||
ldr&t TMP1, [SRC, TMP1]
|
||||
and TMP2, VXMASK, VX, asr #(16 - bpp_shift)
|
||||
adds VX, VX, UNIT_X
|
||||
str&t TMP1, [DST], #(1 << bpp_shift)
|
||||
9: subpls VX, VX, SRC_WIDTH_FIXED
|
||||
bpl 9b
|
||||
|
||||
ldr&t TMP2, [SRC, TMP2]
|
||||
and TMP1, VXMASK, VX, asr #(16 - bpp_shift)
|
||||
adds VX, VX, UNIT_X
|
||||
str&t TMP2, [DST], #(1 << bpp_shift)
|
||||
9: subpls VX, VX, SRC_WIDTH_FIXED
|
||||
bpl 9b
|
||||
.endm
|
||||
|
||||
/* now do the scaling */
|
||||
and TMP1, VXMASK, VX, asr #(16 - bpp_shift)
|
||||
adds VX, VX, UNIT_X
|
||||
9: subpls VX, VX, SRC_WIDTH_FIXED
|
||||
bpl 9b
|
||||
subs W, W, #(8 + prefetch_braking_distance)
|
||||
blt 2f
|
||||
/* calculate prefetch offset */
|
||||
mov PF_OFFS, #prefetch_distance
|
||||
mla PF_OFFS, UNIT_X, PF_OFFS, VX
|
||||
1: /* main loop, process 8 pixels per iteration with prefetch */
|
||||
pld [SRC, PF_OFFS, asr #(16 - bpp_shift)]
|
||||
add PF_OFFS, UNIT_X, lsl #3
|
||||
scale_2_pixels
|
||||
scale_2_pixels
|
||||
scale_2_pixels
|
||||
scale_2_pixels
|
||||
subs W, W, #8
|
||||
bge 1b
|
||||
2:
|
||||
subs W, W, #(4 - 8 - prefetch_braking_distance)
|
||||
blt 2f
|
||||
1: /* process the remaining pixels */
|
||||
scale_2_pixels
|
||||
scale_2_pixels
|
||||
subs W, W, #4
|
||||
bge 1b
|
||||
2:
|
||||
tst W, #2
|
||||
beq 2f
|
||||
scale_2_pixels
|
||||
2:
|
||||
tst W, #1
|
||||
ldrne&t TMP1, [SRC, TMP1]
|
||||
strne&t TMP1, [DST]
|
||||
/* cleanup helper macro */
|
||||
.purgem scale_2_pixels
|
||||
.unreq DST
|
||||
.unreq SRC
|
||||
.unreq W
|
||||
.unreq VX
|
||||
.unreq UNIT_X
|
||||
.unreq TMP1
|
||||
.unreq TMP2
|
||||
.unreq VXMASK
|
||||
.unreq PF_OFFS
|
||||
.unreq SRC_WIDTH_FIXED
|
||||
/* return */
|
||||
pop {r4, r5, r6, r7, r8, r10}
|
||||
bx lr
|
||||
.endfunc
|
||||
.endm
|
||||
|
||||
generate_nearest_scanline_func \
|
||||
pixman_scaled_nearest_scanline_0565_0565_SRC_asm_armv6, 1, h, 80, 32
|
||||
|
||||
generate_nearest_scanline_func \
|
||||
pixman_scaled_nearest_scanline_8888_8888_SRC_asm_armv6, 2, , 48, 32
|
1179
vendor/pixman/pixman/pixman-arm-simd-asm.S
vendored
1179
vendor/pixman/pixman/pixman-arm-simd-asm.S
vendored
File diff suppressed because it is too large
Load Diff
966
vendor/pixman/pixman/pixman-arm-simd-asm.h
vendored
966
vendor/pixman/pixman/pixman-arm-simd-asm.h
vendored
@ -1,966 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Raspberry Pi Foundation
|
||||
* Copyright © 2012 RISC OS Open Ltd
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. The copyright holders make no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Ben Avison (bavison@riscosopen.org)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Because the alignment of pixel data to cachelines, and even the number of
|
||||
* cachelines per row can vary from row to row, and because of the need to
|
||||
* preload each scanline once and only once, this prefetch strategy treats
|
||||
* each row of pixels independently. When a pixel row is long enough, there
|
||||
* are three distinct phases of prefetch:
|
||||
* * an inner loop section, where each time a cacheline of data is
|
||||
* processed, another cacheline is preloaded (the exact distance ahead is
|
||||
* determined empirically using profiling results from lowlevel-blt-bench)
|
||||
* * a leading section, where enough cachelines are preloaded to ensure no
|
||||
* cachelines escape being preloaded when the inner loop starts
|
||||
* * a trailing section, where a limited number (0 or more) of cachelines
|
||||
* are preloaded to deal with data (if any) that hangs off the end of the
|
||||
* last iteration of the inner loop, plus any trailing bytes that were not
|
||||
* enough to make up one whole iteration of the inner loop
|
||||
*
|
||||
* There are (in general) three distinct code paths, selected between
|
||||
* depending upon how long the pixel row is. If it is long enough that there
|
||||
* is at least one iteration of the inner loop (as described above) then
|
||||
* this is described as the "wide" case. If it is shorter than that, but
|
||||
* there are still enough bytes output that there is at least one 16-byte-
|
||||
* long, 16-byte-aligned write to the destination (the optimum type of
|
||||
* write), then this is the "medium" case. If it is not even this long, then
|
||||
* this is the "narrow" case, and there is no attempt to align writes to
|
||||
* 16-byte boundaries. In the "medium" and "narrow" cases, all the
|
||||
* cachelines containing data from the pixel row are prefetched up-front.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Determine whether we put the arguments on the stack for debugging.
|
||||
*/
|
||||
#undef DEBUG_PARAMS
|
||||
|
||||
/*
|
||||
* Bit flags for 'generate_composite_function' macro which are used
|
||||
* to tune generated functions behavior.
|
||||
*/
|
||||
.set FLAG_DST_WRITEONLY, 0
|
||||
.set FLAG_DST_READWRITE, 1
|
||||
.set FLAG_COND_EXEC, 0
|
||||
.set FLAG_BRANCH_OVER, 2
|
||||
.set FLAG_PROCESS_PRESERVES_PSR, 0
|
||||
.set FLAG_PROCESS_CORRUPTS_PSR, 4
|
||||
.set FLAG_PROCESS_DOESNT_STORE, 0
|
||||
.set FLAG_PROCESS_DOES_STORE, 8 /* usually because it needs to conditionally skip it */
|
||||
.set FLAG_NO_SPILL_LINE_VARS, 0
|
||||
.set FLAG_SPILL_LINE_VARS_WIDE, 16
|
||||
.set FLAG_SPILL_LINE_VARS_NON_WIDE, 32
|
||||
.set FLAG_SPILL_LINE_VARS, 48
|
||||
.set FLAG_PROCESS_CORRUPTS_SCRATCH, 0
|
||||
.set FLAG_PROCESS_PRESERVES_SCRATCH, 64
|
||||
.set FLAG_PROCESS_PRESERVES_WK0, 0
|
||||
.set FLAG_PROCESS_CORRUPTS_WK0, 128 /* if possible, use the specified register(s) instead so WK0 can hold number of leading pixels */
|
||||
.set FLAG_PRELOAD_DST, 0
|
||||
.set FLAG_NO_PRELOAD_DST, 256
|
||||
|
||||
/*
|
||||
* Number of bytes by which to adjust preload offset of destination
|
||||
* buffer (allows preload instruction to be moved before the load(s))
|
||||
*/
|
||||
.set DST_PRELOAD_BIAS, 0
|
||||
|
||||
/*
|
||||
* Offset into stack where mask and source pointer/stride can be accessed.
|
||||
*/
|
||||
#ifdef DEBUG_PARAMS
|
||||
.set ARGS_STACK_OFFSET, (9*4+9*4)
|
||||
#else
|
||||
.set ARGS_STACK_OFFSET, (9*4)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Offset into stack where space allocated during init macro can be accessed.
|
||||
*/
|
||||
.set LOCALS_STACK_OFFSET, 0
|
||||
|
||||
/*
|
||||
* Constants for selecting preferable prefetch type.
|
||||
*/
|
||||
.set PREFETCH_TYPE_NONE, 0
|
||||
.set PREFETCH_TYPE_STANDARD, 1
|
||||
|
||||
/*
|
||||
* Definitions of macros for load/store of pixel data.
|
||||
*/
|
||||
|
||||
.macro pixldst op, cond=al, numbytes, reg0, reg1, reg2, reg3, base, unaligned=0
|
||||
.if numbytes == 16
|
||||
.if unaligned == 1
|
||||
op&r&cond WK®0, [base], #4
|
||||
op&r&cond WK®1, [base], #4
|
||||
op&r&cond WK®2, [base], #4
|
||||
op&r&cond WK®3, [base], #4
|
||||
.else
|
||||
op&m&cond&ia base!, {WK®0,WK®1,WK®2,WK®3}
|
||||
.endif
|
||||
.elseif numbytes == 8
|
||||
.if unaligned == 1
|
||||
op&r&cond WK®0, [base], #4
|
||||
op&r&cond WK®1, [base], #4
|
||||
.else
|
||||
op&m&cond&ia base!, {WK®0,WK®1}
|
||||
.endif
|
||||
.elseif numbytes == 4
|
||||
op&r&cond WK®0, [base], #4
|
||||
.elseif numbytes == 2
|
||||
op&r&cond&h WK®0, [base], #2
|
||||
.elseif numbytes == 1
|
||||
op&r&cond&b WK®0, [base], #1
|
||||
.else
|
||||
.error "unsupported size: numbytes"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro pixst_baseupdated cond, numbytes, reg0, reg1, reg2, reg3, base
|
||||
.if numbytes == 16
|
||||
stm&cond&db base, {WK®0,WK®1,WK®2,WK®3}
|
||||
.elseif numbytes == 8
|
||||
stm&cond&db base, {WK®0,WK®1}
|
||||
.elseif numbytes == 4
|
||||
str&cond WK®0, [base, #-4]
|
||||
.elseif numbytes == 2
|
||||
str&cond&h WK®0, [base, #-2]
|
||||
.elseif numbytes == 1
|
||||
str&cond&b WK®0, [base, #-1]
|
||||
.else
|
||||
.error "unsupported size: numbytes"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro pixld cond, numbytes, firstreg, base, unaligned
|
||||
pixldst ld, cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base, unaligned
|
||||
.endm
|
||||
|
||||
.macro pixst cond, numbytes, firstreg, base
|
||||
.if (flags) & FLAG_DST_READWRITE
|
||||
pixst_baseupdated cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base
|
||||
.else
|
||||
pixldst st, cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro PF a, x:vararg
|
||||
.if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_STANDARD)
|
||||
a x
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro preload_leading_step1 bpp, ptr, base
|
||||
/* If the destination is already 16-byte aligned, then we need to preload
|
||||
* between 0 and prefetch_distance (inclusive) cache lines ahead so there
|
||||
* are no gaps when the inner loop starts.
|
||||
*/
|
||||
.if bpp > 0
|
||||
PF bic, ptr, base, #31
|
||||
.set OFFSET, 0
|
||||
.rept prefetch_distance+1
|
||||
PF pld, [ptr, #OFFSET]
|
||||
.set OFFSET, OFFSET+32
|
||||
.endr
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro preload_leading_step2 bpp, bpp_shift, ptr, base
|
||||
/* However, if the destination is not 16-byte aligned, we may need to
|
||||
* preload more cache lines than that. The question we need to ask is:
|
||||
* are the bytes corresponding to the leading pixels more than the amount
|
||||
* by which the source pointer will be rounded down for preloading, and if
|
||||
* so, by how many cache lines? Effectively, we want to calculate
|
||||
* leading_bytes = ((-dst)&15)*src_bpp/dst_bpp
|
||||
* inner_loop_offset = (src+leading_bytes)&31
|
||||
* extra_needed = leading_bytes - inner_loop_offset
|
||||
* and test if extra_needed is <= 0, <= 32, or > 32 (where > 32 is only
|
||||
* possible when there are 4 src bytes for every 1 dst byte).
|
||||
*/
|
||||
.if bpp > 0
|
||||
.ifc base,DST
|
||||
/* The test can be simplified further when preloading the destination */
|
||||
PF tst, base, #16
|
||||
PF beq, 61f
|
||||
.else
|
||||
.if bpp/dst_w_bpp == 4
|
||||
PF add, SCRATCH, base, WK0, lsl #bpp_shift-dst_bpp_shift
|
||||
PF and, SCRATCH, SCRATCH, #31
|
||||
PF rsb, SCRATCH, SCRATCH, WK0, lsl #bpp_shift-dst_bpp_shift
|
||||
PF sub, SCRATCH, SCRATCH, #1 /* so now ranges are -16..-1 / 0..31 / 32..63 */
|
||||
PF movs, SCRATCH, SCRATCH, lsl #32-6 /* so this sets NC / nc / Nc */
|
||||
PF bcs, 61f
|
||||
PF bpl, 60f
|
||||
PF pld, [ptr, #32*(prefetch_distance+2)]
|
||||
.else
|
||||
PF mov, SCRATCH, base, lsl #32-5
|
||||
PF add, SCRATCH, SCRATCH, WK0, lsl #32-5+bpp_shift-dst_bpp_shift
|
||||
PF rsbs, SCRATCH, SCRATCH, WK0, lsl #32-5+bpp_shift-dst_bpp_shift
|
||||
PF bls, 61f
|
||||
.endif
|
||||
.endif
|
||||
60: PF pld, [ptr, #32*(prefetch_distance+1)]
|
||||
61:
|
||||
.endif
|
||||
.endm
|
||||
|
||||
#define IS_END_OF_GROUP(INDEX,SIZE) ((SIZE) < 2 || ((INDEX) & ~((INDEX)+1)) & ((SIZE)/2))
|
||||
.macro preload_middle bpp, base, scratch_holds_offset
|
||||
.if bpp > 0
|
||||
/* prefetch distance = 256/bpp, stm distance = 128/dst_w_bpp */
|
||||
.if IS_END_OF_GROUP(SUBBLOCK,256/128*dst_w_bpp/bpp)
|
||||
.if scratch_holds_offset
|
||||
PF pld, [base, SCRATCH]
|
||||
.else
|
||||
PF bic, SCRATCH, base, #31
|
||||
PF pld, [SCRATCH, #32*prefetch_distance]
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro preload_trailing bpp, bpp_shift, base
|
||||
.if bpp > 0
|
||||
.if bpp*pix_per_block > 256
|
||||
/* Calculations are more complex if more than one fetch per block */
|
||||
PF and, WK1, base, #31
|
||||
PF add, WK1, WK1, WK0, lsl #bpp_shift
|
||||
PF add, WK1, WK1, #32*(bpp*pix_per_block/256-1)*(prefetch_distance+1)
|
||||
PF bic, SCRATCH, base, #31
|
||||
80: PF pld, [SCRATCH, #32*(prefetch_distance+1)]
|
||||
PF add, SCRATCH, SCRATCH, #32
|
||||
PF subs, WK1, WK1, #32
|
||||
PF bhi, 80b
|
||||
.else
|
||||
/* If exactly one fetch per block, then we need either 0, 1 or 2 extra preloads */
|
||||
PF mov, SCRATCH, base, lsl #32-5
|
||||
PF adds, SCRATCH, SCRATCH, X, lsl #32-5+bpp_shift
|
||||
PF adceqs, SCRATCH, SCRATCH, #0
|
||||
/* The instruction above has two effects: ensures Z is only
|
||||
* set if C was clear (so Z indicates that both shifted quantities
|
||||
* were 0), and clears C if Z was set (so C indicates that the sum
|
||||
* of the shifted quantities was greater and not equal to 32) */
|
||||
PF beq, 82f
|
||||
PF bic, SCRATCH, base, #31
|
||||
PF bcc, 81f
|
||||
PF pld, [SCRATCH, #32*(prefetch_distance+2)]
|
||||
81: PF pld, [SCRATCH, #32*(prefetch_distance+1)]
|
||||
82:
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro preload_line narrow_case, bpp, bpp_shift, base
|
||||
/* "narrow_case" - just means that the macro was invoked from the "narrow"
|
||||
* code path rather than the "medium" one - because in the narrow case,
|
||||
* the row of pixels is known to output no more than 30 bytes, then
|
||||
* (assuming the source pixels are no wider than the the destination
|
||||
* pixels) they cannot possibly straddle more than 2 32-byte cachelines,
|
||||
* meaning there's no need for a loop.
|
||||
* "bpp" - number of bits per pixel in the channel (source, mask or
|
||||
* destination) that's being preloaded, or 0 if this channel is not used
|
||||
* for reading
|
||||
* "bpp_shift" - log2 of ("bpp"/8) (except if "bpp"=0 of course)
|
||||
* "base" - base address register of channel to preload (SRC, MASK or DST)
|
||||
*/
|
||||
.if bpp > 0
|
||||
.if narrow_case && (bpp <= dst_w_bpp)
|
||||
/* In these cases, each line for each channel is in either 1 or 2 cache lines */
|
||||
PF bic, WK0, base, #31
|
||||
PF pld, [WK0]
|
||||
PF add, WK1, base, X, LSL #bpp_shift
|
||||
PF sub, WK1, WK1, #1
|
||||
PF bic, WK1, WK1, #31
|
||||
PF cmp, WK1, WK0
|
||||
PF beq, 90f
|
||||
PF pld, [WK1]
|
||||
90:
|
||||
.else
|
||||
PF bic, WK0, base, #31
|
||||
PF pld, [WK0]
|
||||
PF add, WK1, base, X, lsl #bpp_shift
|
||||
PF sub, WK1, WK1, #1
|
||||
PF bic, WK1, WK1, #31
|
||||
PF cmp, WK1, WK0
|
||||
PF beq, 92f
|
||||
91: PF add, WK0, WK0, #32
|
||||
PF cmp, WK0, WK1
|
||||
PF pld, [WK0]
|
||||
PF bne, 91b
|
||||
92:
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx
|
||||
process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, 0
|
||||
.if decrementx
|
||||
sub&cond X, X, #8*numbytes/dst_w_bpp
|
||||
.endif
|
||||
process_tail cond, numbytes, firstreg
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst cond, numbytes, firstreg, DST
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro conditional_process1 cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx
|
||||
.if (flags) & FLAG_BRANCH_OVER
|
||||
.ifc cond,mi
|
||||
bpl 100f
|
||||
.endif
|
||||
.ifc cond,cs
|
||||
bcc 100f
|
||||
.endif
|
||||
.ifc cond,ne
|
||||
beq 100f
|
||||
.endif
|
||||
conditional_process1_helper , process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx
|
||||
100:
|
||||
.else
|
||||
conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro conditional_process2 test, cond1, cond2, process_head, process_tail, numbytes1, numbytes2, firstreg1, firstreg2, unaligned_src, unaligned_mask, decrementx
|
||||
.if (flags) & (FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE)
|
||||
/* Can't interleave reads and writes */
|
||||
test
|
||||
conditional_process1 cond1, process_head, process_tail, numbytes1, firstreg1, unaligned_src, unaligned_mask, decrementx
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_PSR
|
||||
test
|
||||
.endif
|
||||
conditional_process1 cond2, process_head, process_tail, numbytes2, firstreg2, unaligned_src, unaligned_mask, decrementx
|
||||
.else
|
||||
/* Can interleave reads and writes for better scheduling */
|
||||
test
|
||||
process_head cond1, numbytes1, firstreg1, unaligned_src, unaligned_mask, 0
|
||||
process_head cond2, numbytes2, firstreg2, unaligned_src, unaligned_mask, 0
|
||||
.if decrementx
|
||||
sub&cond1 X, X, #8*numbytes1/dst_w_bpp
|
||||
sub&cond2 X, X, #8*numbytes2/dst_w_bpp
|
||||
.endif
|
||||
process_tail cond1, numbytes1, firstreg1
|
||||
process_tail cond2, numbytes2, firstreg2
|
||||
pixst cond1, numbytes1, firstreg1, DST
|
||||
pixst cond2, numbytes2, firstreg2, DST
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro test_bits_1_0_ptr
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
movs SCRATCH, X, lsl #32-1 /* C,N = bits 1,0 of DST */
|
||||
.else
|
||||
movs SCRATCH, WK0, lsl #32-1 /* C,N = bits 1,0 of DST */
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro test_bits_3_2_ptr
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
movs SCRATCH, X, lsl #32-3 /* C,N = bits 3, 2 of DST */
|
||||
.else
|
||||
movs SCRATCH, WK0, lsl #32-3 /* C,N = bits 3, 2 of DST */
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro leading_15bytes process_head, process_tail
|
||||
/* On entry, WK0 bits 0-3 = number of bytes until destination is 16-byte aligned */
|
||||
.set DECREMENT_X, 1
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
.set DECREMENT_X, 0
|
||||
sub X, X, WK0, lsr #dst_bpp_shift
|
||||
str X, [sp, #LINE_SAVED_REG_COUNT*4]
|
||||
mov X, WK0
|
||||
.endif
|
||||
/* Use unaligned loads in all cases for simplicity */
|
||||
.if dst_w_bpp == 8
|
||||
conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, DECREMENT_X
|
||||
.elseif dst_w_bpp == 16
|
||||
test_bits_1_0_ptr
|
||||
conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, DECREMENT_X
|
||||
.endif
|
||||
conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, DECREMENT_X
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
ldr X, [sp, #LINE_SAVED_REG_COUNT*4]
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro test_bits_3_2_pix
|
||||
movs SCRATCH, X, lsl #dst_bpp_shift+32-3
|
||||
.endm
|
||||
|
||||
.macro test_bits_1_0_pix
|
||||
.if dst_w_bpp == 8
|
||||
movs SCRATCH, X, lsl #dst_bpp_shift+32-1
|
||||
.else
|
||||
movs SCRATCH, X, lsr #1
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask
|
||||
conditional_process2 test_bits_3_2_pix, cs, mi, process_head, process_tail, 8, 4, 0, 2, unaligned_src, unaligned_mask, 0
|
||||
.if dst_w_bpp == 16
|
||||
test_bits_1_0_pix
|
||||
conditional_process1 cs, process_head, process_tail, 2, 0, unaligned_src, unaligned_mask, 0
|
||||
.elseif dst_w_bpp == 8
|
||||
conditional_process2 test_bits_1_0_pix, cs, mi, process_head, process_tail, 2, 1, 0, 1, unaligned_src, unaligned_mask, 0
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro wide_case_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, dst_alignment
|
||||
110:
|
||||
.set SUBBLOCK, 0 /* this is a count of STMs; there can be up to 8 STMs per block */
|
||||
.rept pix_per_block*dst_w_bpp/128
|
||||
process_head , 16, 0, unaligned_src, unaligned_mask, 1
|
||||
.if (src_bpp > 0) && (mask_bpp == 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
|
||||
preload_middle src_bpp, SRC, 1
|
||||
.elseif (src_bpp == 0) && (mask_bpp > 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
|
||||
preload_middle mask_bpp, MASK, 1
|
||||
.else
|
||||
preload_middle src_bpp, SRC, 0
|
||||
preload_middle mask_bpp, MASK, 0
|
||||
.endif
|
||||
.if (dst_r_bpp > 0) && ((SUBBLOCK % 2) == 0) && (((flags) & FLAG_NO_PRELOAD_DST) == 0)
|
||||
/* Because we know that writes are 16-byte aligned, it's relatively easy to ensure that
|
||||
* destination prefetches are 32-byte aligned. It's also the easiest channel to offset
|
||||
* preloads for, to achieve staggered prefetches for multiple channels, because there are
|
||||
* always two STMs per prefetch, so there is always an opposite STM on which to put the
|
||||
* preload. Note, no need to BIC the base register here */
|
||||
PF pld, [DST, #32*prefetch_distance - dst_alignment]
|
||||
.endif
|
||||
process_tail , 16, 0
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst , 16, 0, DST
|
||||
.endif
|
||||
.set SUBBLOCK, SUBBLOCK+1
|
||||
.endr
|
||||
subs X, X, #pix_per_block
|
||||
bhs 110b
|
||||
.endm
|
||||
|
||||
.macro wide_case_inner_loop_and_trailing_pixels process_head, process_tail, process_inner_loop, exit_label, unaligned_src, unaligned_mask
|
||||
/* Destination now 16-byte aligned; we have at least one block before we have to stop preloading */
|
||||
.if dst_r_bpp > 0
|
||||
tst DST, #16
|
||||
bne 111f
|
||||
process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 16 + DST_PRELOAD_BIAS
|
||||
b 112f
|
||||
111:
|
||||
.endif
|
||||
process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 0 + DST_PRELOAD_BIAS
|
||||
112:
|
||||
/* Just before the final (prefetch_distance+1) 32-byte blocks, deal with final preloads */
|
||||
.if (src_bpp*pix_per_block > 256) || (mask_bpp*pix_per_block > 256) || (dst_r_bpp*pix_per_block > 256)
|
||||
PF and, WK0, X, #pix_per_block-1
|
||||
.endif
|
||||
preload_trailing src_bpp, src_bpp_shift, SRC
|
||||
preload_trailing mask_bpp, mask_bpp_shift, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_trailing dst_r_bpp, dst_bpp_shift, DST
|
||||
.endif
|
||||
add X, X, #(prefetch_distance+2)*pix_per_block - 128/dst_w_bpp
|
||||
/* The remainder of the line is handled identically to the medium case */
|
||||
medium_case_inner_loop_and_trailing_pixels process_head, process_tail,, exit_label, unaligned_src, unaligned_mask
|
||||
.endm
|
||||
|
||||
.macro medium_case_inner_loop_and_trailing_pixels process_head, process_tail, unused, exit_label, unaligned_src, unaligned_mask
|
||||
120:
|
||||
process_head , 16, 0, unaligned_src, unaligned_mask, 0
|
||||
process_tail , 16, 0
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst , 16, 0, DST
|
||||
.endif
|
||||
subs X, X, #128/dst_w_bpp
|
||||
bhs 120b
|
||||
/* Trailing pixels */
|
||||
tst X, #128/dst_w_bpp - 1
|
||||
beq exit_label
|
||||
trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask
|
||||
.endm
|
||||
|
||||
.macro narrow_case_inner_loop_and_trailing_pixels process_head, process_tail, unused, exit_label, unaligned_src, unaligned_mask
|
||||
tst X, #16*8/dst_w_bpp
|
||||
conditional_process1 ne, process_head, process_tail, 16, 0, unaligned_src, unaligned_mask, 0
|
||||
/* Trailing pixels */
|
||||
/* In narrow case, it's relatively unlikely to be aligned, so let's do without a branch here */
|
||||
trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask
|
||||
.endm
|
||||
|
||||
.macro switch_on_alignment action, process_head, process_tail, process_inner_loop, exit_label
|
||||
/* Note that if we're reading the destination, it's already guaranteed to be aligned at this point */
|
||||
.if mask_bpp == 8 || mask_bpp == 16
|
||||
tst MASK, #3
|
||||
bne 141f
|
||||
.endif
|
||||
.if src_bpp == 8 || src_bpp == 16
|
||||
tst SRC, #3
|
||||
bne 140f
|
||||
.endif
|
||||
action process_head, process_tail, process_inner_loop, exit_label, 0, 0
|
||||
.if src_bpp == 8 || src_bpp == 16
|
||||
b exit_label
|
||||
140:
|
||||
action process_head, process_tail, process_inner_loop, exit_label, 1, 0
|
||||
.endif
|
||||
.if mask_bpp == 8 || mask_bpp == 16
|
||||
b exit_label
|
||||
141:
|
||||
.if src_bpp == 8 || src_bpp == 16
|
||||
tst SRC, #3
|
||||
bne 142f
|
||||
.endif
|
||||
action process_head, process_tail, process_inner_loop, exit_label, 0, 1
|
||||
.if src_bpp == 8 || src_bpp == 16
|
||||
b exit_label
|
||||
142:
|
||||
action process_head, process_tail, process_inner_loop, exit_label, 1, 1
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro end_of_line restore_x, vars_spilled, loop_label, last_one
|
||||
.if vars_spilled
|
||||
/* Sadly, GAS doesn't seem have an equivalent of the DCI directive? */
|
||||
/* This is ldmia sp,{} */
|
||||
.word 0xE89D0000 | LINE_SAVED_REGS
|
||||
.endif
|
||||
subs Y, Y, #1
|
||||
.if vars_spilled
|
||||
.if (LINE_SAVED_REGS) & (1<<1)
|
||||
str Y, [sp]
|
||||
.endif
|
||||
.endif
|
||||
add DST, DST, STRIDE_D
|
||||
.if src_bpp > 0
|
||||
add SRC, SRC, STRIDE_S
|
||||
.endif
|
||||
.if mask_bpp > 0
|
||||
add MASK, MASK, STRIDE_M
|
||||
.endif
|
||||
.if restore_x
|
||||
mov X, ORIG_W
|
||||
.endif
|
||||
bhs loop_label
|
||||
.ifc "last_one",""
|
||||
.if vars_spilled
|
||||
b 197f
|
||||
.else
|
||||
b 198f
|
||||
.endif
|
||||
.else
|
||||
.if (!vars_spilled) && ((flags) & FLAG_SPILL_LINE_VARS)
|
||||
b 198f
|
||||
.endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
.macro generate_composite_function fname, \
|
||||
src_bpp_, \
|
||||
mask_bpp_, \
|
||||
dst_w_bpp_, \
|
||||
flags_, \
|
||||
prefetch_distance_, \
|
||||
init, \
|
||||
newline, \
|
||||
cleanup, \
|
||||
process_head, \
|
||||
process_tail, \
|
||||
process_inner_loop
|
||||
|
||||
pixman_asm_function fname
|
||||
|
||||
/*
|
||||
* Make some macro arguments globally visible and accessible
|
||||
* from other macros
|
||||
*/
|
||||
.set src_bpp, src_bpp_
|
||||
.set mask_bpp, mask_bpp_
|
||||
.set dst_w_bpp, dst_w_bpp_
|
||||
.set flags, flags_
|
||||
.set prefetch_distance, prefetch_distance_
|
||||
|
||||
/*
|
||||
* Select prefetch type for this function.
|
||||
*/
|
||||
.if prefetch_distance == 0
|
||||
.set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE
|
||||
.else
|
||||
.set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_STANDARD
|
||||
.endif
|
||||
|
||||
.if src_bpp == 32
|
||||
.set src_bpp_shift, 2
|
||||
.elseif src_bpp == 24
|
||||
.set src_bpp_shift, 0
|
||||
.elseif src_bpp == 16
|
||||
.set src_bpp_shift, 1
|
||||
.elseif src_bpp == 8
|
||||
.set src_bpp_shift, 0
|
||||
.elseif src_bpp == 0
|
||||
.set src_bpp_shift, -1
|
||||
.else
|
||||
.error "requested src bpp (src_bpp) is not supported"
|
||||
.endif
|
||||
|
||||
.if mask_bpp == 32
|
||||
.set mask_bpp_shift, 2
|
||||
.elseif mask_bpp == 24
|
||||
.set mask_bpp_shift, 0
|
||||
.elseif mask_bpp == 8
|
||||
.set mask_bpp_shift, 0
|
||||
.elseif mask_bpp == 0
|
||||
.set mask_bpp_shift, -1
|
||||
.else
|
||||
.error "requested mask bpp (mask_bpp) is not supported"
|
||||
.endif
|
||||
|
||||
.if dst_w_bpp == 32
|
||||
.set dst_bpp_shift, 2
|
||||
.elseif dst_w_bpp == 24
|
||||
.set dst_bpp_shift, 0
|
||||
.elseif dst_w_bpp == 16
|
||||
.set dst_bpp_shift, 1
|
||||
.elseif dst_w_bpp == 8
|
||||
.set dst_bpp_shift, 0
|
||||
.else
|
||||
.error "requested dst bpp (dst_w_bpp) is not supported"
|
||||
.endif
|
||||
|
||||
.if (((flags) & FLAG_DST_READWRITE) != 0)
|
||||
.set dst_r_bpp, dst_w_bpp
|
||||
.else
|
||||
.set dst_r_bpp, 0
|
||||
.endif
|
||||
|
||||
.set pix_per_block, 16*8/dst_w_bpp
|
||||
.if src_bpp != 0
|
||||
.if 32*8/src_bpp > pix_per_block
|
||||
.set pix_per_block, 32*8/src_bpp
|
||||
.endif
|
||||
.endif
|
||||
.if mask_bpp != 0
|
||||
.if 32*8/mask_bpp > pix_per_block
|
||||
.set pix_per_block, 32*8/mask_bpp
|
||||
.endif
|
||||
.endif
|
||||
.if dst_r_bpp != 0
|
||||
.if 32*8/dst_r_bpp > pix_per_block
|
||||
.set pix_per_block, 32*8/dst_r_bpp
|
||||
.endif
|
||||
.endif
|
||||
|
||||
/* The standard entry conditions set up by pixman-arm-common.h are:
|
||||
* r0 = width (pixels)
|
||||
* r1 = height (rows)
|
||||
* r2 = pointer to top-left pixel of destination
|
||||
* r3 = destination stride (pixels)
|
||||
* [sp] = source pixel value, or pointer to top-left pixel of source
|
||||
* [sp,#4] = 0 or source stride (pixels)
|
||||
* The following arguments are unused for non-mask operations
|
||||
* [sp,#8] = mask pixel value, or pointer to top-left pixel of mask
|
||||
* [sp,#12] = 0 or mask stride (pixels)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Assign symbolic names to registers
|
||||
*/
|
||||
X .req r0 /* pixels to go on this line */
|
||||
Y .req r1 /* lines to go */
|
||||
DST .req r2 /* destination pixel pointer */
|
||||
STRIDE_D .req r3 /* destination stride (bytes, minus width) */
|
||||
SRC .req r4 /* source pixel pointer */
|
||||
STRIDE_S .req r5 /* source stride (bytes, minus width) */
|
||||
MASK .req r6 /* mask pixel pointer (if applicable) */
|
||||
STRIDE_M .req r7 /* mask stride (bytes, minus width) */
|
||||
WK0 .req r8 /* pixel data registers */
|
||||
WK1 .req r9
|
||||
WK2 .req r10
|
||||
WK3 .req r11
|
||||
SCRATCH .req r12
|
||||
ORIG_W .req r14 /* width (pixels) */
|
||||
|
||||
push {r4-r11, lr} /* save all registers */
|
||||
|
||||
subs Y, Y, #1
|
||||
blo 199f
|
||||
|
||||
#ifdef DEBUG_PARAMS
|
||||
sub sp, sp, #9*4
|
||||
#endif
|
||||
|
||||
.if src_bpp > 0
|
||||
ldr SRC, [sp, #ARGS_STACK_OFFSET]
|
||||
ldr STRIDE_S, [sp, #ARGS_STACK_OFFSET+4]
|
||||
.endif
|
||||
.if mask_bpp > 0
|
||||
ldr MASK, [sp, #ARGS_STACK_OFFSET+8]
|
||||
ldr STRIDE_M, [sp, #ARGS_STACK_OFFSET+12]
|
||||
.endif
|
||||
|
||||
#ifdef DEBUG_PARAMS
|
||||
add Y, Y, #1
|
||||
stmia sp, {r0-r7,pc}
|
||||
sub Y, Y, #1
|
||||
#endif
|
||||
|
||||
init
|
||||
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
/* Reserve a word in which to store X during leading pixels */
|
||||
sub sp, sp, #4
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET+4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET+4
|
||||
.endif
|
||||
|
||||
lsl STRIDE_D, #dst_bpp_shift /* stride in bytes */
|
||||
sub STRIDE_D, STRIDE_D, X, lsl #dst_bpp_shift
|
||||
.if src_bpp > 0
|
||||
lsl STRIDE_S, #src_bpp_shift
|
||||
sub STRIDE_S, STRIDE_S, X, lsl #src_bpp_shift
|
||||
.endif
|
||||
.if mask_bpp > 0
|
||||
lsl STRIDE_M, #mask_bpp_shift
|
||||
sub STRIDE_M, STRIDE_M, X, lsl #mask_bpp_shift
|
||||
.endif
|
||||
|
||||
/* Are we not even wide enough to have one 16-byte aligned 16-byte block write? */
|
||||
cmp X, #2*16*8/dst_w_bpp - 1
|
||||
blo 170f
|
||||
.if src_bpp || mask_bpp || dst_r_bpp /* Wide and medium cases are the same for fill */
|
||||
/* To preload ahead on the current line, we need at least (prefetch_distance+2) 32-byte blocks on all prefetch channels */
|
||||
cmp X, #(prefetch_distance+3)*pix_per_block - 1
|
||||
blo 160f
|
||||
|
||||
/* Wide case */
|
||||
/* Adjust X so that the decrement instruction can also test for
|
||||
* inner loop termination. We want it to stop when there are
|
||||
* (prefetch_distance+1) complete blocks to go. */
|
||||
sub X, X, #(prefetch_distance+2)*pix_per_block
|
||||
mov ORIG_W, X
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_WIDE
|
||||
/* This is stmdb sp!,{} */
|
||||
.word 0xE92D0000 | LINE_SAVED_REGS
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
151: /* New line */
|
||||
newline
|
||||
preload_leading_step1 src_bpp, WK1, SRC
|
||||
preload_leading_step1 mask_bpp, WK2, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_leading_step1 dst_r_bpp, WK3, DST
|
||||
.endif
|
||||
|
||||
ands WK0, DST, #15
|
||||
beq 154f
|
||||
rsb WK0, WK0, #16 /* number of leading bytes until destination aligned */
|
||||
|
||||
preload_leading_step2 src_bpp, src_bpp_shift, WK1, SRC
|
||||
preload_leading_step2 mask_bpp, mask_bpp_shift, WK2, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_leading_step2 dst_r_bpp, dst_bpp_shift, WK3, DST
|
||||
.endif
|
||||
|
||||
leading_15bytes process_head, process_tail
|
||||
|
||||
154: /* Destination now 16-byte aligned; we have at least one prefetch on each channel as well as at least one 16-byte output block */
|
||||
.if (src_bpp > 0) && (mask_bpp == 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
|
||||
and SCRATCH, SRC, #31
|
||||
rsb SCRATCH, SCRATCH, #32*prefetch_distance
|
||||
.elseif (src_bpp == 0) && (mask_bpp > 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH)
|
||||
and SCRATCH, MASK, #31
|
||||
rsb SCRATCH, SCRATCH, #32*prefetch_distance
|
||||
.endif
|
||||
.ifc "process_inner_loop",""
|
||||
switch_on_alignment wide_case_inner_loop_and_trailing_pixels, process_head, process_tail, wide_case_inner_loop, 157f
|
||||
.else
|
||||
switch_on_alignment wide_case_inner_loop_and_trailing_pixels, process_head, process_tail, process_inner_loop, 157f
|
||||
.endif
|
||||
|
||||
157: /* Check for another line */
|
||||
end_of_line 1, %((flags) & FLAG_SPILL_LINE_VARS_WIDE), 151b
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_WIDE
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.ltorg
|
||||
|
||||
160: /* Medium case */
|
||||
mov ORIG_W, X
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE
|
||||
/* This is stmdb sp!,{} */
|
||||
.word 0xE92D0000 | LINE_SAVED_REGS
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
161: /* New line */
|
||||
newline
|
||||
preload_line 0, src_bpp, src_bpp_shift, SRC /* in: X, corrupts: WK0-WK1 */
|
||||
preload_line 0, mask_bpp, mask_bpp_shift, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_line 0, dst_r_bpp, dst_bpp_shift, DST
|
||||
.endif
|
||||
|
||||
sub X, X, #128/dst_w_bpp /* simplifies inner loop termination */
|
||||
ands WK0, DST, #15
|
||||
beq 164f
|
||||
rsb WK0, WK0, #16 /* number of leading bytes until destination aligned */
|
||||
|
||||
leading_15bytes process_head, process_tail
|
||||
|
||||
164: /* Destination now 16-byte aligned; we have at least one 16-byte output block */
|
||||
switch_on_alignment medium_case_inner_loop_and_trailing_pixels, process_head, process_tail,, 167f
|
||||
|
||||
167: /* Check for another line */
|
||||
end_of_line 1, %((flags) & FLAG_SPILL_LINE_VARS_NON_WIDE), 161b
|
||||
|
||||
.ltorg
|
||||
|
||||
170: /* Narrow case, less than 31 bytes, so no guarantee of at least one 16-byte block */
|
||||
.if dst_w_bpp < 32
|
||||
mov ORIG_W, X
|
||||
.endif
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE
|
||||
/* This is stmdb sp!,{} */
|
||||
.word 0xE92D0000 | LINE_SAVED_REGS
|
||||
.endif
|
||||
171: /* New line */
|
||||
newline
|
||||
preload_line 1, src_bpp, src_bpp_shift, SRC /* in: X, corrupts: WK0-WK1 */
|
||||
preload_line 1, mask_bpp, mask_bpp_shift, MASK
|
||||
.if ((flags) & FLAG_NO_PRELOAD_DST) == 0
|
||||
preload_line 1, dst_r_bpp, dst_bpp_shift, DST
|
||||
.endif
|
||||
|
||||
.if dst_w_bpp == 8
|
||||
tst DST, #3
|
||||
beq 174f
|
||||
172: subs X, X, #1
|
||||
blo 177f
|
||||
process_head , 1, 0, 1, 1, 0
|
||||
process_tail , 1, 0
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst , 1, 0, DST
|
||||
.endif
|
||||
tst DST, #3
|
||||
bne 172b
|
||||
.elseif dst_w_bpp == 16
|
||||
tst DST, #2
|
||||
beq 174f
|
||||
subs X, X, #1
|
||||
blo 177f
|
||||
process_head , 2, 0, 1, 1, 0
|
||||
process_tail , 2, 0
|
||||
.if !((flags) & FLAG_PROCESS_DOES_STORE)
|
||||
pixst , 2, 0, DST
|
||||
.endif
|
||||
.endif
|
||||
|
||||
174: /* Destination now 4-byte aligned; we have 0 or more output bytes to go */
|
||||
switch_on_alignment narrow_case_inner_loop_and_trailing_pixels, process_head, process_tail,, 177f
|
||||
|
||||
177: /* Check for another line */
|
||||
end_of_line %(dst_w_bpp < 32), %((flags) & FLAG_SPILL_LINE_VARS_NON_WIDE), 171b, last_one
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
|
||||
197:
|
||||
.if (flags) & FLAG_SPILL_LINE_VARS
|
||||
add sp, sp, #LINE_SAVED_REG_COUNT*4
|
||||
.endif
|
||||
198:
|
||||
.if (flags) & FLAG_PROCESS_CORRUPTS_WK0
|
||||
.set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET-4
|
||||
.set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET-4
|
||||
add sp, sp, #4
|
||||
.endif
|
||||
|
||||
cleanup
|
||||
|
||||
#ifdef DEBUG_PARAMS
|
||||
add sp, sp, #9*4 /* junk the debug copy of arguments */
|
||||
#endif
|
||||
199:
|
||||
pop {r4-r11, pc} /* exit */
|
||||
|
||||
.ltorg
|
||||
|
||||
.unreq X
|
||||
.unreq Y
|
||||
.unreq DST
|
||||
.unreq STRIDE_D
|
||||
.unreq SRC
|
||||
.unreq STRIDE_S
|
||||
.unreq MASK
|
||||
.unreq STRIDE_M
|
||||
.unreq WK0
|
||||
.unreq WK1
|
||||
.unreq WK2
|
||||
.unreq WK3
|
||||
.unreq SCRATCH
|
||||
.unreq ORIG_W
|
||||
.endfunc
|
||||
.endm
|
||||
|
||||
.macro line_saved_regs x:vararg
|
||||
.set LINE_SAVED_REGS, 0
|
||||
.set LINE_SAVED_REG_COUNT, 0
|
||||
.irp SAVED_REG,x
|
||||
.ifc "SAVED_REG","Y"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<1)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.ifc "SAVED_REG","STRIDE_D"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<3)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.ifc "SAVED_REG","STRIDE_S"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<5)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.ifc "SAVED_REG","STRIDE_M"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<7)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.ifc "SAVED_REG","ORIG_W"
|
||||
.set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<14)
|
||||
.set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1
|
||||
.endif
|
||||
.endr
|
||||
.endm
|
||||
|
||||
.macro nop_macro x:vararg
|
||||
.endm
|
291
vendor/pixman/pixman/pixman-arm-simd.c
vendored
291
vendor/pixman/pixman/pixman-arm-simd.c
vendored
@ -1,291 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2008 Mozilla Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Mozilla Corporation not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Mozilla Corporation makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Author: Jeff Muizelaar (jeff@infidigm.net)
|
||||
*
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-arm-common.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_8888,
|
||||
uint16_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, add_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, over_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, in_reverse_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, armv6, over_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (0, armv6, over_reverse_n_8888,
|
||||
uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, armv6, over_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8888_8888_ca,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 0565_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 8888_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
void
|
||||
pixman_composite_src_n_8888_asm_armv6 (int32_t w,
|
||||
int32_t h,
|
||||
uint32_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint32_t src);
|
||||
|
||||
void
|
||||
pixman_composite_src_n_0565_asm_armv6 (int32_t w,
|
||||
int32_t h,
|
||||
uint16_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint16_t src);
|
||||
|
||||
void
|
||||
pixman_composite_src_n_8_asm_armv6 (int32_t w,
|
||||
int32_t h,
|
||||
uint8_t *dst,
|
||||
int32_t dst_stride,
|
||||
uint8_t src);
|
||||
|
||||
static pixman_bool_t
|
||||
arm_simd_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride, /* in 32-bit words */
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t _xor)
|
||||
{
|
||||
/* stride is always multiple of 32bit units in pixman */
|
||||
uint32_t byte_stride = stride * sizeof(uint32_t);
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 8:
|
||||
pixman_composite_src_n_8_asm_armv6 (
|
||||
width,
|
||||
height,
|
||||
(uint8_t *)(((char *) bits) + y * byte_stride + x),
|
||||
byte_stride,
|
||||
_xor & 0xff);
|
||||
return TRUE;
|
||||
case 16:
|
||||
pixman_composite_src_n_0565_asm_armv6 (
|
||||
width,
|
||||
height,
|
||||
(uint16_t *)(((char *) bits) + y * byte_stride + x * 2),
|
||||
byte_stride / 2,
|
||||
_xor & 0xffff);
|
||||
return TRUE;
|
||||
case 32:
|
||||
pixman_composite_src_n_8888_asm_armv6 (
|
||||
width,
|
||||
height,
|
||||
(uint32_t *)(((char *) bits) + y * byte_stride + x * 4),
|
||||
byte_stride / 4,
|
||||
_xor);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
arm_simd_blt (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride, /* in 32-bit words */
|
||||
int dst_stride, /* in 32-bit words */
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (src_bpp != dst_bpp)
|
||||
return FALSE;
|
||||
|
||||
switch (src_bpp)
|
||||
{
|
||||
case 8:
|
||||
pixman_composite_src_8_8_asm_armv6 (
|
||||
width, height,
|
||||
(uint8_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 1), dst_stride * 4,
|
||||
(uint8_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 1), src_stride * 4);
|
||||
return TRUE;
|
||||
case 16:
|
||||
pixman_composite_src_0565_0565_asm_armv6 (
|
||||
width, height,
|
||||
(uint16_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2,
|
||||
(uint16_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 2), src_stride * 2);
|
||||
return TRUE;
|
||||
case 32:
|
||||
pixman_composite_src_8888_8888_asm_armv6 (
|
||||
width, height,
|
||||
(uint32_t *)(((char *) dst_bits) +
|
||||
dest_y * dst_stride * 4 + dest_x * 4), dst_stride,
|
||||
(uint32_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 4), src_stride);
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t arm_simd_fast_paths[] =
|
||||
{
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, armv6_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, armv6_composite_src_x888_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, a1r5g5b5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, a1b5g5r5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, a4r4g4b4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, a4b4g4r4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r3g3b2, null, r3g3b2, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b2g3r3, null, b2g3r3, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a2r2g2b2, null, a2r2g2b2, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a2b2g2r2, null, a2b2g2r2, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, c8, null, c8, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, g8, null, g8, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4a4, null, x4a4, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4c4, null, x4c4, armv6_composite_src_8_8),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x4g4, null, x4g4, armv6_composite_src_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, armv6_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, armv6_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, armv6_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, armv6_composite_src_0565_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, armv6_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, armv6_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, armv6_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, armv6_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, armv6_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, armv6_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, armv6_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, armv6_composite_over_8888_n_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, armv6_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, armv6_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, a8b8g8r8, armv6_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, x8b8g8r8, armv6_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, armv6_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, armv6_composite_over_reverse_n_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, armv6_composite_add_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, armv6_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, armv6_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, armv6_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, armv6_composite_over_n_8_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, a8r8g8b8, armv6_composite_in_reverse_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, x8r8g8b8, armv6_composite_in_reverse_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, a8b8g8r8, armv6_composite_in_reverse_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, x8b8g8r8, armv6_composite_in_reverse_8888_8888),
|
||||
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, armv6_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, armv6_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, armv6_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, armv6_composite_over_n_8888_8888_ca),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565),
|
||||
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, armv6_8888_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, armv6_8888_8888),
|
||||
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_arm_simd (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp = _pixman_implementation_create (fallback, arm_simd_fast_paths);
|
||||
|
||||
imp->blt = arm_simd_blt;
|
||||
imp->fill = arm_simd_fill;
|
||||
|
||||
return imp;
|
||||
}
|
256
vendor/pixman/pixman/pixman-arm.c
vendored
256
vendor/pixman/pixman/pixman-arm.c
vendored
@ -1,256 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ARM_V7 = (1 << 0),
|
||||
ARM_V6 = (1 << 1),
|
||||
ARM_VFP = (1 << 2),
|
||||
ARM_NEON = (1 << 3),
|
||||
ARM_IWMMXT = (1 << 4)
|
||||
} arm_cpu_features_t;
|
||||
|
||||
#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
|
||||
#include <windows.h>
|
||||
|
||||
extern int pixman_msvc_try_arm_neon_op ();
|
||||
extern int pixman_msvc_try_arm_simd_op ();
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
pixman_msvc_try_arm_simd_op ();
|
||||
features |= ARM_V6;
|
||||
}
|
||||
__except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
{
|
||||
}
|
||||
|
||||
__try
|
||||
{
|
||||
pixman_msvc_try_arm_neon_op ();
|
||||
features |= ARM_NEON;
|
||||
}
|
||||
__except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
{
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__) && defined(TARGET_OS_IPHONE) /* iOS */
|
||||
|
||||
#include "TargetConditionals.h"
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
|
||||
features |= ARM_V6;
|
||||
|
||||
/* Detection of ARM NEON on iOS is fairly simple because iOS binaries
|
||||
* contain separate executable images for each processor architecture.
|
||||
* So all we have to do is detect the armv7 architecture build. The
|
||||
* operating system automatically runs the armv7 binary for armv7 devices
|
||||
* and the armv6 binary for armv6 devices.
|
||||
*/
|
||||
#if defined(__ARM_NEON__)
|
||||
features |= ARM_NEON;
|
||||
#endif
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined(__ANDROID__) || defined(ANDROID) /* Android */
|
||||
|
||||
#include <cpu-features.h>
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
AndroidCpuFamily cpu_family;
|
||||
uint64_t cpu_features;
|
||||
|
||||
cpu_family = android_getCpuFamily();
|
||||
cpu_features = android_getCpuFeatures();
|
||||
|
||||
if (cpu_family == ANDROID_CPU_FAMILY_ARM)
|
||||
{
|
||||
if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7)
|
||||
features |= ARM_V7;
|
||||
|
||||
if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3)
|
||||
features |= ARM_VFP;
|
||||
|
||||
if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)
|
||||
features |= ARM_NEON;
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined (__linux__) /* linux ELF */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
Elf32_auxv_t aux;
|
||||
int fd;
|
||||
|
||||
fd = open ("/proc/self/auxv", O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t))
|
||||
{
|
||||
if (aux.a_type == AT_HWCAP)
|
||||
{
|
||||
uint32_t hwcap = aux.a_un.a_val;
|
||||
|
||||
/* hardcode these values to avoid depending on specific
|
||||
* versions of the hwcap header, e.g. HWCAP_NEON
|
||||
*/
|
||||
if ((hwcap & 64) != 0)
|
||||
features |= ARM_VFP;
|
||||
if ((hwcap & 512) != 0)
|
||||
features |= ARM_IWMMXT;
|
||||
/* this flag is only present on kernel 2.6.29 */
|
||||
if ((hwcap & 4096) != 0)
|
||||
features |= ARM_NEON;
|
||||
}
|
||||
else if (aux.a_type == AT_PLATFORM)
|
||||
{
|
||||
const char *plat = (const char*) aux.a_un.a_val;
|
||||
|
||||
if (strncmp (plat, "v7l", 3) == 0)
|
||||
features |= (ARM_V7 | ARM_V6);
|
||||
else if (strncmp (plat, "v6l", 3) == 0)
|
||||
features |= ARM_V6;
|
||||
}
|
||||
}
|
||||
close (fd);
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined (_3DS) /* 3DS homebrew (devkitARM) */
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
|
||||
features |= ARM_V6;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#elif defined (PSP2) || defined (__SWITCH__)
|
||||
/* Vita (VitaSDK) or Switch (devkitA64) homebrew */
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
arm_cpu_features_t features = 0;
|
||||
|
||||
features |= ARM_NEON;
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
#else /* Unknown */
|
||||
|
||||
static arm_cpu_features_t
|
||||
detect_cpu_features (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* Linux elf */
|
||||
|
||||
static pixman_bool_t
|
||||
have_feature (arm_cpu_features_t feature)
|
||||
{
|
||||
static pixman_bool_t initialized;
|
||||
static arm_cpu_features_t features;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
features = detect_cpu_features();
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
||||
return (features & feature) == feature;
|
||||
}
|
||||
|
||||
#endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_arm_get_implementations (pixman_implementation_t *imp)
|
||||
{
|
||||
#ifdef USE_ARM_SIMD
|
||||
if (!_pixman_disabled ("arm-simd") && have_feature (ARM_V6))
|
||||
imp = _pixman_implementation_create_arm_simd (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_IWMMXT
|
||||
if (!_pixman_disabled ("arm-iwmmxt") && have_feature (ARM_IWMMXT))
|
||||
imp = _pixman_implementation_create_mmx (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_NEON
|
||||
if (!_pixman_disabled ("arm-neon") && have_feature (ARM_NEON))
|
||||
imp = _pixman_implementation_create_arm_neon (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_A64_NEON
|
||||
/* neon is a part of aarch64 */
|
||||
if (!_pixman_disabled ("arm-neon"))
|
||||
imp = _pixman_implementation_create_arm_neon (imp);
|
||||
#endif
|
||||
|
||||
return imp;
|
||||
}
|
1275
vendor/pixman/pixman/pixman-arma64-neon-asm-bilinear.S
vendored
1275
vendor/pixman/pixman/pixman-arma64-neon-asm-bilinear.S
vendored
File diff suppressed because it is too large
Load Diff
3704
vendor/pixman/pixman/pixman-arma64-neon-asm.S
vendored
3704
vendor/pixman/pixman/pixman-arma64-neon-asm.S
vendored
File diff suppressed because it is too large
Load Diff
1310
vendor/pixman/pixman/pixman-arma64-neon-asm.h
vendored
1310
vendor/pixman/pixman/pixman-arma64-neon-asm.h
vendored
File diff suppressed because it is too large
Load Diff
1383
vendor/pixman/pixman/pixman-bits-image.c
vendored
1383
vendor/pixman/pixman/pixman-bits-image.c
vendored
File diff suppressed because it is too large
Load Diff
1158
vendor/pixman/pixman/pixman-combine-float.c
vendored
1158
vendor/pixman/pixman/pixman-combine-float.c
vendored
File diff suppressed because it is too large
Load Diff
1189
vendor/pixman/pixman/pixman-combine32.c
vendored
1189
vendor/pixman/pixman/pixman-combine32.c
vendored
File diff suppressed because it is too large
Load Diff
272
vendor/pixman/pixman/pixman-combine32.h
vendored
272
vendor/pixman/pixman/pixman-combine32.h
vendored
@ -1,272 +0,0 @@
|
||||
#define COMPONENT_SIZE 8
|
||||
#define MASK 0xff
|
||||
#define ONE_HALF 0x80
|
||||
|
||||
#define A_SHIFT 8 * 3
|
||||
#define R_SHIFT 8 * 2
|
||||
#define G_SHIFT 8
|
||||
#define A_MASK 0xff000000
|
||||
#define R_MASK 0xff0000
|
||||
#define G_MASK 0xff00
|
||||
|
||||
#define RB_MASK 0xff00ff
|
||||
#define AG_MASK 0xff00ff00
|
||||
#define RB_ONE_HALF 0x800080
|
||||
#define RB_MASK_PLUS_ONE 0x1000100
|
||||
|
||||
#define ALPHA_8(x) ((x) >> A_SHIFT)
|
||||
#define RED_8(x) (((x) >> R_SHIFT) & MASK)
|
||||
#define GREEN_8(x) (((x) >> G_SHIFT) & MASK)
|
||||
#define BLUE_8(x) ((x) & MASK)
|
||||
|
||||
/*
|
||||
* ARMv6 has UQADD8 instruction, which implements unsigned saturated
|
||||
* addition for 8-bit values packed in 32-bit registers. It is very useful
|
||||
* for UN8x4_ADD_UN8x4, UN8_rb_ADD_UN8_rb and ADD_UN8 macros (which would
|
||||
* otherwise need a lot of arithmetic operations to simulate this operation).
|
||||
* Since most of the major ARM linux distros are built for ARMv7, we are
|
||||
* much less dependent on runtime CPU detection and can get practical
|
||||
* benefits from conditional compilation here for a lot of users.
|
||||
*/
|
||||
|
||||
#if defined(USE_GCC_INLINE_ASM) && defined(__arm__) && \
|
||||
!defined(__aarch64__) && (!defined(__thumb__) || defined(__thumb2__))
|
||||
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
|
||||
defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \
|
||||
defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) || \
|
||||
defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_7__) || \
|
||||
defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \
|
||||
defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
static force_inline uint32_t
|
||||
un8x4_add_un8x4 (uint32_t x, uint32_t y)
|
||||
{
|
||||
uint32_t t;
|
||||
asm ("uqadd8 %0, %1, %2" : "=r" (t) : "%r" (x), "r" (y));
|
||||
return t;
|
||||
}
|
||||
|
||||
#define UN8x4_ADD_UN8x4(x, y) \
|
||||
((x) = un8x4_add_un8x4 ((x), (y)))
|
||||
|
||||
#define UN8_rb_ADD_UN8_rb(x, y, t) \
|
||||
((t) = un8x4_add_un8x4 ((x), (y)), (x) = (t))
|
||||
|
||||
#define ADD_UN8(x, y, t) \
|
||||
((t) = (x), un8x4_add_un8x4 ((t), (y)))
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Helper macros.
|
||||
*/
|
||||
|
||||
#define MUL_UN8(a, b, t) \
|
||||
((t) = (a) * (uint16_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
|
||||
|
||||
#define DIV_UN8(a, b) \
|
||||
(((uint16_t) (a) * MASK + ((b) / 2)) / (b))
|
||||
|
||||
#ifndef ADD_UN8
|
||||
#define ADD_UN8(x, y, t) \
|
||||
((t) = (x) + (y), \
|
||||
(uint32_t) (uint8_t) ((t) | (0 - ((t) >> G_SHIFT))))
|
||||
#endif
|
||||
|
||||
#define DIV_ONE_UN8(x) \
|
||||
(((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT)
|
||||
|
||||
/*
|
||||
* The methods below use some tricks to be able to do two color
|
||||
* components at the same time.
|
||||
*/
|
||||
|
||||
/*
|
||||
* x_rb = (x_rb * a) / 255
|
||||
*/
|
||||
#define UN8_rb_MUL_UN8(x, a, t) \
|
||||
do \
|
||||
{ \
|
||||
t = ((x) & RB_MASK) * (a); \
|
||||
t += RB_ONE_HALF; \
|
||||
x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
|
||||
x &= RB_MASK; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_rb = min (x_rb + y_rb, 255)
|
||||
*/
|
||||
#ifndef UN8_rb_ADD_UN8_rb
|
||||
#define UN8_rb_ADD_UN8_rb(x, y, t) \
|
||||
do \
|
||||
{ \
|
||||
t = ((x) + (y)); \
|
||||
t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \
|
||||
x = (t & RB_MASK); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* x_rb = (x_rb * a_rb) / 255
|
||||
*/
|
||||
#define UN8_rb_MUL_UN8_rb(x, a, t) \
|
||||
do \
|
||||
{ \
|
||||
t = (x & MASK) * (a & MASK); \
|
||||
t |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \
|
||||
t += RB_ONE_HALF; \
|
||||
t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \
|
||||
x = t & RB_MASK; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8(x, a) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a) / 255 + y_c
|
||||
*/
|
||||
#define UN8x4_MUL_UN8_ADD_UN8x4(x, a, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a + y_c * b) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8(x, a, y, b) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (y); \
|
||||
UN8_rb_MUL_UN8 (r1__, (a), t__); \
|
||||
UN8_rb_MUL_UN8 (r2__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT); \
|
||||
r3__ = ((y) >> G_SHIFT); \
|
||||
UN8_rb_MUL_UN8 (r2__, (a), t__); \
|
||||
UN8_rb_MUL_UN8 (r3__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4(x, a) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = (a) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c) / 255 + y_c
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4_ADD_UN8x4(x, a, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT); \
|
||||
r3__ = ((a) >> G_SHIFT); \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
(x) = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* x_c = (x_c * a_c + y_c * b) / 255
|
||||
*/
|
||||
#define UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8(x, a, y, b) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x); \
|
||||
r2__ = (a); \
|
||||
UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \
|
||||
r2__ = (y); \
|
||||
UN8_rb_MUL_UN8 (r2__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = (x) >> G_SHIFT; \
|
||||
r3__ = (a) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \
|
||||
r3__ = (y) >> G_SHIFT; \
|
||||
UN8_rb_MUL_UN8 (r3__, (b), t__); \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
x = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
x_c = min(x_c + y_c, 255)
|
||||
*/
|
||||
#ifndef UN8x4_ADD_UN8x4
|
||||
#define UN8x4_ADD_UN8x4(x, y) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t r1__, r2__, r3__, t__; \
|
||||
\
|
||||
r1__ = (x) & RB_MASK; \
|
||||
r2__ = (y) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \
|
||||
\
|
||||
r2__ = ((x) >> G_SHIFT) & RB_MASK; \
|
||||
r3__ = ((y) >> G_SHIFT) & RB_MASK; \
|
||||
UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \
|
||||
\
|
||||
x = r1__ | (r2__ << G_SHIFT); \
|
||||
} while (0)
|
||||
#endif
|
234
vendor/pixman/pixman/pixman-compiler.h
vendored
234
vendor/pixman/pixman/pixman-compiler.h
vendored
@ -1,234 +0,0 @@
|
||||
/* Pixman uses some non-standard compiler features. This file ensures
|
||||
* they exist
|
||||
*
|
||||
* The features are:
|
||||
*
|
||||
* FUNC must be defined to expand to the current function
|
||||
* PIXMAN_EXPORT should be defined to whatever is required to
|
||||
* export functions from a shared library
|
||||
* limits limits for various types must be defined
|
||||
* inline must be defined
|
||||
* force_inline must be defined
|
||||
*/
|
||||
#if defined (__GNUC__)
|
||||
# define FUNC ((const char*) (__PRETTY_FUNCTION__))
|
||||
#elif defined (__sun) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
|
||||
# define FUNC ((const char*) (__func__))
|
||||
#else
|
||||
# define FUNC ((const char*) ("???"))
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__)
|
||||
# define unlikely(expr) __builtin_expect ((expr), 0)
|
||||
#else
|
||||
# define unlikely(expr) (expr)
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__)
|
||||
# define MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MIN
|
||||
# define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MAX
|
||||
# define INT16_MAX (32767)
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MIN
|
||||
# define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MAX
|
||||
# define INT32_MAX (2147483647)
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MIN
|
||||
# define UINT32_MIN (0)
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#ifndef INT64_MIN
|
||||
# define INT64_MIN (-9223372036854775807-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT64_MAX
|
||||
# define INT64_MAX (9223372036854775807)
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* 'inline' is available only in C++ in MSVC */
|
||||
# define inline __inline
|
||||
# define force_inline __forceinline
|
||||
# define noinline __declspec(noinline)
|
||||
#elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
|
||||
# define inline __inline__
|
||||
# define force_inline __inline__ __attribute__ ((__always_inline__))
|
||||
# define noinline __attribute__((noinline))
|
||||
#else
|
||||
# ifndef force_inline
|
||||
# define force_inline inline
|
||||
# endif
|
||||
# ifndef noinline
|
||||
# define noinline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* GCC visibility */
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32)
|
||||
# define PIXMAN_EXPORT __attribute__ ((visibility("default")))
|
||||
/* Sun Studio 8 visibility */
|
||||
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
|
||||
# define PIXMAN_EXPORT __global
|
||||
#elif defined (_MSC_VER) || defined(__MINGW32__)
|
||||
# define PIXMAN_EXPORT PIXMAN_API
|
||||
#else
|
||||
# define PIXMAN_EXPORT
|
||||
#endif
|
||||
|
||||
/* member offsets */
|
||||
#define CONTAINER_OF(type, member, data) \
|
||||
((type *)(((uint8_t *)data) - offsetof (type, member)))
|
||||
|
||||
/* TLS */
|
||||
#if defined(PIXMAN_NO_TLS)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static type name;
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(TLS)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static TLS type name;
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
|
||||
# define _NO_W32_PSEUDO_MODIFIERS
|
||||
# include <windows.h>
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static volatile int tls_ ## name ## _initialized = 0; \
|
||||
static void *tls_ ## name ## _mutex = NULL; \
|
||||
static unsigned tls_ ## name ## _index; \
|
||||
\
|
||||
static type * \
|
||||
tls_ ## name ## _alloc (void) \
|
||||
{ \
|
||||
type *value = calloc (1, sizeof (type)); \
|
||||
if (value) \
|
||||
TlsSetValue (tls_ ## name ## _index, value); \
|
||||
return value; \
|
||||
} \
|
||||
\
|
||||
static force_inline type * \
|
||||
tls_ ## name ## _get (void) \
|
||||
{ \
|
||||
type *value; \
|
||||
if (!tls_ ## name ## _initialized) \
|
||||
{ \
|
||||
if (!tls_ ## name ## _mutex) \
|
||||
{ \
|
||||
void *mutex = CreateMutexA (NULL, 0, NULL); \
|
||||
if (InterlockedCompareExchangePointer ( \
|
||||
&tls_ ## name ## _mutex, mutex, NULL) != NULL) \
|
||||
{ \
|
||||
CloseHandle (mutex); \
|
||||
} \
|
||||
} \
|
||||
WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \
|
||||
if (!tls_ ## name ## _initialized) \
|
||||
{ \
|
||||
tls_ ## name ## _index = TlsAlloc (); \
|
||||
tls_ ## name ## _initialized = 1; \
|
||||
} \
|
||||
ReleaseMutex (tls_ ## name ## _mutex); \
|
||||
} \
|
||||
if (tls_ ## name ## _index == 0xFFFFFFFF) \
|
||||
return NULL; \
|
||||
value = TlsGetValue (tls_ ## name ## _index); \
|
||||
if (!value) \
|
||||
value = tls_ ## name ## _alloc (); \
|
||||
return value; \
|
||||
}
|
||||
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
tls_ ## name ## _get ()
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static __declspec(thread) type name;
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(HAVE_PTHREADS)
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
|
||||
static pthread_key_t tls_ ## name ## _key; \
|
||||
\
|
||||
static void \
|
||||
tls_ ## name ## _destroy_value (void *value) \
|
||||
{ \
|
||||
free (value); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
tls_ ## name ## _make_key (void) \
|
||||
{ \
|
||||
pthread_key_create (&tls_ ## name ## _key, \
|
||||
tls_ ## name ## _destroy_value); \
|
||||
} \
|
||||
\
|
||||
static type * \
|
||||
tls_ ## name ## _alloc (void) \
|
||||
{ \
|
||||
type *value = calloc (1, sizeof (type)); \
|
||||
if (value) \
|
||||
pthread_setspecific (tls_ ## name ## _key, value); \
|
||||
return value; \
|
||||
} \
|
||||
\
|
||||
static force_inline type * \
|
||||
tls_ ## name ## _get (void) \
|
||||
{ \
|
||||
type *value = NULL; \
|
||||
if (pthread_once (&tls_ ## name ## _once_control, \
|
||||
tls_ ## name ## _make_key) == 0) \
|
||||
{ \
|
||||
value = pthread_getspecific (tls_ ## name ## _key); \
|
||||
if (!value) \
|
||||
value = tls_ ## name ## _alloc (); \
|
||||
} \
|
||||
return value; \
|
||||
}
|
||||
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
tls_ ## name ## _get ()
|
||||
|
||||
#else
|
||||
|
||||
# error "Unknown thread local support for this system. Pixman will not work with multiple threads. Define PIXMAN_NO_TLS to acknowledge and accept this limitation and compile pixman without thread-safety support."
|
||||
|
||||
#endif
|
220
vendor/pixman/pixman/pixman-conical-gradient.c
vendored
220
vendor/pixman/pixman/pixman-conical-gradient.c
vendored
@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static force_inline double
|
||||
coordinates_to_parameter (double x, double y, double angle)
|
||||
{
|
||||
double t;
|
||||
|
||||
t = atan2 (y, x) + angle;
|
||||
|
||||
while (t < 0)
|
||||
t += 2 * M_PI;
|
||||
|
||||
while (t >= 2 * M_PI)
|
||||
t -= 2 * M_PI;
|
||||
|
||||
return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and
|
||||
* make rotation CCW
|
||||
*/
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
conical_get_scanline (pixman_iter_t *iter,
|
||||
const uint32_t *mask,
|
||||
int Bpp,
|
||||
pixman_gradient_walker_write_t write_pixel)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
int x = iter->x;
|
||||
int y = iter->y;
|
||||
int width = iter->width;
|
||||
uint32_t *buffer = iter->buffer;
|
||||
|
||||
gradient_t *gradient = (gradient_t *)image;
|
||||
conical_gradient_t *conical = (conical_gradient_t *)image;
|
||||
uint32_t *end = buffer + width * (Bpp / 4);
|
||||
pixman_gradient_walker_t walker;
|
||||
pixman_bool_t affine = TRUE;
|
||||
double cx = 1.;
|
||||
double cy = 0.;
|
||||
double cz = 0.;
|
||||
double rx = x + 0.5;
|
||||
double ry = y + 0.5;
|
||||
double rz = 1.;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
|
||||
|
||||
if (image->common.transform)
|
||||
{
|
||||
pixman_vector_t v;
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
if (!pixman_transform_point_3d (image->common.transform, &v))
|
||||
return iter->buffer;
|
||||
|
||||
cx = image->common.transform->matrix[0][0] / 65536.;
|
||||
cy = image->common.transform->matrix[1][0] / 65536.;
|
||||
cz = image->common.transform->matrix[2][0] / 65536.;
|
||||
|
||||
rx = v.vector[0] / 65536.;
|
||||
ry = v.vector[1] / 65536.;
|
||||
rz = v.vector[2] / 65536.;
|
||||
|
||||
affine =
|
||||
image->common.transform->matrix[2][0] == 0 &&
|
||||
v.vector[2] == pixman_fixed_1;
|
||||
}
|
||||
|
||||
if (affine)
|
||||
{
|
||||
rx -= conical->center.x / 65536.;
|
||||
ry -= conical->center.y / 65536.;
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
double t = coordinates_to_parameter (rx, ry, conical->angle);
|
||||
|
||||
write_pixel (&walker,
|
||||
(pixman_fixed_48_16_t)pixman_double_to_fixed (t),
|
||||
buffer);
|
||||
}
|
||||
|
||||
buffer += (Bpp / 4);
|
||||
|
||||
rx += cx;
|
||||
ry += cy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (buffer < end)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
double t;
|
||||
|
||||
if (rz != 0)
|
||||
{
|
||||
x = rx / rz;
|
||||
y = ry / rz;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = y = 0.;
|
||||
}
|
||||
|
||||
x -= conical->center.x / 65536.;
|
||||
y -= conical->center.y / 65536.;
|
||||
|
||||
t = coordinates_to_parameter (x, y, conical->angle);
|
||||
|
||||
write_pixel (&walker,
|
||||
(pixman_fixed_48_16_t)pixman_double_to_fixed (t),
|
||||
buffer);
|
||||
}
|
||||
|
||||
buffer += (Bpp / 4);
|
||||
|
||||
rx += cx;
|
||||
ry += cy;
|
||||
rz += cz;
|
||||
}
|
||||
}
|
||||
|
||||
iter->y++;
|
||||
return iter->buffer;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return conical_get_scanline (iter, mask, 4,
|
||||
_pixman_gradient_walker_write_narrow);
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return conical_get_scanline (iter, NULL, 16,
|
||||
_pixman_gradient_walker_write_wide);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
||||
{
|
||||
if (iter->iter_flags & ITER_NARROW)
|
||||
iter->get_scanline = conical_get_scanline_narrow;
|
||||
else
|
||||
iter->get_scanline = conical_get_scanline_wide;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_conical_gradient (const pixman_point_fixed_t * center,
|
||||
pixman_fixed_t angle,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_image_t *image = _pixman_image_allocate ();
|
||||
conical_gradient_t *conical;
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
conical = &image->conical;
|
||||
|
||||
if (!_pixman_init_gradient (&conical->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
angle = MOD (angle, pixman_int_to_fixed (360));
|
||||
|
||||
image->type = CONICAL;
|
||||
|
||||
conical->center = *center;
|
||||
conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
4
vendor/pixman/pixman/pixman-edge-accessors.c
vendored
4
vendor/pixman/pixman/pixman-edge-accessors.c
vendored
@ -1,4 +0,0 @@
|
||||
|
||||
#define PIXMAN_FB_ACCESSORS
|
||||
|
||||
#include "pixman-edge.c"
|
182
vendor/pixman/pixman/pixman-edge-imp.h
vendored
182
vendor/pixman/pixman/pixman-edge-imp.h
vendored
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef rasterize_span
|
||||
#endif
|
||||
|
||||
static void
|
||||
RASTERIZE_EDGES (pixman_image_t *image,
|
||||
pixman_edge_t *l,
|
||||
pixman_edge_t *r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
pixman_fixed_t y = t;
|
||||
uint32_t *line;
|
||||
uint32_t *buf = (image)->bits.bits;
|
||||
int stride = (image)->bits.rowstride;
|
||||
int width = (image)->bits.width;
|
||||
|
||||
line = buf + pixman_fixed_to_int (y) * stride;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
pixman_fixed_t lx;
|
||||
pixman_fixed_t rx;
|
||||
int lxi;
|
||||
int rxi;
|
||||
|
||||
lx = l->x;
|
||||
rx = r->x;
|
||||
#if N_BITS == 1
|
||||
/* For the non-antialiased case, round the coordinates up, in effect
|
||||
* sampling just slightly to the left of the pixel. This is so that
|
||||
* when the sample point lies exactly on the line, we round towards
|
||||
* north-west.
|
||||
*
|
||||
* (The AA case does a similar adjustment in RENDER_SAMPLES_X)
|
||||
*/
|
||||
lx += X_FRAC_FIRST(1) - pixman_fixed_e;
|
||||
rx += X_FRAC_FIRST(1) - pixman_fixed_e;
|
||||
#endif
|
||||
/* clip X */
|
||||
if (lx < 0)
|
||||
lx = 0;
|
||||
if (pixman_fixed_to_int (rx) >= width)
|
||||
#if N_BITS == 1
|
||||
rx = pixman_int_to_fixed (width);
|
||||
#else
|
||||
/* Use the last pixel of the scanline, covered 100%.
|
||||
* We can't use the first pixel following the scanline,
|
||||
* because accessing it could result in a buffer overrun.
|
||||
*/
|
||||
rx = pixman_int_to_fixed (width) - 1;
|
||||
#endif
|
||||
|
||||
/* Skip empty (or backwards) sections */
|
||||
if (rx > lx)
|
||||
{
|
||||
|
||||
/* Find pixel bounds for span */
|
||||
lxi = pixman_fixed_to_int (lx);
|
||||
rxi = pixman_fixed_to_int (rx);
|
||||
|
||||
#if N_BITS == 1
|
||||
{
|
||||
|
||||
#define LEFT_MASK(x) \
|
||||
(((x) & 0x1f) ? \
|
||||
SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0)
|
||||
#define RIGHT_MASK(x) \
|
||||
(((32 - (x)) & 0x1f) ? \
|
||||
SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0)
|
||||
|
||||
#define MASK_BITS(x,w,l,n,r) { \
|
||||
n = (w); \
|
||||
r = RIGHT_MASK ((x) + n); \
|
||||
l = LEFT_MASK (x); \
|
||||
if (l) { \
|
||||
n -= 32 - ((x) & 0x1f); \
|
||||
if (n < 0) { \
|
||||
n = 0; \
|
||||
l &= r; \
|
||||
r = 0; \
|
||||
} \
|
||||
} \
|
||||
n >>= 5; \
|
||||
}
|
||||
|
||||
uint32_t *a = line;
|
||||
uint32_t startmask;
|
||||
uint32_t endmask;
|
||||
int nmiddle;
|
||||
int width = rxi - lxi;
|
||||
int x = lxi;
|
||||
|
||||
a += x >> 5;
|
||||
x &= 0x1f;
|
||||
|
||||
MASK_BITS (x, width, startmask, nmiddle, endmask);
|
||||
|
||||
if (startmask) {
|
||||
WRITE(image, a, READ(image, a) | startmask);
|
||||
a++;
|
||||
}
|
||||
while (nmiddle--)
|
||||
WRITE(image, a++, 0xffffffff);
|
||||
if (endmask)
|
||||
WRITE(image, a, READ(image, a) | endmask);
|
||||
}
|
||||
#else
|
||||
{
|
||||
DEFINE_ALPHA(line,lxi);
|
||||
int lxs;
|
||||
int rxs;
|
||||
|
||||
/* Sample coverage for edge pixels */
|
||||
lxs = RENDER_SAMPLES_X (lx, N_BITS);
|
||||
rxs = RENDER_SAMPLES_X (rx, N_BITS);
|
||||
|
||||
/* Add coverage across row */
|
||||
if (lxi == rxi)
|
||||
{
|
||||
ADD_ALPHA (rxs - lxs);
|
||||
}
|
||||
else
|
||||
{
|
||||
int xi;
|
||||
|
||||
ADD_ALPHA (N_X_FRAC(N_BITS) - lxs);
|
||||
STEP_ALPHA;
|
||||
for (xi = lxi + 1; xi < rxi; xi++)
|
||||
{
|
||||
ADD_ALPHA (N_X_FRAC(N_BITS));
|
||||
STEP_ALPHA;
|
||||
}
|
||||
ADD_ALPHA (rxs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (y == b)
|
||||
break;
|
||||
|
||||
#if N_BITS > 1
|
||||
if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS))
|
||||
{
|
||||
RENDER_EDGE_STEP_SMALL (l);
|
||||
RENDER_EDGE_STEP_SMALL (r);
|
||||
y += STEP_Y_SMALL(N_BITS);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RENDER_EDGE_STEP_BIG (l);
|
||||
RENDER_EDGE_STEP_BIG (r);
|
||||
y += STEP_Y_BIG(N_BITS);
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef rasterize_span
|
385
vendor/pixman/pixman/pixman-edge.c
vendored
385
vendor/pixman/pixman/pixman-edge.c
vendored
@ -1,385 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2004 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-accessor.h"
|
||||
|
||||
/*
|
||||
* Step across a small sample grid gap
|
||||
*/
|
||||
#define RENDER_EDGE_STEP_SMALL(edge) \
|
||||
{ \
|
||||
edge->x += edge->stepx_small; \
|
||||
edge->e += edge->dx_small; \
|
||||
if (edge->e > 0) \
|
||||
{ \
|
||||
edge->e -= edge->dy; \
|
||||
edge->x += edge->signdx; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Step across a large sample grid gap
|
||||
*/
|
||||
#define RENDER_EDGE_STEP_BIG(edge) \
|
||||
{ \
|
||||
edge->x += edge->stepx_big; \
|
||||
edge->e += edge->dx_big; \
|
||||
if (edge->e > 0) \
|
||||
{ \
|
||||
edge->e -= edge->dy; \
|
||||
edge->x += edge->signdx; \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef PIXMAN_FB_ACCESSORS
|
||||
#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_accessors
|
||||
#else
|
||||
#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_no_accessors
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 4 bit alpha
|
||||
*/
|
||||
|
||||
#define N_BITS 4
|
||||
#define RASTERIZE_EDGES rasterize_edges_4
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
#define SHIFT_4(o) ((o) << 2)
|
||||
#else
|
||||
#define SHIFT_4(o) ((1 - (o)) << 2)
|
||||
#endif
|
||||
|
||||
#define GET_4(x, o) (((x) >> SHIFT_4 (o)) & 0xf)
|
||||
#define PUT_4(x, o, v) \
|
||||
(((x) & ~(0xf << SHIFT_4 (o))) | (((v) & 0xf) << SHIFT_4 (o)))
|
||||
|
||||
#define DEFINE_ALPHA(line, x) \
|
||||
uint8_t *__ap = (uint8_t *) line + ((x) >> 1); \
|
||||
int __ao = (x) & 1
|
||||
|
||||
#define STEP_ALPHA ((__ap += __ao), (__ao ^= 1))
|
||||
|
||||
#define ADD_ALPHA(a) \
|
||||
{ \
|
||||
uint8_t __o = READ (image, __ap); \
|
||||
uint8_t __a = (a) + GET_4 (__o, __ao); \
|
||||
WRITE (image, __ap, PUT_4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \
|
||||
}
|
||||
|
||||
#include "pixman-edge-imp.h"
|
||||
|
||||
#undef ADD_ALPHA
|
||||
#undef STEP_ALPHA
|
||||
#undef DEFINE_ALPHA
|
||||
#undef RASTERIZE_EDGES
|
||||
#undef N_BITS
|
||||
|
||||
|
||||
/*
|
||||
* 1 bit alpha
|
||||
*/
|
||||
|
||||
#define N_BITS 1
|
||||
#define RASTERIZE_EDGES rasterize_edges_1
|
||||
|
||||
#include "pixman-edge-imp.h"
|
||||
|
||||
#undef RASTERIZE_EDGES
|
||||
#undef N_BITS
|
||||
|
||||
/*
|
||||
* 8 bit alpha
|
||||
*/
|
||||
|
||||
static force_inline uint8_t
|
||||
clip255 (int x)
|
||||
{
|
||||
if (x > 255)
|
||||
return 255;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
#define ADD_SATURATE_8(buf, val, length) \
|
||||
do \
|
||||
{ \
|
||||
int i__ = (length); \
|
||||
uint8_t *buf__ = (buf); \
|
||||
int val__ = (val); \
|
||||
\
|
||||
while (i__--) \
|
||||
{ \
|
||||
WRITE (image, (buf__), clip255 (READ (image, (buf__)) + (val__))); \
|
||||
(buf__)++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* We want to detect the case where we add the same value to a long
|
||||
* span of pixels. The triangles on the end are filled in while we
|
||||
* count how many sub-pixel scanlines contribute to the middle section.
|
||||
*
|
||||
* +--------------------------+
|
||||
* fill_height =| \ /
|
||||
* +------------------+
|
||||
* |================|
|
||||
* fill_start fill_end
|
||||
*/
|
||||
static void
|
||||
rasterize_edges_8 (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
pixman_fixed_t y = t;
|
||||
uint32_t *line;
|
||||
int fill_start = -1, fill_end = -1;
|
||||
int fill_size = 0;
|
||||
uint32_t *buf = (image)->bits.bits;
|
||||
int stride = (image)->bits.rowstride;
|
||||
int width = (image)->bits.width;
|
||||
|
||||
line = buf + pixman_fixed_to_int (y) * stride;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
uint8_t *ap = (uint8_t *) line;
|
||||
pixman_fixed_t lx, rx;
|
||||
int lxi, rxi;
|
||||
|
||||
/* clip X */
|
||||
lx = l->x;
|
||||
if (lx < 0)
|
||||
lx = 0;
|
||||
|
||||
rx = r->x;
|
||||
|
||||
if (pixman_fixed_to_int (rx) >= width)
|
||||
{
|
||||
/* Use the last pixel of the scanline, covered 100%.
|
||||
* We can't use the first pixel following the scanline,
|
||||
* because accessing it could result in a buffer overrun.
|
||||
*/
|
||||
rx = pixman_int_to_fixed (width) - 1;
|
||||
}
|
||||
|
||||
/* Skip empty (or backwards) sections */
|
||||
if (rx > lx)
|
||||
{
|
||||
int lxs, rxs;
|
||||
|
||||
/* Find pixel bounds for span. */
|
||||
lxi = pixman_fixed_to_int (lx);
|
||||
rxi = pixman_fixed_to_int (rx);
|
||||
|
||||
/* Sample coverage for edge pixels */
|
||||
lxs = RENDER_SAMPLES_X (lx, 8);
|
||||
rxs = RENDER_SAMPLES_X (rx, 8);
|
||||
|
||||
/* Add coverage across row */
|
||||
if (lxi == rxi)
|
||||
{
|
||||
WRITE (image, ap + lxi,
|
||||
clip255 (READ (image, ap + lxi) + rxs - lxs));
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE (image, ap + lxi,
|
||||
clip255 (READ (image, ap + lxi) + N_X_FRAC (8) - lxs));
|
||||
|
||||
/* Move forward so that lxi/rxi is the pixel span */
|
||||
lxi++;
|
||||
|
||||
/* Don't bother trying to optimize the fill unless
|
||||
* the span is longer than 4 pixels. */
|
||||
if (rxi - lxi > 4)
|
||||
{
|
||||
if (fill_start < 0)
|
||||
{
|
||||
fill_start = lxi;
|
||||
fill_end = rxi;
|
||||
fill_size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lxi >= fill_end || rxi < fill_start)
|
||||
{
|
||||
/* We're beyond what we saved, just fill it */
|
||||
ADD_SATURATE_8 (ap + fill_start,
|
||||
fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
fill_start = lxi;
|
||||
fill_end = rxi;
|
||||
fill_size = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update fill_start */
|
||||
if (lxi > fill_start)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start,
|
||||
fill_size * N_X_FRAC (8),
|
||||
lxi - fill_start);
|
||||
fill_start = lxi;
|
||||
}
|
||||
else if (lxi < fill_start)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8),
|
||||
fill_start - lxi);
|
||||
}
|
||||
|
||||
/* Update fill_end */
|
||||
if (rxi < fill_end)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + rxi,
|
||||
fill_size * N_X_FRAC (8),
|
||||
fill_end - rxi);
|
||||
fill_end = rxi;
|
||||
}
|
||||
else if (fill_end < rxi)
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_end,
|
||||
N_X_FRAC (8),
|
||||
rxi - fill_end);
|
||||
}
|
||||
fill_size++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), rxi - lxi);
|
||||
}
|
||||
|
||||
WRITE (image, ap + rxi, clip255 (READ (image, ap + rxi) + rxs));
|
||||
}
|
||||
}
|
||||
|
||||
if (y == b)
|
||||
{
|
||||
/* We're done, make sure we clean up any remaining fill. */
|
||||
if (fill_start != fill_end)
|
||||
{
|
||||
if (fill_size == N_Y_FRAC (8))
|
||||
{
|
||||
MEMSET_WRAPPED (image, ap + fill_start,
|
||||
0xff, fill_end - fill_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (pixman_fixed_frac (y) != Y_FRAC_LAST (8))
|
||||
{
|
||||
RENDER_EDGE_STEP_SMALL (l);
|
||||
RENDER_EDGE_STEP_SMALL (r);
|
||||
y += STEP_Y_SMALL (8);
|
||||
}
|
||||
else
|
||||
{
|
||||
RENDER_EDGE_STEP_BIG (l);
|
||||
RENDER_EDGE_STEP_BIG (r);
|
||||
y += STEP_Y_BIG (8);
|
||||
if (fill_start != fill_end)
|
||||
{
|
||||
if (fill_size == N_Y_FRAC (8))
|
||||
{
|
||||
MEMSET_WRAPPED (image, ap + fill_start,
|
||||
0xff, fill_end - fill_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
|
||||
fill_end - fill_start);
|
||||
}
|
||||
|
||||
fill_start = fill_end = -1;
|
||||
fill_size = 0;
|
||||
}
|
||||
|
||||
line += stride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PIXMAN_FB_ACCESSORS
|
||||
static
|
||||
#endif
|
||||
void
|
||||
PIXMAN_RASTERIZE_EDGES (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
switch (PIXMAN_FORMAT_BPP (image->bits.format))
|
||||
{
|
||||
case 1:
|
||||
rasterize_edges_1 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
rasterize_edges_4 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
rasterize_edges_8 (image, l, r, t, b);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PIXMAN_FB_ACCESSORS
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_rasterize_edges (pixman_image_t *image,
|
||||
pixman_edge_t * l,
|
||||
pixman_edge_t * r,
|
||||
pixman_fixed_t t,
|
||||
pixman_fixed_t b)
|
||||
{
|
||||
return_if_fail (image->type == BITS);
|
||||
return_if_fail (PIXMAN_FORMAT_TYPE (image->bits.format) == PIXMAN_TYPE_A);
|
||||
|
||||
if (image->bits.read_func || image->bits.write_func)
|
||||
pixman_rasterize_edges_accessors (image, l, r, t, b);
|
||||
else
|
||||
pixman_rasterize_edges_no_accessors (image, l, r, t, b);
|
||||
}
|
||||
|
||||
#endif
|
3298
vendor/pixman/pixman/pixman-fast-path.c
vendored
3298
vendor/pixman/pixman/pixman-fast-path.c
vendored
File diff suppressed because it is too large
Load Diff
491
vendor/pixman/pixman/pixman-filter.c
vendored
491
vendor/pixman/pixman/pixman-filter.c
vendored
@ -1,491 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012, Red Hat, Inc.
|
||||
* Copyright 2012, Soren Sandmann
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann <soren.sandmann@gmail.com>
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
typedef double (* kernel_func_t) (double x);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pixman_kernel_t kernel;
|
||||
kernel_func_t func;
|
||||
double width;
|
||||
} filter_info_t;
|
||||
|
||||
static double
|
||||
impulse_kernel (double x)
|
||||
{
|
||||
return (x == 0.0)? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
static double
|
||||
box_kernel (double x)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static double
|
||||
linear_kernel (double x)
|
||||
{
|
||||
return 1 - fabs (x);
|
||||
}
|
||||
|
||||
static double
|
||||
gaussian_kernel (double x)
|
||||
{
|
||||
#define SQRT2 (1.4142135623730950488016887242096980785696718753769480)
|
||||
#define SIGMA (SQRT2 / 2.0)
|
||||
|
||||
return exp (- x * x / (2 * SIGMA * SIGMA)) / (SIGMA * sqrt (2.0 * M_PI));
|
||||
}
|
||||
|
||||
static double
|
||||
sinc (double x)
|
||||
{
|
||||
if (x == 0.0)
|
||||
return 1.0;
|
||||
else
|
||||
return sin (M_PI * x) / (M_PI * x);
|
||||
}
|
||||
|
||||
static double
|
||||
lanczos (double x, int n)
|
||||
{
|
||||
return sinc (x) * sinc (x * (1.0 / n));
|
||||
}
|
||||
|
||||
static double
|
||||
lanczos2_kernel (double x)
|
||||
{
|
||||
return lanczos (x, 2);
|
||||
}
|
||||
|
||||
static double
|
||||
lanczos3_kernel (double x)
|
||||
{
|
||||
return lanczos (x, 3);
|
||||
}
|
||||
|
||||
static double
|
||||
nice_kernel (double x)
|
||||
{
|
||||
return lanczos3_kernel (x * 0.75);
|
||||
}
|
||||
|
||||
static double
|
||||
general_cubic (double x, double B, double C)
|
||||
{
|
||||
double ax = fabs(x);
|
||||
|
||||
if (ax < 1)
|
||||
{
|
||||
return (((12 - 9 * B - 6 * C) * ax +
|
||||
(-18 + 12 * B + 6 * C)) * ax * ax +
|
||||
(6 - 2 * B)) / 6;
|
||||
}
|
||||
else if (ax < 2)
|
||||
{
|
||||
return ((((-B - 6 * C) * ax +
|
||||
(6 * B + 30 * C)) * ax +
|
||||
(-12 * B - 48 * C)) * ax +
|
||||
(8 * B + 24 * C)) / 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static double
|
||||
cubic_kernel (double x)
|
||||
{
|
||||
/* This is the Mitchell-Netravali filter.
|
||||
*
|
||||
* (0.0, 0.5) would give us the Catmull-Rom spline,
|
||||
* but that one seems to be indistinguishable from Lanczos2.
|
||||
*/
|
||||
return general_cubic (x, 1/3.0, 1/3.0);
|
||||
}
|
||||
|
||||
static const filter_info_t filters[] =
|
||||
{
|
||||
{ PIXMAN_KERNEL_IMPULSE, impulse_kernel, 0.0 },
|
||||
{ PIXMAN_KERNEL_BOX, box_kernel, 1.0 },
|
||||
{ PIXMAN_KERNEL_LINEAR, linear_kernel, 2.0 },
|
||||
{ PIXMAN_KERNEL_CUBIC, cubic_kernel, 4.0 },
|
||||
{ PIXMAN_KERNEL_GAUSSIAN, gaussian_kernel, 5.0 },
|
||||
{ PIXMAN_KERNEL_LANCZOS2, lanczos2_kernel, 4.0 },
|
||||
{ PIXMAN_KERNEL_LANCZOS3, lanczos3_kernel, 6.0 },
|
||||
{ PIXMAN_KERNEL_LANCZOS3_STRETCHED, nice_kernel, 8.0 },
|
||||
};
|
||||
|
||||
/* This function scales @kernel2 by @scale, then
|
||||
* aligns @x1 in @kernel1 with @x2 in @kernel2 and
|
||||
* and integrates the product of the kernels across @width.
|
||||
*
|
||||
* This function assumes that the intervals are within
|
||||
* the kernels in question. E.g., the caller must not
|
||||
* try to integrate a linear kernel ouside of [-1:1]
|
||||
*/
|
||||
static double
|
||||
integral (pixman_kernel_t kernel1, double x1,
|
||||
pixman_kernel_t kernel2, double scale, double x2,
|
||||
double width)
|
||||
{
|
||||
if (kernel1 == PIXMAN_KERNEL_BOX && kernel2 == PIXMAN_KERNEL_BOX)
|
||||
{
|
||||
return width;
|
||||
}
|
||||
/* The LINEAR filter is not differentiable at 0, so if the
|
||||
* integration interval crosses zero, break it into two
|
||||
* separate integrals.
|
||||
*/
|
||||
else if (kernel1 == PIXMAN_KERNEL_LINEAR && x1 < 0 && x1 + width > 0)
|
||||
{
|
||||
return
|
||||
integral (kernel1, x1, kernel2, scale, x2, - x1) +
|
||||
integral (kernel1, 0, kernel2, scale, x2 - x1, width + x1);
|
||||
}
|
||||
else if (kernel2 == PIXMAN_KERNEL_LINEAR && x2 < 0 && x2 + width > 0)
|
||||
{
|
||||
return
|
||||
integral (kernel1, x1, kernel2, scale, x2, - x2) +
|
||||
integral (kernel1, x1 - x2, kernel2, scale, 0, width + x2);
|
||||
}
|
||||
else if (kernel1 == PIXMAN_KERNEL_IMPULSE)
|
||||
{
|
||||
assert (width == 0.0);
|
||||
return filters[kernel2].func (x2 * scale);
|
||||
}
|
||||
else if (kernel2 == PIXMAN_KERNEL_IMPULSE)
|
||||
{
|
||||
assert (width == 0.0);
|
||||
return filters[kernel1].func (x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Integration via Simpson's rule
|
||||
* See http://www.intmath.com/integration/6-simpsons-rule.php
|
||||
* 12 segments (6 cubic approximations) seems to produce best
|
||||
* result for lanczos3.linear, which was the combination that
|
||||
* showed the most errors. This makes sense as the lanczos3
|
||||
* filter is 6 wide.
|
||||
*/
|
||||
#define N_SEGMENTS 12
|
||||
#define SAMPLE(a1, a2) \
|
||||
(filters[kernel1].func ((a1)) * filters[kernel2].func ((a2) * scale))
|
||||
|
||||
double s = 0.0;
|
||||
double h = width / N_SEGMENTS;
|
||||
int i;
|
||||
|
||||
s = SAMPLE (x1, x2);
|
||||
|
||||
for (i = 1; i < N_SEGMENTS; i += 2)
|
||||
{
|
||||
double a1 = x1 + h * i;
|
||||
double a2 = x2 + h * i;
|
||||
s += 4 * SAMPLE (a1, a2);
|
||||
}
|
||||
|
||||
for (i = 2; i < N_SEGMENTS; i += 2)
|
||||
{
|
||||
double a1 = x1 + h * i;
|
||||
double a2 = x2 + h * i;
|
||||
s += 2 * SAMPLE (a1, a2);
|
||||
}
|
||||
|
||||
s += SAMPLE (x1 + width, x2 + width);
|
||||
|
||||
return h * s * (1.0 / 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_1d_filter (int width,
|
||||
pixman_kernel_t reconstruct,
|
||||
pixman_kernel_t sample,
|
||||
double scale,
|
||||
int n_phases,
|
||||
pixman_fixed_t *pstart,
|
||||
pixman_fixed_t *pend
|
||||
)
|
||||
{
|
||||
pixman_fixed_t *p = pstart;
|
||||
double step;
|
||||
int i;
|
||||
if(width <= 0) return;
|
||||
step = 1.0 / n_phases;
|
||||
|
||||
for (i = 0; i < n_phases; ++i)
|
||||
{
|
||||
double frac = step / 2.0 + i * step;
|
||||
pixman_fixed_t new_total;
|
||||
int x, x1, x2;
|
||||
double total, e;
|
||||
|
||||
/* Sample convolution of reconstruction and sampling
|
||||
* filter. See rounding.txt regarding the rounding
|
||||
* and sample positions.
|
||||
*/
|
||||
|
||||
x1 = ceil (frac - width / 2.0 - 0.5);
|
||||
x2 = x1 + width;
|
||||
assert( p >= pstart && p + (x2 - x1) <= pend ); /* assert validity of the following loop */
|
||||
total = 0;
|
||||
for (x = x1; x < x2; ++x)
|
||||
{
|
||||
double pos = x + 0.5 - frac;
|
||||
double rlow = - filters[reconstruct].width / 2.0;
|
||||
double rhigh = rlow + filters[reconstruct].width;
|
||||
double slow = pos - scale * filters[sample].width / 2.0;
|
||||
double shigh = slow + scale * filters[sample].width;
|
||||
double c = 0.0;
|
||||
double ilow, ihigh;
|
||||
|
||||
if (rhigh >= slow && rlow <= shigh)
|
||||
{
|
||||
ilow = MAX (slow, rlow);
|
||||
ihigh = MIN (shigh, rhigh);
|
||||
|
||||
c = integral (reconstruct, ilow,
|
||||
sample, 1.0 / scale, ilow - pos,
|
||||
ihigh - ilow);
|
||||
}
|
||||
|
||||
*p = (pixman_fixed_t)floor (c * 65536.0 + 0.5);
|
||||
total += *p;
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Normalize, with error diffusion */
|
||||
p -= width;
|
||||
assert(p >= pstart && p + (x2 - x1) <= pend); /* assert validity of the following loop */
|
||||
|
||||
total = 65536.0 / total;
|
||||
new_total = 0;
|
||||
e = 0.0;
|
||||
for (x = x1; x < x2; ++x)
|
||||
{
|
||||
double v = (*p) * total + e;
|
||||
pixman_fixed_t t = floor (v + 0.5);
|
||||
|
||||
e = v - t;
|
||||
new_total += t;
|
||||
*p++ = t;
|
||||
}
|
||||
|
||||
/* pixman_fixed_e's worth of error may remain; put it
|
||||
* at the first sample, since that is the only one that
|
||||
* hasn't had any error diffused into it.
|
||||
*/
|
||||
|
||||
assert(p - width >= pstart && p - width < pend); /* assert... */
|
||||
*(p - width) += pixman_fixed_1 - new_total;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
filter_width (pixman_kernel_t reconstruct, pixman_kernel_t sample, double size)
|
||||
{
|
||||
return ceil (filters[reconstruct].width + size * filters[sample].width);
|
||||
}
|
||||
|
||||
#ifdef PIXMAN_GNUPLOT
|
||||
|
||||
/* If enable-gnuplot is configured, then you can pipe the output of a
|
||||
* pixman-using program to gnuplot and get a continuously-updated plot
|
||||
* of the horizontal filter. This works well with demos/scale to test
|
||||
* the filter generation.
|
||||
*
|
||||
* The plot is all the different subposition filters shuffled
|
||||
* together. This is misleading in a few cases:
|
||||
*
|
||||
* IMPULSE.BOX - goes up and down as the subfilters have different
|
||||
* numbers of non-zero samples
|
||||
* IMPULSE.TRIANGLE - somewhat crooked for the same reason
|
||||
* 1-wide filters - looks triangular, but a 1-wide box would be more
|
||||
* accurate
|
||||
*/
|
||||
static void
|
||||
gnuplot_filter (int width, int n_phases, const pixman_fixed_t* p)
|
||||
{
|
||||
double step;
|
||||
int i, j;
|
||||
int first;
|
||||
|
||||
step = 1.0 / n_phases;
|
||||
|
||||
printf ("set style line 1 lc rgb '#0060ad' lt 1 lw 0.5 pt 7 pi 1 ps 0.5\n");
|
||||
printf ("plot [x=%g:%g] '-' with linespoints ls 1\n", -width*0.5, width*0.5);
|
||||
/* Print a point at the origin so that y==0 line is included: */
|
||||
printf ("0 0\n\n");
|
||||
|
||||
/* The position of the first sample of the phase corresponding to
|
||||
* frac is given by:
|
||||
*
|
||||
* ceil (frac - width / 2.0 - 0.5) + 0.5 - frac
|
||||
*
|
||||
* We have to find the frac that minimizes this expression.
|
||||
*
|
||||
* For odd widths, we have
|
||||
*
|
||||
* ceil (frac - width / 2.0 - 0.5) + 0.5 - frac
|
||||
* = ceil (frac) + K - frac
|
||||
* = 1 + K - frac
|
||||
*
|
||||
* for some K, so this is minimized when frac is maximized and
|
||||
* strictly growing with frac. So for odd widths, we can simply
|
||||
* start at the last phase and go backwards.
|
||||
*
|
||||
* For even widths, we have
|
||||
*
|
||||
* ceil (frac - width / 2.0 - 0.5) + 0.5 - frac
|
||||
* = ceil (frac - 0.5) + K - frac
|
||||
*
|
||||
* The graph for this function (ignoring K) looks like this:
|
||||
*
|
||||
* 0.5
|
||||
* | |\
|
||||
* | | \
|
||||
* | | \
|
||||
* 0 | | \
|
||||
* |\ |
|
||||
* | \ |
|
||||
* | \ |
|
||||
* -0.5 | \|
|
||||
* ---------------------------------
|
||||
* 0 0.5 1
|
||||
*
|
||||
* So in this case we need to start with the phase whose frac is
|
||||
* less than, but as close as possible to 0.5, then go backwards
|
||||
* until we hit the first phase, then wrap around to the last
|
||||
* phase and continue backwards.
|
||||
*
|
||||
* Which phase is as close as possible 0.5? The locations of the
|
||||
* sampling point corresponding to the kth phase is given by
|
||||
* 1/(2 * n_phases) + k / n_phases:
|
||||
*
|
||||
* 1/(2 * n_phases) + k / n_phases = 0.5
|
||||
*
|
||||
* from which it follows that
|
||||
*
|
||||
* k = (n_phases - 1) / 2
|
||||
*
|
||||
* rounded down is the phase in question.
|
||||
*/
|
||||
if (width & 1)
|
||||
first = n_phases - 1;
|
||||
else
|
||||
first = (n_phases - 1) / 2;
|
||||
|
||||
for (j = 0; j < width; ++j)
|
||||
{
|
||||
for (i = 0; i < n_phases; ++i)
|
||||
{
|
||||
int phase = first - i;
|
||||
double frac, pos;
|
||||
|
||||
if (phase < 0)
|
||||
phase = n_phases + phase;
|
||||
|
||||
frac = step / 2.0 + phase * step;
|
||||
pos = ceil (frac - width / 2.0 - 0.5) + 0.5 - frac + j;
|
||||
|
||||
printf ("%g %g\n",
|
||||
pos,
|
||||
pixman_fixed_to_double (*(p + phase * width + j)));
|
||||
}
|
||||
}
|
||||
|
||||
printf ("e\n");
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Create the parameter list for a SEPARABLE_CONVOLUTION filter
|
||||
* with the given kernels and scale parameters
|
||||
*/
|
||||
PIXMAN_EXPORT pixman_fixed_t *
|
||||
pixman_filter_create_separable_convolution (int *n_values,
|
||||
pixman_fixed_t scale_x,
|
||||
pixman_fixed_t scale_y,
|
||||
pixman_kernel_t reconstruct_x,
|
||||
pixman_kernel_t reconstruct_y,
|
||||
pixman_kernel_t sample_x,
|
||||
pixman_kernel_t sample_y,
|
||||
int subsample_bits_x,
|
||||
int subsample_bits_y)
|
||||
{
|
||||
double sx = fabs (pixman_fixed_to_double (scale_x));
|
||||
double sy = fabs (pixman_fixed_to_double (scale_y));
|
||||
pixman_fixed_t *params;
|
||||
int subsample_x, subsample_y;
|
||||
int width, height;
|
||||
|
||||
width = filter_width (reconstruct_x, sample_x, sx);
|
||||
subsample_x = (1 << subsample_bits_x);
|
||||
|
||||
height = filter_width (reconstruct_y, sample_y, sy);
|
||||
subsample_y = (1 << subsample_bits_y);
|
||||
|
||||
*n_values = 4 + width * subsample_x + height * subsample_y;
|
||||
|
||||
params = malloc (*n_values * sizeof (pixman_fixed_t));
|
||||
if (!params)
|
||||
return NULL;
|
||||
|
||||
params[0] = pixman_int_to_fixed (width);
|
||||
params[1] = pixman_int_to_fixed (height);
|
||||
params[2] = pixman_int_to_fixed (subsample_bits_x);
|
||||
params[3] = pixman_int_to_fixed (subsample_bits_y);
|
||||
|
||||
{
|
||||
pixman_fixed_t
|
||||
*xparams = params+4,
|
||||
*yparams = xparams + width*subsample_x,
|
||||
*endparams = params + *n_values;
|
||||
create_1d_filter(width, reconstruct_x, sample_x, sx, subsample_x,
|
||||
xparams, yparams);
|
||||
create_1d_filter(height, reconstruct_y, sample_y, sy, subsample_y,
|
||||
yparams, endparams);
|
||||
}
|
||||
|
||||
#ifdef PIXMAN_GNUPLOT
|
||||
gnuplot_filter(width, subsample_x, params + 4);
|
||||
#endif
|
||||
|
||||
return params;
|
||||
}
|
264
vendor/pixman/pixman/pixman-general.c
vendored
264
vendor/pixman/pixman/pixman-general.c
vendored
@ -1,264 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
* 2008 Aaron Plattner, NVIDIA Corporation
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Red Hat not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. Red Hat makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static void
|
||||
general_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
|
||||
switch (image->type)
|
||||
{
|
||||
case BITS:
|
||||
if ((iter->iter_flags & ITER_SRC) == ITER_SRC)
|
||||
_pixman_bits_image_src_iter_init (image, iter);
|
||||
else
|
||||
_pixman_bits_image_dest_iter_init (image, iter);
|
||||
break;
|
||||
|
||||
case LINEAR:
|
||||
_pixman_linear_gradient_iter_init (image, iter);
|
||||
break;
|
||||
|
||||
case RADIAL:
|
||||
_pixman_radial_gradient_iter_init (image, iter);
|
||||
break;
|
||||
|
||||
case CONICAL:
|
||||
_pixman_conical_gradient_iter_init (image, iter);
|
||||
break;
|
||||
|
||||
case SOLID:
|
||||
_pixman_log_error (FUNC, "Solid image not handled by noop");
|
||||
break;
|
||||
|
||||
default:
|
||||
_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_iter_info_t general_iters[] =
|
||||
{
|
||||
{ PIXMAN_any, 0, 0, general_iter_init, NULL, NULL },
|
||||
{ PIXMAN_null },
|
||||
};
|
||||
|
||||
typedef struct op_info_t op_info_t;
|
||||
struct op_info_t
|
||||
{
|
||||
uint8_t src, dst;
|
||||
};
|
||||
|
||||
#define ITER_IGNORE_BOTH \
|
||||
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA)
|
||||
|
||||
static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
|
||||
{
|
||||
/* Src Dst */
|
||||
{ ITER_IGNORE_BOTH, ITER_IGNORE_BOTH }, /* CLEAR */
|
||||
{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_BOTH }, /* SRC */
|
||||
{ ITER_IGNORE_BOTH, ITER_LOCALIZED_ALPHA }, /* DST */
|
||||
{ 0, ITER_LOCALIZED_ALPHA }, /* OVER */
|
||||
{ ITER_LOCALIZED_ALPHA, 0 }, /* OVER_REVERSE */
|
||||
{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* IN */
|
||||
{ ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* IN_REVERSE */
|
||||
{ ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* OUT */
|
||||
{ ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* OUT_REVERSE */
|
||||
{ 0, 0 }, /* ATOP */
|
||||
{ 0, 0 }, /* ATOP_REVERSE */
|
||||
{ 0, 0 }, /* XOR */
|
||||
{ ITER_LOCALIZED_ALPHA, ITER_LOCALIZED_ALPHA }, /* ADD */
|
||||
{ 0, 0 }, /* SATURATE */
|
||||
};
|
||||
|
||||
#define SCANLINE_BUFFER_LENGTH 8192
|
||||
|
||||
static pixman_bool_t
|
||||
operator_needs_division (pixman_op_t op)
|
||||
{
|
||||
static const uint8_t needs_division[] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* SATURATE */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* DISJOINT */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* CONJOINT */
|
||||
0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, /* blend ops */
|
||||
};
|
||||
|
||||
return needs_division[op];
|
||||
}
|
||||
|
||||
static void
|
||||
general_composite_rect (pixman_implementation_t *imp,
|
||||
pixman_composite_info_t *info)
|
||||
{
|
||||
PIXMAN_COMPOSITE_ARGS (info);
|
||||
uint8_t stack_scanline_buffer[3 * SCANLINE_BUFFER_LENGTH];
|
||||
uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
|
||||
uint8_t *src_buffer, *mask_buffer, *dest_buffer;
|
||||
pixman_iter_t src_iter, mask_iter, dest_iter;
|
||||
pixman_combine_32_func_t compose;
|
||||
pixman_bool_t component_alpha;
|
||||
iter_flags_t width_flag, src_iter_flags;
|
||||
int Bpp;
|
||||
int i;
|
||||
|
||||
if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(dest_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
!(operator_needs_division (op)) &&
|
||||
(dest_image->bits.dither == PIXMAN_DITHER_NONE))
|
||||
{
|
||||
width_flag = ITER_NARROW;
|
||||
Bpp = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
width_flag = ITER_WIDE;
|
||||
Bpp = 16;
|
||||
}
|
||||
|
||||
#define ALIGN(addr) \
|
||||
((uint8_t *)((((uintptr_t)(addr)) + 15) & (~15)))
|
||||
|
||||
if (width <= 0 || _pixman_multiply_overflows_int (width, Bpp * 3))
|
||||
return;
|
||||
|
||||
if (width * Bpp * 3 > sizeof (stack_scanline_buffer) - 15 * 3)
|
||||
{
|
||||
scanline_buffer = pixman_malloc_ab_plus_c (width, Bpp * 3, 15 * 3);
|
||||
|
||||
if (!scanline_buffer)
|
||||
return;
|
||||
|
||||
memset (scanline_buffer, 0, width * Bpp * 3 + 15 * 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (stack_scanline_buffer, 0, sizeof (stack_scanline_buffer));
|
||||
}
|
||||
|
||||
src_buffer = ALIGN (scanline_buffer);
|
||||
mask_buffer = ALIGN (src_buffer + width * Bpp);
|
||||
dest_buffer = ALIGN (mask_buffer + width * Bpp);
|
||||
|
||||
if (width_flag == ITER_WIDE)
|
||||
{
|
||||
/* To make sure there aren't any NANs in the buffers */
|
||||
memset (src_buffer, 0, width * Bpp);
|
||||
memset (mask_buffer, 0, width * Bpp);
|
||||
memset (dest_buffer, 0, width * Bpp);
|
||||
}
|
||||
|
||||
/* src iter */
|
||||
src_iter_flags = width_flag | op_flags[op].src | ITER_SRC;
|
||||
|
||||
_pixman_implementation_iter_init (imp->toplevel, &src_iter, src_image,
|
||||
src_x, src_y, width, height,
|
||||
src_buffer, src_iter_flags,
|
||||
info->src_flags);
|
||||
|
||||
/* mask iter */
|
||||
if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
|
||||
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
|
||||
{
|
||||
/* If it doesn't matter what the source is, then it doesn't matter
|
||||
* what the mask is
|
||||
*/
|
||||
mask_image = NULL;
|
||||
}
|
||||
|
||||
component_alpha = mask_image && mask_image->common.component_alpha;
|
||||
|
||||
_pixman_implementation_iter_init (
|
||||
imp->toplevel, &mask_iter,
|
||||
mask_image, mask_x, mask_y, width, height, mask_buffer,
|
||||
ITER_SRC | width_flag | (component_alpha? 0 : ITER_IGNORE_RGB),
|
||||
info->mask_flags);
|
||||
|
||||
/* dest iter */
|
||||
_pixman_implementation_iter_init (
|
||||
imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
|
||||
dest_buffer, ITER_DEST | width_flag | op_flags[op].dst, info->dest_flags);
|
||||
|
||||
compose = _pixman_implementation_lookup_combiner (
|
||||
imp->toplevel, op, component_alpha, width_flag != ITER_WIDE);
|
||||
|
||||
for (i = 0; i < height; ++i)
|
||||
{
|
||||
uint32_t *s, *m, *d;
|
||||
|
||||
m = mask_iter.get_scanline (&mask_iter, NULL);
|
||||
s = src_iter.get_scanline (&src_iter, m);
|
||||
d = dest_iter.get_scanline (&dest_iter, NULL);
|
||||
|
||||
compose (imp->toplevel, op, d, s, m, width);
|
||||
|
||||
dest_iter.write_back (&dest_iter);
|
||||
}
|
||||
|
||||
if (src_iter.fini)
|
||||
src_iter.fini (&src_iter);
|
||||
if (mask_iter.fini)
|
||||
mask_iter.fini (&mask_iter);
|
||||
if (dest_iter.fini)
|
||||
dest_iter.fini (&dest_iter);
|
||||
|
||||
if (scanline_buffer != (uint8_t *) stack_scanline_buffer)
|
||||
free (scanline_buffer);
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t general_fast_path[] =
|
||||
{
|
||||
{ PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect },
|
||||
{ PIXMAN_OP_NONE }
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_general (void)
|
||||
{
|
||||
pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
|
||||
|
||||
_pixman_setup_combiner_functions_32 (imp);
|
||||
_pixman_setup_combiner_functions_float (imp);
|
||||
|
||||
imp->iter_info = general_iters;
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
676
vendor/pixman/pixman/pixman-glyph.c
vendored
676
vendor/pixman/pixman/pixman-glyph.c
vendored
@ -1,676 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010, 2012, Soren Sandmann <sandmann@cs.au.dk>
|
||||
* Copyright 2010, 2011, 2012, Red Hat, Inc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Author: Soren Sandmann <sandmann@cs.au.dk>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct glyph_metrics_t glyph_metrics_t;
|
||||
typedef struct glyph_t glyph_t;
|
||||
|
||||
#define TOMBSTONE ((glyph_t *)0x1)
|
||||
|
||||
/* XXX: These numbers are arbitrary---we've never done any measurements.
|
||||
*/
|
||||
#define N_GLYPHS_HIGH_WATER (16384)
|
||||
#define N_GLYPHS_LOW_WATER (8192)
|
||||
#define HASH_SIZE (2 * N_GLYPHS_HIGH_WATER)
|
||||
#define HASH_MASK (HASH_SIZE - 1)
|
||||
|
||||
struct glyph_t
|
||||
{
|
||||
void * font_key;
|
||||
void * glyph_key;
|
||||
int origin_x;
|
||||
int origin_y;
|
||||
pixman_image_t * image;
|
||||
pixman_link_t mru_link;
|
||||
};
|
||||
|
||||
struct pixman_glyph_cache_t
|
||||
{
|
||||
int n_glyphs;
|
||||
int n_tombstones;
|
||||
int freeze_count;
|
||||
pixman_list_t mru;
|
||||
glyph_t * glyphs[HASH_SIZE];
|
||||
};
|
||||
|
||||
static void
|
||||
free_glyph (glyph_t *glyph)
|
||||
{
|
||||
pixman_list_unlink (&glyph->mru_link);
|
||||
pixman_image_unref (glyph->image);
|
||||
free (glyph);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
hash (const void *font_key, const void *glyph_key)
|
||||
{
|
||||
size_t key = (size_t)font_key + (size_t)glyph_key;
|
||||
|
||||
/* This hash function is based on one found on Thomas Wang's
|
||||
* web page at
|
||||
*
|
||||
* http://www.concentric.net/~Ttwang/tech/inthash.htm
|
||||
*
|
||||
*/
|
||||
key = (key << 15) - key - 1;
|
||||
key = key ^ (key >> 12);
|
||||
key = key + (key << 2);
|
||||
key = key ^ (key >> 4);
|
||||
key = key + (key << 3) + (key << 11);
|
||||
key = key ^ (key >> 16);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static glyph_t *
|
||||
lookup_glyph (pixman_glyph_cache_t *cache,
|
||||
void *font_key,
|
||||
void *glyph_key)
|
||||
{
|
||||
unsigned idx;
|
||||
glyph_t *g;
|
||||
|
||||
idx = hash (font_key, glyph_key);
|
||||
while ((g = cache->glyphs[idx++ & HASH_MASK]))
|
||||
{
|
||||
if (g != TOMBSTONE &&
|
||||
g->font_key == font_key &&
|
||||
g->glyph_key == glyph_key)
|
||||
{
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
insert_glyph (pixman_glyph_cache_t *cache,
|
||||
glyph_t *glyph)
|
||||
{
|
||||
unsigned idx;
|
||||
glyph_t **loc;
|
||||
|
||||
idx = hash (glyph->font_key, glyph->glyph_key);
|
||||
|
||||
/* Note: we assume that there is room in the table. If there isn't,
|
||||
* this will be an infinite loop.
|
||||
*/
|
||||
do
|
||||
{
|
||||
loc = &cache->glyphs[idx++ & HASH_MASK];
|
||||
} while (*loc && *loc != TOMBSTONE);
|
||||
|
||||
if (*loc == TOMBSTONE)
|
||||
cache->n_tombstones--;
|
||||
cache->n_glyphs++;
|
||||
|
||||
*loc = glyph;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_glyph (pixman_glyph_cache_t *cache,
|
||||
glyph_t *glyph)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
idx = hash (glyph->font_key, glyph->glyph_key);
|
||||
while (cache->glyphs[idx & HASH_MASK] != glyph)
|
||||
idx++;
|
||||
|
||||
cache->glyphs[idx & HASH_MASK] = TOMBSTONE;
|
||||
cache->n_tombstones++;
|
||||
cache->n_glyphs--;
|
||||
|
||||
/* Eliminate tombstones if possible */
|
||||
if (cache->glyphs[(idx + 1) & HASH_MASK] == NULL)
|
||||
{
|
||||
while (cache->glyphs[idx & HASH_MASK] == TOMBSTONE)
|
||||
{
|
||||
cache->glyphs[idx & HASH_MASK] = NULL;
|
||||
cache->n_tombstones--;
|
||||
idx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clear_table (pixman_glyph_cache_t *cache)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HASH_SIZE; ++i)
|
||||
{
|
||||
glyph_t *glyph = cache->glyphs[i];
|
||||
|
||||
if (glyph && glyph != TOMBSTONE)
|
||||
free_glyph (glyph);
|
||||
|
||||
cache->glyphs[i] = NULL;
|
||||
}
|
||||
|
||||
cache->n_glyphs = 0;
|
||||
cache->n_tombstones = 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_glyph_cache_t *
|
||||
pixman_glyph_cache_create (void)
|
||||
{
|
||||
pixman_glyph_cache_t *cache;
|
||||
|
||||
if (!(cache = malloc (sizeof *cache)))
|
||||
return NULL;
|
||||
|
||||
memset (cache->glyphs, 0, sizeof (cache->glyphs));
|
||||
cache->n_glyphs = 0;
|
||||
cache->n_tombstones = 0;
|
||||
cache->freeze_count = 0;
|
||||
|
||||
pixman_list_init (&cache->mru);
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_cache_destroy (pixman_glyph_cache_t *cache)
|
||||
{
|
||||
return_if_fail (cache->freeze_count == 0);
|
||||
|
||||
clear_table (cache);
|
||||
|
||||
free (cache);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_cache_freeze (pixman_glyph_cache_t *cache)
|
||||
{
|
||||
cache->freeze_count++;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_cache_thaw (pixman_glyph_cache_t *cache)
|
||||
{
|
||||
if (--cache->freeze_count == 0 &&
|
||||
cache->n_glyphs + cache->n_tombstones > N_GLYPHS_HIGH_WATER)
|
||||
{
|
||||
if (cache->n_tombstones > N_GLYPHS_HIGH_WATER)
|
||||
{
|
||||
/* More than half the entries are
|
||||
* tombstones. Just dump the whole table.
|
||||
*/
|
||||
clear_table (cache);
|
||||
}
|
||||
|
||||
while (cache->n_glyphs > N_GLYPHS_LOW_WATER)
|
||||
{
|
||||
glyph_t *glyph = CONTAINER_OF (glyph_t, mru_link, cache->mru.tail);
|
||||
|
||||
remove_glyph (cache, glyph);
|
||||
free_glyph (glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT const void *
|
||||
pixman_glyph_cache_lookup (pixman_glyph_cache_t *cache,
|
||||
void *font_key,
|
||||
void *glyph_key)
|
||||
{
|
||||
return lookup_glyph (cache, font_key, glyph_key);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT const void *
|
||||
pixman_glyph_cache_insert (pixman_glyph_cache_t *cache,
|
||||
void *font_key,
|
||||
void *glyph_key,
|
||||
int origin_x,
|
||||
int origin_y,
|
||||
pixman_image_t *image)
|
||||
{
|
||||
glyph_t *glyph;
|
||||
int32_t width, height;
|
||||
|
||||
return_val_if_fail (cache->freeze_count > 0, NULL);
|
||||
return_val_if_fail (image->type == BITS, NULL);
|
||||
|
||||
width = image->bits.width;
|
||||
height = image->bits.height;
|
||||
|
||||
if (cache->n_glyphs >= HASH_SIZE)
|
||||
return NULL;
|
||||
|
||||
if (!(glyph = malloc (sizeof *glyph)))
|
||||
return NULL;
|
||||
|
||||
glyph->font_key = font_key;
|
||||
glyph->glyph_key = glyph_key;
|
||||
glyph->origin_x = origin_x;
|
||||
glyph->origin_y = origin_y;
|
||||
|
||||
if (!(glyph->image = pixman_image_create_bits (
|
||||
image->bits.format, width, height, NULL, -1)))
|
||||
{
|
||||
free (glyph);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pixman_image_composite32 (PIXMAN_OP_SRC,
|
||||
image, NULL, glyph->image, 0, 0, 0, 0, 0, 0,
|
||||
width, height);
|
||||
|
||||
if (PIXMAN_FORMAT_A (glyph->image->bits.format) != 0 &&
|
||||
PIXMAN_FORMAT_RGB (glyph->image->bits.format) != 0)
|
||||
{
|
||||
pixman_image_set_component_alpha (glyph->image, TRUE);
|
||||
}
|
||||
|
||||
pixman_list_prepend (&cache->mru, &glyph->mru_link);
|
||||
|
||||
_pixman_image_validate (glyph->image);
|
||||
insert_glyph (cache, glyph);
|
||||
|
||||
return glyph;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_cache_remove (pixman_glyph_cache_t *cache,
|
||||
void *font_key,
|
||||
void *glyph_key)
|
||||
{
|
||||
glyph_t *glyph;
|
||||
|
||||
if ((glyph = lookup_glyph (cache, font_key, glyph_key)))
|
||||
{
|
||||
remove_glyph (cache, glyph);
|
||||
|
||||
free_glyph (glyph);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_glyph_get_extents (pixman_glyph_cache_t *cache,
|
||||
int n_glyphs,
|
||||
pixman_glyph_t *glyphs,
|
||||
pixman_box32_t *extents)
|
||||
{
|
||||
int i;
|
||||
|
||||
extents->x1 = extents->y1 = INT32_MAX;
|
||||
extents->x2 = extents->y2 = INT32_MIN;
|
||||
|
||||
for (i = 0; i < n_glyphs; ++i)
|
||||
{
|
||||
glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
x1 = glyphs[i].x - glyph->origin_x;
|
||||
y1 = glyphs[i].y - glyph->origin_y;
|
||||
x2 = glyphs[i].x - glyph->origin_x + glyph->image->bits.width;
|
||||
y2 = glyphs[i].y - glyph->origin_y + glyph->image->bits.height;
|
||||
|
||||
if (x1 < extents->x1)
|
||||
extents->x1 = x1;
|
||||
if (y1 < extents->y1)
|
||||
extents->y1 = y1;
|
||||
if (x2 > extents->x2)
|
||||
extents->x2 = x2;
|
||||
if (y2 > extents->y2)
|
||||
extents->y2 = y2;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function returns a format that is suitable for use as a mask for the
|
||||
* set of glyphs in question.
|
||||
*/
|
||||
PIXMAN_EXPORT pixman_format_code_t
|
||||
pixman_glyph_get_mask_format (pixman_glyph_cache_t *cache,
|
||||
int n_glyphs,
|
||||
const pixman_glyph_t *glyphs)
|
||||
{
|
||||
pixman_format_code_t format = PIXMAN_a1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_glyphs; ++i)
|
||||
{
|
||||
const glyph_t *glyph = glyphs[i].glyph;
|
||||
pixman_format_code_t glyph_format = glyph->image->bits.format;
|
||||
|
||||
if (PIXMAN_FORMAT_TYPE (glyph_format) == PIXMAN_TYPE_A)
|
||||
{
|
||||
if (PIXMAN_FORMAT_A (glyph_format) > PIXMAN_FORMAT_A (format))
|
||||
format = glyph_format;
|
||||
}
|
||||
else
|
||||
{
|
||||
return PIXMAN_a8r8g8b8;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
box32_intersect (pixman_box32_t *dest,
|
||||
const pixman_box32_t *box1,
|
||||
const pixman_box32_t *box2)
|
||||
{
|
||||
dest->x1 = MAX (box1->x1, box2->x1);
|
||||
dest->y1 = MAX (box1->y1, box2->y1);
|
||||
dest->x2 = MIN (box1->x2, box2->x2);
|
||||
dest->y2 = MIN (box1->y2, box2->y2);
|
||||
|
||||
return dest->x2 > dest->x1 && dest->y2 > dest->y1;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
|
||||
__attribute__((__force_align_arg_pointer__))
|
||||
#endif
|
||||
PIXMAN_EXPORT void
|
||||
pixman_composite_glyphs_no_mask (pixman_op_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *dest,
|
||||
int32_t src_x,
|
||||
int32_t src_y,
|
||||
int32_t dest_x,
|
||||
int32_t dest_y,
|
||||
pixman_glyph_cache_t *cache,
|
||||
int n_glyphs,
|
||||
const pixman_glyph_t *glyphs)
|
||||
{
|
||||
pixman_region32_t region;
|
||||
pixman_format_code_t glyph_format = PIXMAN_null;
|
||||
uint32_t glyph_flags = 0;
|
||||
pixman_format_code_t dest_format;
|
||||
uint32_t dest_flags;
|
||||
pixman_composite_func_t func = NULL;
|
||||
pixman_implementation_t *implementation = NULL;
|
||||
pixman_composite_info_t info;
|
||||
int i;
|
||||
|
||||
_pixman_image_validate (src);
|
||||
_pixman_image_validate (dest);
|
||||
|
||||
dest_format = dest->common.extended_format_code;
|
||||
dest_flags = dest->common.flags;
|
||||
|
||||
pixman_region32_init (®ion);
|
||||
if (!_pixman_compute_composite_region32 (
|
||||
®ion,
|
||||
src, NULL, dest,
|
||||
src_x - dest_x, src_y - dest_y, 0, 0, 0, 0,
|
||||
dest->bits.width, dest->bits.height))
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
info.op = op;
|
||||
info.src_image = src;
|
||||
info.dest_image = dest;
|
||||
info.src_flags = src->common.flags;
|
||||
info.dest_flags = dest->common.flags;
|
||||
|
||||
for (i = 0; i < n_glyphs; ++i)
|
||||
{
|
||||
glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
|
||||
pixman_image_t *glyph_img = glyph->image;
|
||||
pixman_box32_t glyph_box;
|
||||
pixman_box32_t *pbox;
|
||||
uint32_t extra = FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
|
||||
pixman_box32_t composite_box;
|
||||
int n;
|
||||
|
||||
glyph_box.x1 = dest_x + glyphs[i].x - glyph->origin_x;
|
||||
glyph_box.y1 = dest_y + glyphs[i].y - glyph->origin_y;
|
||||
glyph_box.x2 = glyph_box.x1 + glyph->image->bits.width;
|
||||
glyph_box.y2 = glyph_box.y1 + glyph->image->bits.height;
|
||||
|
||||
pbox = pixman_region32_rectangles (®ion, &n);
|
||||
|
||||
info.mask_image = glyph_img;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if (box32_intersect (&composite_box, pbox, &glyph_box))
|
||||
{
|
||||
if (glyph_img->common.extended_format_code != glyph_format ||
|
||||
glyph_img->common.flags != glyph_flags)
|
||||
{
|
||||
glyph_format = glyph_img->common.extended_format_code;
|
||||
glyph_flags = glyph_img->common.flags;
|
||||
|
||||
_pixman_implementation_lookup_composite (
|
||||
get_implementation(), op,
|
||||
src->common.extended_format_code, src->common.flags,
|
||||
glyph_format, glyph_flags | extra,
|
||||
dest_format, dest_flags,
|
||||
&implementation, &func);
|
||||
}
|
||||
|
||||
info.src_x = src_x + composite_box.x1 - dest_x;
|
||||
info.src_y = src_y + composite_box.y1 - dest_y;
|
||||
info.mask_x = composite_box.x1 - (dest_x + glyphs[i].x - glyph->origin_x);
|
||||
info.mask_y = composite_box.y1 - (dest_y + glyphs[i].y - glyph->origin_y);
|
||||
info.dest_x = composite_box.x1;
|
||||
info.dest_y = composite_box.y1;
|
||||
info.width = composite_box.x2 - composite_box.x1;
|
||||
info.height = composite_box.y2 - composite_box.y1;
|
||||
|
||||
info.mask_flags = glyph_flags;
|
||||
|
||||
func (implementation, &info);
|
||||
}
|
||||
|
||||
pbox++;
|
||||
}
|
||||
pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
|
||||
}
|
||||
|
||||
out:
|
||||
pixman_region32_fini (®ion);
|
||||
}
|
||||
|
||||
static void
|
||||
add_glyphs (pixman_glyph_cache_t *cache,
|
||||
pixman_image_t *dest,
|
||||
int off_x, int off_y,
|
||||
int n_glyphs, const pixman_glyph_t *glyphs)
|
||||
{
|
||||
pixman_format_code_t glyph_format = PIXMAN_null;
|
||||
uint32_t glyph_flags = 0;
|
||||
pixman_composite_func_t func = NULL;
|
||||
pixman_implementation_t *implementation = NULL;
|
||||
pixman_format_code_t dest_format;
|
||||
uint32_t dest_flags;
|
||||
pixman_box32_t dest_box;
|
||||
pixman_composite_info_t info;
|
||||
pixman_image_t *white_img = NULL;
|
||||
pixman_bool_t white_src = FALSE;
|
||||
int i;
|
||||
|
||||
_pixman_image_validate (dest);
|
||||
|
||||
dest_format = dest->common.extended_format_code;
|
||||
dest_flags = dest->common.flags;
|
||||
|
||||
info.op = PIXMAN_OP_ADD;
|
||||
info.dest_image = dest;
|
||||
info.src_x = 0;
|
||||
info.src_y = 0;
|
||||
info.dest_flags = dest_flags;
|
||||
|
||||
dest_box.x1 = 0;
|
||||
dest_box.y1 = 0;
|
||||
dest_box.x2 = dest->bits.width;
|
||||
dest_box.y2 = dest->bits.height;
|
||||
|
||||
for (i = 0; i < n_glyphs; ++i)
|
||||
{
|
||||
glyph_t *glyph = (glyph_t *)glyphs[i].glyph;
|
||||
pixman_image_t *glyph_img = glyph->image;
|
||||
pixman_box32_t glyph_box;
|
||||
pixman_box32_t composite_box;
|
||||
|
||||
if (glyph_img->common.extended_format_code != glyph_format ||
|
||||
glyph_img->common.flags != glyph_flags)
|
||||
{
|
||||
pixman_format_code_t src_format, mask_format;
|
||||
|
||||
glyph_format = glyph_img->common.extended_format_code;
|
||||
glyph_flags = glyph_img->common.flags;
|
||||
|
||||
if (glyph_format == dest->bits.format)
|
||||
{
|
||||
src_format = glyph_format;
|
||||
mask_format = PIXMAN_null;
|
||||
info.src_flags = glyph_flags | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
|
||||
info.mask_flags = FAST_PATH_IS_OPAQUE;
|
||||
info.mask_image = NULL;
|
||||
white_src = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!white_img)
|
||||
{
|
||||
static const pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff };
|
||||
|
||||
if (!(white_img = pixman_image_create_solid_fill (&white)))
|
||||
goto out;
|
||||
|
||||
_pixman_image_validate (white_img);
|
||||
}
|
||||
|
||||
src_format = PIXMAN_solid;
|
||||
mask_format = glyph_format;
|
||||
info.src_flags = white_img->common.flags;
|
||||
info.mask_flags = glyph_flags | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
|
||||
info.src_image = white_img;
|
||||
white_src = TRUE;
|
||||
}
|
||||
|
||||
_pixman_implementation_lookup_composite (
|
||||
get_implementation(), PIXMAN_OP_ADD,
|
||||
src_format, info.src_flags,
|
||||
mask_format, info.mask_flags,
|
||||
dest_format, dest_flags,
|
||||
&implementation, &func);
|
||||
}
|
||||
|
||||
glyph_box.x1 = glyphs[i].x - glyph->origin_x + off_x;
|
||||
glyph_box.y1 = glyphs[i].y - glyph->origin_y + off_y;
|
||||
glyph_box.x2 = glyph_box.x1 + glyph->image->bits.width;
|
||||
glyph_box.y2 = glyph_box.y1 + glyph->image->bits.height;
|
||||
|
||||
if (box32_intersect (&composite_box, &glyph_box, &dest_box))
|
||||
{
|
||||
int src_x = composite_box.x1 - glyph_box.x1;
|
||||
int src_y = composite_box.y1 - glyph_box.y1;
|
||||
|
||||
if (white_src)
|
||||
info.mask_image = glyph_img;
|
||||
else
|
||||
info.src_image = glyph_img;
|
||||
|
||||
info.mask_x = info.src_x = src_x;
|
||||
info.mask_y = info.src_y = src_y;
|
||||
info.dest_x = composite_box.x1;
|
||||
info.dest_y = composite_box.y1;
|
||||
info.width = composite_box.x2 - composite_box.x1;
|
||||
info.height = composite_box.y2 - composite_box.y1;
|
||||
|
||||
func (implementation, &info);
|
||||
|
||||
pixman_list_move_to_front (&cache->mru, &glyph->mru_link);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (white_img)
|
||||
pixman_image_unref (white_img);
|
||||
}
|
||||
|
||||
/* Conceptually, for each glyph, (white IN glyph) is PIXMAN_OP_ADDed to an
|
||||
* infinitely big mask image at the position such that the glyph origin point
|
||||
* is positioned at the (glyphs[i].x, glyphs[i].y) point.
|
||||
*
|
||||
* Then (mask_x, mask_y) in the infinite mask and (src_x, src_y) in the source
|
||||
* image are both aligned with (dest_x, dest_y) in the destination image. Then
|
||||
* these three images are composited within the
|
||||
*
|
||||
* (dest_x, dest_y, dst_x + width, dst_y + height)
|
||||
*
|
||||
* rectangle.
|
||||
*
|
||||
* TODO:
|
||||
* - Trim the mask to the destination clip/image?
|
||||
* - Trim composite region based on sources, when the op ignores 0s.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
|
||||
__attribute__((__force_align_arg_pointer__))
|
||||
#endif
|
||||
PIXMAN_EXPORT void
|
||||
pixman_composite_glyphs (pixman_op_t op,
|
||||
pixman_image_t *src,
|
||||
pixman_image_t *dest,
|
||||
pixman_format_code_t mask_format,
|
||||
int32_t src_x,
|
||||
int32_t src_y,
|
||||
int32_t mask_x,
|
||||
int32_t mask_y,
|
||||
int32_t dest_x,
|
||||
int32_t dest_y,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
pixman_glyph_cache_t *cache,
|
||||
int n_glyphs,
|
||||
const pixman_glyph_t *glyphs)
|
||||
{
|
||||
pixman_image_t *mask;
|
||||
|
||||
if (!(mask = pixman_image_create_bits (mask_format, width, height, NULL, -1)))
|
||||
return;
|
||||
|
||||
if (PIXMAN_FORMAT_A (mask_format) != 0 &&
|
||||
PIXMAN_FORMAT_RGB (mask_format) != 0)
|
||||
{
|
||||
pixman_image_set_component_alpha (mask, TRUE);
|
||||
}
|
||||
|
||||
add_glyphs (cache, mask, - mask_x, - mask_y, n_glyphs, glyphs);
|
||||
|
||||
pixman_image_composite32 (op, src, mask, dest,
|
||||
src_x, src_y,
|
||||
0, 0,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
pixman_image_unref (mask);
|
||||
}
|
264
vendor/pixman/pixman/pixman-gradient-walker.c
vendored
264
vendor/pixman/pixman/pixman-gradient-walker.c
vendored
@ -1,264 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include "pixman-private.h"
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
|
||||
gradient_t * gradient,
|
||||
pixman_repeat_t repeat)
|
||||
{
|
||||
walker->num_stops = gradient->n_stops;
|
||||
walker->stops = gradient->stops;
|
||||
walker->left_x = 0;
|
||||
walker->right_x = 0x10000;
|
||||
walker->a_s = 0.0f;
|
||||
walker->a_b = 0.0f;
|
||||
walker->r_s = 0.0f;
|
||||
walker->r_b = 0.0f;
|
||||
walker->g_s = 0.0f;
|
||||
walker->g_b = 0.0f;
|
||||
walker->b_s = 0.0f;
|
||||
walker->b_b = 0.0f;
|
||||
walker->repeat = repeat;
|
||||
|
||||
walker->need_reset = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t pos)
|
||||
{
|
||||
int64_t x, left_x, right_x;
|
||||
pixman_color_t *left_c, *right_c;
|
||||
int n, count = walker->num_stops;
|
||||
pixman_gradient_stop_t *stops = walker->stops;
|
||||
float la, lr, lg, lb;
|
||||
float ra, rr, rg, rb;
|
||||
float lx, rx;
|
||||
|
||||
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
|
||||
{
|
||||
x = (int32_t)pos & 0xffff;
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
|
||||
{
|
||||
x = (int32_t)pos & 0xffff;
|
||||
if ((int32_t)pos & 0x10000)
|
||||
x = 0x10000 - x;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = pos;
|
||||
}
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
if (x < stops[n].x)
|
||||
break;
|
||||
}
|
||||
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
|
||||
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
|
||||
{
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
|
||||
{
|
||||
if ((int32_t)pos & 0x10000)
|
||||
{
|
||||
pixman_color_t *tmp_c;
|
||||
int32_t tmp_x;
|
||||
|
||||
tmp_x = 0x10000 - right_x;
|
||||
right_x = 0x10000 - left_x;
|
||||
left_x = tmp_x;
|
||||
|
||||
tmp_c = right_c;
|
||||
right_c = left_c;
|
||||
left_c = tmp_c;
|
||||
|
||||
x = 0x10000 - x;
|
||||
}
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (n == 0)
|
||||
right_c = left_c;
|
||||
else if (n == count)
|
||||
left_c = right_c;
|
||||
}
|
||||
|
||||
/* The alpha/red/green/blue channels are scaled to be in [0, 1].
|
||||
* This ensures that after premultiplication all channels will
|
||||
* be in the [0, 1] interval.
|
||||
*/
|
||||
la = (left_c->alpha * (1.0f/257.0f));
|
||||
lr = (left_c->red * (1.0f/257.0f));
|
||||
lg = (left_c->green * (1.0f/257.0f));
|
||||
lb = (left_c->blue * (1.0f/257.0f));
|
||||
|
||||
ra = (right_c->alpha * (1.0f/257.0f));
|
||||
rr = (right_c->red * (1.0f/257.0f));
|
||||
rg = (right_c->green * (1.0f/257.0f));
|
||||
rb = (right_c->blue * (1.0f/257.0f));
|
||||
|
||||
lx = left_x * (1.0f/65536.0f);
|
||||
rx = right_x * (1.0f/65536.0f);
|
||||
|
||||
if (FLOAT_IS_ZERO (rx - lx) || left_x == INT32_MIN || right_x == INT32_MAX)
|
||||
{
|
||||
walker->a_s = walker->r_s = walker->g_s = walker->b_s = 0.0f;
|
||||
walker->a_b = (la + ra) / 510.0f;
|
||||
walker->r_b = (lr + rr) / 510.0f;
|
||||
walker->g_b = (lg + rg) / 510.0f;
|
||||
walker->b_b = (lb + rb) / 510.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float w_rec = 1.0f / (rx - lx);
|
||||
|
||||
walker->a_b = (la * rx - ra * lx) * w_rec * (1.0f/255.0f);
|
||||
walker->r_b = (lr * rx - rr * lx) * w_rec * (1.0f/255.0f);
|
||||
walker->g_b = (lg * rx - rg * lx) * w_rec * (1.0f/255.0f);
|
||||
walker->b_b = (lb * rx - rb * lx) * w_rec * (1.0f/255.0f);
|
||||
|
||||
walker->a_s = (ra - la) * w_rec * (1.0f/255.0f);
|
||||
walker->r_s = (rr - lr) * w_rec * (1.0f/255.0f);
|
||||
walker->g_s = (rg - lg) * w_rec * (1.0f/255.0f);
|
||||
walker->b_s = (rb - lb) * w_rec * (1.0f/255.0f);
|
||||
}
|
||||
|
||||
walker->left_x = left_x;
|
||||
walker->right_x = right_x;
|
||||
|
||||
walker->need_reset = FALSE;
|
||||
}
|
||||
|
||||
static argb_t
|
||||
pixman_gradient_walker_pixel_float (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t x)
|
||||
{
|
||||
argb_t f;
|
||||
float y;
|
||||
|
||||
if (walker->need_reset || x < walker->left_x || x >= walker->right_x)
|
||||
gradient_walker_reset (walker, x);
|
||||
|
||||
y = x * (1.0f / 65536.0f);
|
||||
|
||||
f.a = walker->a_s * y + walker->a_b;
|
||||
f.r = f.a * (walker->r_s * y + walker->r_b);
|
||||
f.g = f.a * (walker->g_s * y + walker->g_b);
|
||||
f.b = f.a * (walker->b_s * y + walker->b_b);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
pixman_gradient_walker_pixel_32 (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t x)
|
||||
{
|
||||
argb_t f;
|
||||
float y;
|
||||
|
||||
if (walker->need_reset || x < walker->left_x || x >= walker->right_x)
|
||||
gradient_walker_reset (walker, x);
|
||||
|
||||
y = x * (1.0f / 65536.0f);
|
||||
|
||||
/* Instead of [0...1] for ARGB, we want [0...255],
|
||||
* multiply alpha with 255 and the color channels
|
||||
* also get multiplied by the alpha multiplier.
|
||||
*
|
||||
* We don't use pixman_contract_from_float because it causes a 2x
|
||||
* slowdown to do so, and the values are already normalized,
|
||||
* so we don't have to worry about values < 0.f or > 1.f
|
||||
*/
|
||||
f.a = 255.f * (walker->a_s * y + walker->a_b);
|
||||
f.r = f.a * (walker->r_s * y + walker->r_b);
|
||||
f.g = f.a * (walker->g_s * y + walker->g_b);
|
||||
f.b = f.a * (walker->b_s * y + walker->b_b);
|
||||
|
||||
return (((uint32_t)(f.a + .5f) << 24) & 0xff000000) |
|
||||
(((uint32_t)(f.r + .5f) << 16) & 0x00ff0000) |
|
||||
(((uint32_t)(f.g + .5f) << 8) & 0x0000ff00) |
|
||||
(((uint32_t)(f.b + .5f) >> 0) & 0x000000ff);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_write_narrow (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t x,
|
||||
uint32_t *buffer)
|
||||
{
|
||||
*buffer = pixman_gradient_walker_pixel_32 (walker, x);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_write_wide (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t x,
|
||||
uint32_t *buffer)
|
||||
{
|
||||
*(argb_t *)buffer = pixman_gradient_walker_pixel_float (walker, x);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_fill_narrow (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t x,
|
||||
uint32_t *buffer,
|
||||
uint32_t *end)
|
||||
{
|
||||
register uint32_t color;
|
||||
|
||||
color = pixman_gradient_walker_pixel_32 (walker, x);
|
||||
while (buffer < end)
|
||||
*buffer++ = color;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_fill_wide (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t x,
|
||||
uint32_t *buffer,
|
||||
uint32_t *end)
|
||||
{
|
||||
register argb_t color;
|
||||
argb_t *buffer_wide = (argb_t *)buffer;
|
||||
argb_t *end_wide = (argb_t *)end;
|
||||
|
||||
color = pixman_gradient_walker_pixel_float (walker, x);
|
||||
while (buffer_wide < end_wide)
|
||||
*buffer_wide++ = color;
|
||||
}
|
994
vendor/pixman/pixman/pixman-image.c
vendored
994
vendor/pixman/pixman/pixman-image.c
vendored
@ -1,994 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
|
||||
|
||||
static void
|
||||
gradient_property_changed (pixman_image_t *image)
|
||||
{
|
||||
gradient_t *gradient = &image->gradient;
|
||||
int n = gradient->n_stops;
|
||||
pixman_gradient_stop_t *stops = gradient->stops;
|
||||
pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
|
||||
pixman_gradient_stop_t *end = &(gradient->stops[n]);
|
||||
|
||||
switch (gradient->common.repeat)
|
||||
{
|
||||
default:
|
||||
case PIXMAN_REPEAT_NONE:
|
||||
begin->x = INT32_MIN;
|
||||
begin->color = transparent_black;
|
||||
end->x = INT32_MAX;
|
||||
end->color = transparent_black;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_NORMAL:
|
||||
begin->x = stops[n - 1].x - pixman_fixed_1;
|
||||
begin->color = stops[n - 1].color;
|
||||
end->x = stops[0].x + pixman_fixed_1;
|
||||
end->color = stops[0].color;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
begin->x = - stops[0].x;
|
||||
begin->color = stops[0].color;
|
||||
end->x = pixman_int_to_fixed (2) - stops[n - 1].x;
|
||||
end->color = stops[n - 1].color;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
begin->x = INT32_MIN;
|
||||
begin->color = stops[0].color;
|
||||
end->x = INT32_MAX;
|
||||
end->color = stops[n - 1].color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_init_gradient (gradient_t * gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
return_val_if_fail (n_stops > 0, FALSE);
|
||||
|
||||
/* We allocate two extra stops, one before the beginning of the stop list,
|
||||
* and one after the end. These stops are initialized to whatever color
|
||||
* would be used for positions outside the range of the stop list.
|
||||
*
|
||||
* This saves a bit of computation in the gradient walker.
|
||||
*
|
||||
* The pointer we store in the gradient_t struct still points to the
|
||||
* first user-supplied struct, so when freeing, we will have to
|
||||
* subtract one.
|
||||
*/
|
||||
gradient->stops =
|
||||
pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
|
||||
if (!gradient->stops)
|
||||
return FALSE;
|
||||
|
||||
gradient->stops += 1;
|
||||
memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
|
||||
gradient->n_stops = n_stops;
|
||||
|
||||
gradient->common.property_changed = gradient_property_changed;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_init (pixman_image_t *image)
|
||||
{
|
||||
image_common_t *common = &image->common;
|
||||
|
||||
pixman_region32_init (&common->clip_region);
|
||||
|
||||
common->alpha_count = 0;
|
||||
common->have_clip_region = FALSE;
|
||||
common->clip_sources = FALSE;
|
||||
common->transform = NULL;
|
||||
common->repeat = PIXMAN_REPEAT_NONE;
|
||||
common->filter = PIXMAN_FILTER_NEAREST;
|
||||
common->filter_params = NULL;
|
||||
common->n_filter_params = 0;
|
||||
common->alpha_map = NULL;
|
||||
common->component_alpha = FALSE;
|
||||
common->ref_count = 1;
|
||||
common->property_changed = NULL;
|
||||
common->client_clip = FALSE;
|
||||
common->destroy_func = NULL;
|
||||
common->destroy_data = NULL;
|
||||
common->dirty = TRUE;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_image_fini (pixman_image_t *image)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
|
||||
common->ref_count--;
|
||||
|
||||
if (common->ref_count == 0)
|
||||
{
|
||||
if (image->common.destroy_func)
|
||||
image->common.destroy_func (image, image->common.destroy_data);
|
||||
|
||||
pixman_region32_fini (&common->clip_region);
|
||||
|
||||
free (common->transform);
|
||||
free (common->filter_params);
|
||||
|
||||
if (common->alpha_map)
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
|
||||
if (image->type == LINEAR ||
|
||||
image->type == RADIAL ||
|
||||
image->type == CONICAL)
|
||||
{
|
||||
if (image->gradient.stops)
|
||||
{
|
||||
/* See _pixman_init_gradient() for an explanation of the - 1 */
|
||||
free (image->gradient.stops - 1);
|
||||
}
|
||||
|
||||
/* This will trigger if someone adds a property_changed
|
||||
* method to the linear/radial/conical gradient overwriting
|
||||
* the general one.
|
||||
*/
|
||||
assert (
|
||||
image->common.property_changed == gradient_property_changed);
|
||||
}
|
||||
|
||||
if (image->type == BITS && image->bits.free_me)
|
||||
free (image->bits.free_me);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixman_image_t *
|
||||
_pixman_image_allocate (void)
|
||||
{
|
||||
pixman_image_t *image = malloc (sizeof (pixman_image_t));
|
||||
|
||||
if (image)
|
||||
_pixman_image_init (image);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static void
|
||||
image_property_changed (pixman_image_t *image)
|
||||
{
|
||||
image->common.dirty = TRUE;
|
||||
}
|
||||
|
||||
/* Ref Counting */
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_ref (pixman_image_t *image)
|
||||
{
|
||||
image->common.ref_count++;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/* returns TRUE when the image is freed */
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_unref (pixman_image_t *image)
|
||||
{
|
||||
if (_pixman_image_fini (image))
|
||||
{
|
||||
free (image);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_destroy_function (pixman_image_t * image,
|
||||
pixman_image_destroy_func_t func,
|
||||
void * data)
|
||||
{
|
||||
image->common.destroy_func = func;
|
||||
image->common.destroy_data = data;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void *
|
||||
pixman_image_get_destroy_data (pixman_image_t *image)
|
||||
{
|
||||
return image->common.destroy_data;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_reset_clip_region (pixman_image_t *image)
|
||||
{
|
||||
image->common.have_clip_region = FALSE;
|
||||
}
|
||||
|
||||
/* Executive Summary: This function is a no-op that only exists
|
||||
* for historical reasons.
|
||||
*
|
||||
* There used to be a bug in the X server where it would rely on
|
||||
* out-of-bounds accesses when it was asked to composite with a
|
||||
* window as the source. It would create a pixman image pointing
|
||||
* to some bogus position in memory, but then set a clip region
|
||||
* to the position where the actual bits were.
|
||||
*
|
||||
* Due to a bug in old versions of pixman, where it would not clip
|
||||
* against the image bounds when a clip region was set, this would
|
||||
* actually work. So when the pixman bug was fixed, a workaround was
|
||||
* added to allow certain out-of-bound accesses. This function disabled
|
||||
* those workarounds.
|
||||
*
|
||||
* Since 0.21.2, pixman doesn't do these workarounds anymore, so now
|
||||
* this function is a no-op.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_disable_out_of_bounds_workaround (void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
compute_image_info (pixman_image_t *image)
|
||||
{
|
||||
pixman_format_code_t code;
|
||||
uint32_t flags = 0;
|
||||
|
||||
/* Transform */
|
||||
if (!image->common.transform)
|
||||
{
|
||||
flags |= (FAST_PATH_ID_TRANSFORM |
|
||||
FAST_PATH_X_UNIT_POSITIVE |
|
||||
FAST_PATH_Y_UNIT_ZERO |
|
||||
FAST_PATH_AFFINE_TRANSFORM);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= FAST_PATH_HAS_TRANSFORM;
|
||||
|
||||
if (image->common.transform->matrix[2][0] == 0 &&
|
||||
image->common.transform->matrix[2][1] == 0 &&
|
||||
image->common.transform->matrix[2][2] == pixman_fixed_1)
|
||||
{
|
||||
flags |= FAST_PATH_AFFINE_TRANSFORM;
|
||||
|
||||
if (image->common.transform->matrix[0][1] == 0 &&
|
||||
image->common.transform->matrix[1][0] == 0)
|
||||
{
|
||||
if (image->common.transform->matrix[0][0] == -pixman_fixed_1 &&
|
||||
image->common.transform->matrix[1][1] == -pixman_fixed_1)
|
||||
{
|
||||
flags |= FAST_PATH_ROTATE_180_TRANSFORM;
|
||||
}
|
||||
flags |= FAST_PATH_SCALE_TRANSFORM;
|
||||
}
|
||||
else if (image->common.transform->matrix[0][0] == 0 &&
|
||||
image->common.transform->matrix[1][1] == 0)
|
||||
{
|
||||
pixman_fixed_t m01 = image->common.transform->matrix[0][1];
|
||||
pixman_fixed_t m10 = image->common.transform->matrix[1][0];
|
||||
|
||||
if (m01 == -pixman_fixed_1 && m10 == pixman_fixed_1)
|
||||
flags |= FAST_PATH_ROTATE_90_TRANSFORM;
|
||||
else if (m01 == pixman_fixed_1 && m10 == -pixman_fixed_1)
|
||||
flags |= FAST_PATH_ROTATE_270_TRANSFORM;
|
||||
}
|
||||
}
|
||||
|
||||
if (image->common.transform->matrix[0][0] > 0)
|
||||
flags |= FAST_PATH_X_UNIT_POSITIVE;
|
||||
|
||||
if (image->common.transform->matrix[1][0] == 0)
|
||||
flags |= FAST_PATH_Y_UNIT_ZERO;
|
||||
}
|
||||
|
||||
/* Filter */
|
||||
switch (image->common.filter)
|
||||
{
|
||||
case PIXMAN_FILTER_NEAREST:
|
||||
case PIXMAN_FILTER_FAST:
|
||||
flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
|
||||
break;
|
||||
|
||||
case PIXMAN_FILTER_BILINEAR:
|
||||
case PIXMAN_FILTER_GOOD:
|
||||
case PIXMAN_FILTER_BEST:
|
||||
flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
|
||||
|
||||
/* Here we have a chance to optimize BILINEAR filter to NEAREST if
|
||||
* they are equivalent for the currently used transformation matrix.
|
||||
*/
|
||||
if (flags & FAST_PATH_ID_TRANSFORM)
|
||||
{
|
||||
flags |= FAST_PATH_NEAREST_FILTER;
|
||||
}
|
||||
else if (flags & FAST_PATH_AFFINE_TRANSFORM)
|
||||
{
|
||||
/* Suppose the transform is
|
||||
*
|
||||
* [ t00, t01, t02 ]
|
||||
* [ t10, t11, t12 ]
|
||||
* [ 0, 0, 1 ]
|
||||
*
|
||||
* and the destination coordinates are (n + 0.5, m + 0.5). Then
|
||||
* the transformed x coordinate is:
|
||||
*
|
||||
* tx = t00 * (n + 0.5) + t01 * (m + 0.5) + t02
|
||||
* = t00 * n + t01 * m + t02 + (t00 + t01) * 0.5
|
||||
*
|
||||
* which implies that if t00, t01 and t02 are all integers
|
||||
* and (t00 + t01) is odd, then tx will be an integer plus 0.5,
|
||||
* which means a BILINEAR filter will reduce to NEAREST. The same
|
||||
* applies in the y direction
|
||||
*/
|
||||
pixman_fixed_t (*t)[3] = image->common.transform->matrix;
|
||||
|
||||
if ((pixman_fixed_frac (
|
||||
t[0][0] | t[0][1] | t[0][2] |
|
||||
t[1][0] | t[1][1] | t[1][2]) == 0) &&
|
||||
(pixman_fixed_to_int (
|
||||
(t[0][0] + t[0][1]) & (t[1][0] + t[1][1])) % 2) == 1)
|
||||
{
|
||||
/* FIXME: there are some affine-test failures, showing that
|
||||
* handling of BILINEAR and NEAREST filter is not quite
|
||||
* equivalent when getting close to 32K for the translation
|
||||
* components of the matrix. That's likely some bug, but for
|
||||
* now just skip BILINEAR->NEAREST optimization in this case.
|
||||
*/
|
||||
pixman_fixed_t magic_limit = pixman_int_to_fixed (30000);
|
||||
if (image->common.transform->matrix[0][2] <= magic_limit &&
|
||||
image->common.transform->matrix[1][2] <= magic_limit &&
|
||||
image->common.transform->matrix[0][2] >= -magic_limit &&
|
||||
image->common.transform->matrix[1][2] >= -magic_limit)
|
||||
{
|
||||
flags |= FAST_PATH_NEAREST_FILTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIXMAN_FILTER_CONVOLUTION:
|
||||
break;
|
||||
|
||||
case PIXMAN_FILTER_SEPARABLE_CONVOLUTION:
|
||||
flags |= FAST_PATH_SEPARABLE_CONVOLUTION_FILTER;
|
||||
break;
|
||||
|
||||
default:
|
||||
flags |= FAST_PATH_NO_CONVOLUTION_FILTER;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Repeat mode */
|
||||
switch (image->common.repeat)
|
||||
{
|
||||
case PIXMAN_REPEAT_NONE:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
flags |=
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT |
|
||||
FAST_PATH_NO_NORMAL_REPEAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
flags |=
|
||||
FAST_PATH_NO_REFLECT_REPEAT |
|
||||
FAST_PATH_NO_PAD_REPEAT |
|
||||
FAST_PATH_NO_NONE_REPEAT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Component alpha */
|
||||
if (image->common.component_alpha)
|
||||
flags |= FAST_PATH_COMPONENT_ALPHA;
|
||||
else
|
||||
flags |= FAST_PATH_UNIFIED_ALPHA;
|
||||
|
||||
flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT);
|
||||
|
||||
/* Type specific checks */
|
||||
switch (image->type)
|
||||
{
|
||||
case SOLID:
|
||||
code = PIXMAN_solid;
|
||||
|
||||
if (image->solid.color.alpha == 0xffff)
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
break;
|
||||
|
||||
case BITS:
|
||||
if (image->bits.width == 1 &&
|
||||
image->bits.height == 1 &&
|
||||
image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
code = PIXMAN_solid;
|
||||
}
|
||||
else
|
||||
{
|
||||
code = image->bits.format;
|
||||
flags |= FAST_PATH_BITS_IMAGE;
|
||||
}
|
||||
|
||||
if (!PIXMAN_FORMAT_A (image->bits.format) &&
|
||||
PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY &&
|
||||
PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR)
|
||||
{
|
||||
flags |= FAST_PATH_SAMPLES_OPAQUE;
|
||||
|
||||
if (image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
}
|
||||
|
||||
if (image->bits.read_func || image->bits.write_func)
|
||||
flags &= ~FAST_PATH_NO_ACCESSORS;
|
||||
|
||||
if (PIXMAN_FORMAT_IS_WIDE (image->bits.format))
|
||||
flags &= ~FAST_PATH_NARROW_FORMAT;
|
||||
break;
|
||||
|
||||
case RADIAL:
|
||||
code = PIXMAN_unknown;
|
||||
|
||||
/*
|
||||
* As explained in pixman-radial-gradient.c, every point of
|
||||
* the plane has a valid associated radius (and thus will be
|
||||
* colored) if and only if a is negative (i.e. one of the two
|
||||
* circles contains the other one).
|
||||
*/
|
||||
|
||||
if (image->radial.a >= 0)
|
||||
break;
|
||||
|
||||
/* Fall through */
|
||||
|
||||
case CONICAL:
|
||||
case LINEAR:
|
||||
code = PIXMAN_unknown;
|
||||
|
||||
if (image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
int i;
|
||||
|
||||
flags |= FAST_PATH_IS_OPAQUE;
|
||||
for (i = 0; i < image->gradient.n_stops; ++i)
|
||||
{
|
||||
if (image->gradient.stops[i].color.alpha != 0xffff)
|
||||
{
|
||||
flags &= ~FAST_PATH_IS_OPAQUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
code = PIXMAN_unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Alpha maps are only supported for BITS images, so it's always
|
||||
* safe to ignore their presense for non-BITS images
|
||||
*/
|
||||
if (!image->common.alpha_map || image->type != BITS)
|
||||
{
|
||||
flags |= FAST_PATH_NO_ALPHA_MAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format))
|
||||
flags &= ~FAST_PATH_NARROW_FORMAT;
|
||||
}
|
||||
|
||||
/* Both alpha maps and convolution filters can introduce
|
||||
* non-opaqueness in otherwise opaque images. Also
|
||||
* an image with component alpha turned on is only opaque
|
||||
* if all channels are opaque, so we simply turn it off
|
||||
* unconditionally for those images.
|
||||
*/
|
||||
if (image->common.alpha_map ||
|
||||
image->common.filter == PIXMAN_FILTER_CONVOLUTION ||
|
||||
image->common.filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION ||
|
||||
image->common.component_alpha)
|
||||
{
|
||||
flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE);
|
||||
}
|
||||
|
||||
image->common.flags = flags;
|
||||
image->common.extended_format_code = code;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_validate (pixman_image_t *image)
|
||||
{
|
||||
if (image->common.dirty)
|
||||
{
|
||||
compute_image_info (image);
|
||||
|
||||
/* It is important that property_changed is
|
||||
* called *after* compute_image_info() because
|
||||
* property_changed() can make use of the flags
|
||||
* to set up accessors etc.
|
||||
*/
|
||||
if (image->common.property_changed)
|
||||
image->common.property_changed (image);
|
||||
|
||||
image->common.dirty = FALSE;
|
||||
}
|
||||
|
||||
if (image->common.alpha_map)
|
||||
_pixman_image_validate ((pixman_image_t *)image->common.alpha_map);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_clip_region32 (pixman_image_t * image,
|
||||
const pixman_region32_t *region)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (region)
|
||||
{
|
||||
if ((result = pixman_region32_copy (&common->clip_region, region)))
|
||||
image->common.have_clip_region = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pixman_image_reset_clip_region (image);
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_clip_region (pixman_image_t * image,
|
||||
const pixman_region16_t *region)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (region)
|
||||
{
|
||||
if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
|
||||
image->common.have_clip_region = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pixman_image_reset_clip_region (image);
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_has_client_clip (pixman_image_t *image,
|
||||
pixman_bool_t client_clip)
|
||||
{
|
||||
image->common.client_clip = client_clip;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_transform (pixman_image_t * image,
|
||||
const pixman_transform_t *transform)
|
||||
{
|
||||
static const pixman_transform_t id =
|
||||
{
|
||||
{ { pixman_fixed_1, 0, 0 },
|
||||
{ 0, pixman_fixed_1, 0 },
|
||||
{ 0, 0, pixman_fixed_1 } }
|
||||
};
|
||||
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_bool_t result;
|
||||
|
||||
if (common->transform == transform)
|
||||
return TRUE;
|
||||
|
||||
if (!transform || memcmp (&id, transform, sizeof (pixman_transform_t)) == 0)
|
||||
{
|
||||
free (common->transform);
|
||||
common->transform = NULL;
|
||||
result = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (common->transform &&
|
||||
memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (common->transform == NULL)
|
||||
common->transform = malloc (sizeof (pixman_transform_t));
|
||||
|
||||
if (common->transform == NULL)
|
||||
{
|
||||
result = FALSE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy (common->transform, transform, sizeof(pixman_transform_t));
|
||||
|
||||
result = TRUE;
|
||||
|
||||
out:
|
||||
image_property_changed (image);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_repeat (pixman_image_t *image,
|
||||
pixman_repeat_t repeat)
|
||||
{
|
||||
if (image->common.repeat == repeat)
|
||||
return;
|
||||
|
||||
image->common.repeat = repeat;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_dither (pixman_image_t *image,
|
||||
pixman_dither_t dither)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
{
|
||||
if (image->bits.dither == dither)
|
||||
return;
|
||||
|
||||
image->bits.dither = dither;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_dither_offset (pixman_image_t *image,
|
||||
int offset_x,
|
||||
int offset_y)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
{
|
||||
if (image->bits.dither_offset_x == offset_x &&
|
||||
image->bits.dither_offset_y == offset_y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
image->bits.dither_offset_x = offset_x;
|
||||
image->bits.dither_offset_y = offset_y;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_set_filter (pixman_image_t * image,
|
||||
pixman_filter_t filter,
|
||||
const pixman_fixed_t *params,
|
||||
int n_params)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
pixman_fixed_t *new_params;
|
||||
|
||||
if (params == common->filter_params && filter == common->filter)
|
||||
return TRUE;
|
||||
|
||||
if (filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION)
|
||||
{
|
||||
int width = pixman_fixed_to_int (params[0]);
|
||||
int height = pixman_fixed_to_int (params[1]);
|
||||
int x_phase_bits = pixman_fixed_to_int (params[2]);
|
||||
int y_phase_bits = pixman_fixed_to_int (params[3]);
|
||||
int n_x_phases = (1 << x_phase_bits);
|
||||
int n_y_phases = (1 << y_phase_bits);
|
||||
|
||||
return_val_if_fail (
|
||||
n_params == 4 + n_x_phases * width + n_y_phases * height, FALSE);
|
||||
}
|
||||
|
||||
new_params = NULL;
|
||||
if (params)
|
||||
{
|
||||
new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
|
||||
if (!new_params)
|
||||
return FALSE;
|
||||
|
||||
memcpy (new_params,
|
||||
params, n_params * sizeof (pixman_fixed_t));
|
||||
}
|
||||
|
||||
common->filter = filter;
|
||||
|
||||
if (common->filter_params)
|
||||
free (common->filter_params);
|
||||
|
||||
common->filter_params = new_params;
|
||||
common->n_filter_params = n_params;
|
||||
|
||||
image_property_changed (image);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_source_clipping (pixman_image_t *image,
|
||||
pixman_bool_t clip_sources)
|
||||
{
|
||||
if (image->common.clip_sources == clip_sources)
|
||||
return;
|
||||
|
||||
image->common.clip_sources = clip_sources;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
/* Unlike all the other property setters, this function does not
|
||||
* copy the content of indexed. Doing this copying is simply
|
||||
* way, way too expensive.
|
||||
*/
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_indexed (pixman_image_t * image,
|
||||
const pixman_indexed_t *indexed)
|
||||
{
|
||||
bits_image_t *bits = (bits_image_t *)image;
|
||||
|
||||
if (bits->indexed == indexed)
|
||||
return;
|
||||
|
||||
bits->indexed = indexed;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_alpha_map (pixman_image_t *image,
|
||||
pixman_image_t *alpha_map,
|
||||
int16_t x,
|
||||
int16_t y)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
|
||||
return_if_fail (!alpha_map || alpha_map->type == BITS);
|
||||
|
||||
if (alpha_map && common->alpha_count > 0)
|
||||
{
|
||||
/* If this image is being used as an alpha map itself,
|
||||
* then you can't give it an alpha map of its own.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (alpha_map && alpha_map->common.alpha_map)
|
||||
{
|
||||
/* If the image has an alpha map of its own,
|
||||
* then it can't be used as an alpha map itself
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (common->alpha_map != (bits_image_t *)alpha_map)
|
||||
{
|
||||
if (common->alpha_map)
|
||||
{
|
||||
common->alpha_map->common.alpha_count--;
|
||||
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
}
|
||||
|
||||
if (alpha_map)
|
||||
{
|
||||
common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map);
|
||||
|
||||
common->alpha_map->common.alpha_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
common->alpha_map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
common->alpha_origin_x = x;
|
||||
common->alpha_origin_y = y;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_component_alpha (pixman_image_t *image,
|
||||
pixman_bool_t component_alpha)
|
||||
{
|
||||
if (image->common.component_alpha == component_alpha)
|
||||
return;
|
||||
|
||||
image->common.component_alpha = component_alpha;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_get_component_alpha (pixman_image_t *image)
|
||||
{
|
||||
return image->common.component_alpha;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
pixman_image_set_accessors (pixman_image_t * image,
|
||||
pixman_read_memory_func_t read_func,
|
||||
pixman_write_memory_func_t write_func)
|
||||
{
|
||||
return_if_fail (image != NULL);
|
||||
|
||||
if (image->type == BITS)
|
||||
{
|
||||
/* Accessors only work for <= 32 bpp. */
|
||||
if (PIXMAN_FORMAT_BPP(image->bits.format) > 32)
|
||||
return_if_fail (!read_func && !write_func);
|
||||
|
||||
image->bits.read_func = read_func;
|
||||
image->bits.write_func = write_func;
|
||||
|
||||
image_property_changed (image);
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT uint32_t *
|
||||
pixman_image_get_data (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.bits;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_width (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.width;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_height (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_stride (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.rowstride * (int) sizeof (uint32_t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT int
|
||||
pixman_image_get_depth (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return PIXMAN_FORMAT_DEPTH (image->bits.format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_format_code_t
|
||||
pixman_image_get_format (pixman_image_t *image)
|
||||
{
|
||||
if (image->type == BITS)
|
||||
return image->bits.format;
|
||||
|
||||
return PIXMAN_null;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
_pixman_image_get_solid (pixman_implementation_t *imp,
|
||||
pixman_image_t * image,
|
||||
pixman_format_code_t format)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
if (image->type == SOLID)
|
||||
{
|
||||
result = image->solid.color_32;
|
||||
}
|
||||
else if (image->type == BITS)
|
||||
{
|
||||
if (image->bits.format == PIXMAN_a8r8g8b8)
|
||||
result = image->bits.bits[0];
|
||||
else if (image->bits.format == PIXMAN_x8r8g8b8)
|
||||
result = image->bits.bits[0] | 0xff000000;
|
||||
else if (image->bits.format == PIXMAN_a8)
|
||||
result = (uint32_t)(*(uint8_t *)image->bits.bits) << 24;
|
||||
else
|
||||
goto otherwise;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixman_iter_t iter;
|
||||
|
||||
otherwise:
|
||||
_pixman_implementation_iter_init (
|
||||
imp, &iter, image, 0, 0, 1, 1,
|
||||
(uint8_t *)&result,
|
||||
ITER_NARROW | ITER_SRC, image->common.flags);
|
||||
|
||||
result = *iter.get_scanline (&iter, NULL);
|
||||
|
||||
if (iter.fini)
|
||||
iter.fini (&iter);
|
||||
}
|
||||
|
||||
/* If necessary, convert RGB <--> BGR. */
|
||||
if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB
|
||||
&& PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB_SRGB)
|
||||
{
|
||||
result = (((result & 0xff000000) >> 0) |
|
||||
((result & 0x00ff0000) >> 16) |
|
||||
((result & 0x0000ff00) >> 0) |
|
||||
((result & 0x000000ff) << 16));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
417
vendor/pixman/pixman/pixman-implementation.c
vendored
417
vendor/pixman/pixman/pixman-implementation.c
vendored
@ -1,417 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2009 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Red Hat not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. Red Hat makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create (pixman_implementation_t *fallback,
|
||||
const pixman_fast_path_t *fast_paths)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
|
||||
assert (fast_paths);
|
||||
|
||||
if ((imp = malloc (sizeof (pixman_implementation_t))))
|
||||
{
|
||||
pixman_implementation_t *d;
|
||||
|
||||
memset (imp, 0, sizeof *imp);
|
||||
|
||||
imp->fallback = fallback;
|
||||
imp->fast_paths = fast_paths;
|
||||
|
||||
/* Make sure the whole fallback chain has the right toplevel */
|
||||
for (d = imp; d != NULL; d = d->fallback)
|
||||
d->toplevel = imp;
|
||||
}
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
||||
#define N_CACHED_FAST_PATHS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
pixman_implementation_t * imp;
|
||||
pixman_fast_path_t fast_path;
|
||||
} cache [N_CACHED_FAST_PATHS];
|
||||
} cache_t;
|
||||
|
||||
PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache)
|
||||
|
||||
static void
|
||||
dummy_composite_rect (pixman_implementation_t *imp,
|
||||
pixman_composite_info_t *info)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_lookup_composite (pixman_implementation_t *toplevel,
|
||||
pixman_op_t op,
|
||||
pixman_format_code_t src_format,
|
||||
uint32_t src_flags,
|
||||
pixman_format_code_t mask_format,
|
||||
uint32_t mask_flags,
|
||||
pixman_format_code_t dest_format,
|
||||
uint32_t dest_flags,
|
||||
pixman_implementation_t **out_imp,
|
||||
pixman_composite_func_t *out_func)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
cache_t *cache;
|
||||
int i;
|
||||
|
||||
/* Check cache for fast paths */
|
||||
cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
|
||||
|
||||
for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
|
||||
{
|
||||
const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
|
||||
|
||||
/* Note that we check for equality here, not whether
|
||||
* the cached fast path matches. This is to prevent
|
||||
* us from selecting an overly general fast path
|
||||
* when a more specific one would work.
|
||||
*/
|
||||
if (info->op == op &&
|
||||
info->src_format == src_format &&
|
||||
info->mask_format == mask_format &&
|
||||
info->dest_format == dest_format &&
|
||||
info->src_flags == src_flags &&
|
||||
info->mask_flags == mask_flags &&
|
||||
info->dest_flags == dest_flags &&
|
||||
info->func)
|
||||
{
|
||||
*out_imp = cache->cache[i].imp;
|
||||
*out_func = cache->cache[i].fast_path.func;
|
||||
|
||||
goto update_cache;
|
||||
}
|
||||
}
|
||||
|
||||
for (imp = toplevel; imp != NULL; imp = imp->fallback)
|
||||
{
|
||||
const pixman_fast_path_t *info = imp->fast_paths;
|
||||
|
||||
while (info->op != PIXMAN_OP_NONE)
|
||||
{
|
||||
if ((info->op == op || info->op == PIXMAN_OP_any) &&
|
||||
/* Formats */
|
||||
((info->src_format == src_format) ||
|
||||
(info->src_format == PIXMAN_any)) &&
|
||||
((info->mask_format == mask_format) ||
|
||||
(info->mask_format == PIXMAN_any)) &&
|
||||
((info->dest_format == dest_format) ||
|
||||
(info->dest_format == PIXMAN_any)) &&
|
||||
/* Flags */
|
||||
(info->src_flags & src_flags) == info->src_flags &&
|
||||
(info->mask_flags & mask_flags) == info->mask_flags &&
|
||||
(info->dest_flags & dest_flags) == info->dest_flags)
|
||||
{
|
||||
*out_imp = imp;
|
||||
*out_func = info->func;
|
||||
|
||||
/* Set i to the last spot in the cache so that the
|
||||
* move-to-front code below will work
|
||||
*/
|
||||
i = N_CACHED_FAST_PATHS - 1;
|
||||
|
||||
goto update_cache;
|
||||
}
|
||||
|
||||
++info;
|
||||
}
|
||||
}
|
||||
|
||||
/* We should never reach this point */
|
||||
_pixman_log_error (
|
||||
FUNC,
|
||||
"No composite function found\n"
|
||||
"\n"
|
||||
"The most likely cause of this is that this system has issues with\n"
|
||||
"thread local storage\n");
|
||||
|
||||
*out_imp = NULL;
|
||||
*out_func = dummy_composite_rect;
|
||||
return;
|
||||
|
||||
update_cache:
|
||||
if (i)
|
||||
{
|
||||
while (i--)
|
||||
cache->cache[i + 1] = cache->cache[i];
|
||||
|
||||
cache->cache[0].imp = *out_imp;
|
||||
cache->cache[0].fast_path.op = op;
|
||||
cache->cache[0].fast_path.src_format = src_format;
|
||||
cache->cache[0].fast_path.src_flags = src_flags;
|
||||
cache->cache[0].fast_path.mask_format = mask_format;
|
||||
cache->cache[0].fast_path.mask_flags = mask_flags;
|
||||
cache->cache[0].fast_path.dest_format = dest_format;
|
||||
cache->cache[0].fast_path.dest_flags = dest_flags;
|
||||
cache->cache[0].fast_path.func = *out_func;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dummy_combine (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * pd,
|
||||
const uint32_t * ps,
|
||||
const uint32_t * pm,
|
||||
int w)
|
||||
{
|
||||
}
|
||||
|
||||
pixman_combine_32_func_t
|
||||
_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
pixman_bool_t component_alpha,
|
||||
pixman_bool_t narrow)
|
||||
{
|
||||
while (imp)
|
||||
{
|
||||
pixman_combine_32_func_t f = NULL;
|
||||
|
||||
switch ((narrow << 1) | component_alpha)
|
||||
{
|
||||
case 0: /* not narrow, not component alpha */
|
||||
f = (pixman_combine_32_func_t)imp->combine_float[op];
|
||||
break;
|
||||
|
||||
case 1: /* not narrow, component_alpha */
|
||||
f = (pixman_combine_32_func_t)imp->combine_float_ca[op];
|
||||
break;
|
||||
|
||||
case 2: /* narrow, not component alpha */
|
||||
f = imp->combine_32[op];
|
||||
break;
|
||||
|
||||
case 3: /* narrow, component_alpha */
|
||||
f = imp->combine_32_ca[op];
|
||||
break;
|
||||
}
|
||||
|
||||
if (f)
|
||||
return f;
|
||||
|
||||
imp = imp->fallback;
|
||||
}
|
||||
|
||||
/* We should never reach this point */
|
||||
_pixman_log_error (FUNC, "No known combine function\n");
|
||||
return dummy_combine;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_blt (pixman_implementation_t * imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
while (imp)
|
||||
{
|
||||
if (imp->blt &&
|
||||
(*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
|
||||
src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
|
||||
width, height))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
imp = imp->fallback;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t filler)
|
||||
{
|
||||
while (imp)
|
||||
{
|
||||
if (imp->fill &&
|
||||
((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler)))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
imp = imp->fallback;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_iter_init (pixman_implementation_t *imp,
|
||||
pixman_iter_t *iter,
|
||||
pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint8_t *buffer,
|
||||
iter_flags_t iter_flags,
|
||||
uint32_t image_flags)
|
||||
{
|
||||
pixman_format_code_t format;
|
||||
|
||||
iter->image = image;
|
||||
iter->buffer = (uint32_t *)buffer;
|
||||
iter->x = x;
|
||||
iter->y = y;
|
||||
iter->width = width;
|
||||
iter->height = height;
|
||||
iter->iter_flags = iter_flags;
|
||||
iter->image_flags = image_flags;
|
||||
iter->fini = NULL;
|
||||
|
||||
if (!iter->image)
|
||||
{
|
||||
iter->get_scanline = get_scanline_null;
|
||||
return;
|
||||
}
|
||||
|
||||
format = iter->image->common.extended_format_code;
|
||||
|
||||
while (imp)
|
||||
{
|
||||
if (imp->iter_info)
|
||||
{
|
||||
const pixman_iter_info_t *info;
|
||||
|
||||
for (info = imp->iter_info; info->format != PIXMAN_null; ++info)
|
||||
{
|
||||
if ((info->format == PIXMAN_any || info->format == format) &&
|
||||
(info->image_flags & image_flags) == info->image_flags &&
|
||||
(info->iter_flags & iter_flags) == info->iter_flags)
|
||||
{
|
||||
iter->get_scanline = info->get_scanline;
|
||||
iter->write_back = info->write_back;
|
||||
|
||||
if (info->initializer)
|
||||
info->initializer (iter, info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
imp = imp->fallback;
|
||||
}
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_disabled (const char *name)
|
||||
{
|
||||
const char *env;
|
||||
|
||||
if ((env = getenv ("PIXMAN_DISABLE")))
|
||||
{
|
||||
do
|
||||
{
|
||||
const char *end;
|
||||
int len;
|
||||
|
||||
if ((end = strchr (env, ' ')))
|
||||
len = end - env;
|
||||
else
|
||||
len = strlen (env);
|
||||
|
||||
if (strlen (name) == len && strncmp (name, env, len) == 0)
|
||||
{
|
||||
printf ("pixman: Disabled %s implementation\n", name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
env += len;
|
||||
}
|
||||
while (*env++);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t empty_fast_path[] =
|
||||
{
|
||||
{ PIXMAN_OP_NONE }
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_choose_implementation (void)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
|
||||
imp = _pixman_implementation_create_general();
|
||||
|
||||
if (!_pixman_disabled ("fast"))
|
||||
imp = _pixman_implementation_create_fast_path (imp);
|
||||
|
||||
imp = _pixman_x86_get_implementations (imp);
|
||||
imp = _pixman_arm_get_implementations (imp);
|
||||
imp = _pixman_ppc_get_implementations (imp);
|
||||
imp = _pixman_mips_get_implementations (imp);
|
||||
|
||||
imp = _pixman_implementation_create_noop (imp);
|
||||
|
||||
if (_pixman_disabled ("wholeops"))
|
||||
{
|
||||
pixman_implementation_t *cur;
|
||||
|
||||
/* Disable all whole-operation paths except the general one,
|
||||
* so that optimized iterators are used as much as possible.
|
||||
*/
|
||||
for (cur = imp; cur->fallback; cur = cur->fallback)
|
||||
cur->fast_paths = empty_fast_path;
|
||||
}
|
||||
|
||||
return imp;
|
||||
}
|
1365
vendor/pixman/pixman/pixman-inlines.h
vendored
1365
vendor/pixman/pixman/pixman-inlines.h
vendored
File diff suppressed because it is too large
Load Diff
292
vendor/pixman/pixman/pixman-linear-gradient.c
vendored
292
vendor/pixman/pixman/pixman-linear-gradient.c
vendored
@ -1,292 +0,0 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static pixman_bool_t
|
||||
linear_gradient_is_horizontal (pixman_image_t *image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
linear_gradient_t *linear = (linear_gradient_t *)image;
|
||||
pixman_vector_t v;
|
||||
pixman_fixed_32_32_t l;
|
||||
pixman_fixed_48_16_t dx, dy;
|
||||
double inc;
|
||||
|
||||
if (image->common.transform)
|
||||
{
|
||||
/* projective transformation */
|
||||
if (image->common.transform->matrix[2][0] != 0 ||
|
||||
image->common.transform->matrix[2][1] != 0 ||
|
||||
image->common.transform->matrix[2][2] == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
v.vector[0] = image->common.transform->matrix[0][1];
|
||||
v.vector[1] = image->common.transform->matrix[1][1];
|
||||
v.vector[2] = image->common.transform->matrix[2][2];
|
||||
}
|
||||
else
|
||||
{
|
||||
v.vector[0] = 0;
|
||||
v.vector[1] = pixman_fixed_1;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
}
|
||||
|
||||
dx = linear->p2.x - linear->p1.x;
|
||||
dy = linear->p2.y - linear->p1.y;
|
||||
|
||||
l = dx * dx + dy * dy;
|
||||
|
||||
if (l == 0)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* compute how much the input of the gradient walked changes
|
||||
* when moving vertically through the whole image
|
||||
*/
|
||||
inc = height * (double) pixman_fixed_1 * pixman_fixed_1 *
|
||||
(dx * v.vector[0] + dy * v.vector[1]) /
|
||||
(v.vector[2] * (double) l);
|
||||
|
||||
/* check that casting to integer would result in 0 */
|
||||
if (-1 < inc && inc < 1)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
linear_get_scanline (pixman_iter_t *iter,
|
||||
const uint32_t *mask,
|
||||
int Bpp,
|
||||
pixman_gradient_walker_write_t write_pixel,
|
||||
pixman_gradient_walker_fill_t fill_pixel)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
int x = iter->x;
|
||||
int y = iter->y;
|
||||
int width = iter->width;
|
||||
uint32_t * buffer = iter->buffer;
|
||||
|
||||
pixman_vector_t v, unit;
|
||||
pixman_fixed_32_32_t l;
|
||||
pixman_fixed_48_16_t dx, dy;
|
||||
gradient_t *gradient = (gradient_t *)image;
|
||||
linear_gradient_t *linear = (linear_gradient_t *)image;
|
||||
uint32_t *end = buffer + width * (Bpp / 4);
|
||||
pixman_gradient_walker_t walker;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
if (image->common.transform)
|
||||
{
|
||||
if (!pixman_transform_point_3d (image->common.transform, &v))
|
||||
return iter->buffer;
|
||||
|
||||
unit.vector[0] = image->common.transform->matrix[0][0];
|
||||
unit.vector[1] = image->common.transform->matrix[1][0];
|
||||
unit.vector[2] = image->common.transform->matrix[2][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
unit.vector[0] = pixman_fixed_1;
|
||||
unit.vector[1] = 0;
|
||||
unit.vector[2] = 0;
|
||||
}
|
||||
|
||||
dx = linear->p2.x - linear->p1.x;
|
||||
dy = linear->p2.y - linear->p1.y;
|
||||
|
||||
l = dx * dx + dy * dy;
|
||||
|
||||
if (l == 0 || unit.vector[2] == 0)
|
||||
{
|
||||
/* affine transformation only */
|
||||
pixman_fixed_32_32_t t, next_inc;
|
||||
double inc;
|
||||
|
||||
if (l == 0 || v.vector[2] == 0)
|
||||
{
|
||||
t = 0;
|
||||
inc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double invden, v2;
|
||||
|
||||
invden = pixman_fixed_1 * (double) pixman_fixed_1 /
|
||||
(l * (double) v.vector[2]);
|
||||
v2 = v.vector[2] * (1. / pixman_fixed_1);
|
||||
t = ((dx * v.vector[0] + dy * v.vector[1]) -
|
||||
(dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
|
||||
inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden;
|
||||
}
|
||||
next_inc = 0;
|
||||
|
||||
if (((pixman_fixed_32_32_t )(inc * width)) == 0)
|
||||
{
|
||||
fill_pixel (&walker, t, buffer, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
write_pixel (&walker, t + next_inc, buffer);
|
||||
}
|
||||
i++;
|
||||
next_inc = inc * i;
|
||||
buffer += (Bpp / 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* projective transformation */
|
||||
double t;
|
||||
|
||||
t = 0;
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
if (v.vector[2] != 0)
|
||||
{
|
||||
double invden, v2;
|
||||
|
||||
invden = pixman_fixed_1 * (double) pixman_fixed_1 /
|
||||
(l * (double) v.vector[2]);
|
||||
v2 = v.vector[2] * (1. / pixman_fixed_1);
|
||||
t = ((dx * v.vector[0] + dy * v.vector[1]) -
|
||||
(dx * linear->p1.x + dy * linear->p1.y) * v2) * invden;
|
||||
}
|
||||
|
||||
write_pixel (&walker, t, buffer);
|
||||
}
|
||||
|
||||
buffer += (Bpp / 4);
|
||||
|
||||
v.vector[0] += unit.vector[0];
|
||||
v.vector[1] += unit.vector[1];
|
||||
v.vector[2] += unit.vector[2];
|
||||
}
|
||||
}
|
||||
|
||||
iter->y++;
|
||||
|
||||
return iter->buffer;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
linear_get_scanline_narrow (pixman_iter_t *iter,
|
||||
const uint32_t *mask)
|
||||
{
|
||||
return linear_get_scanline (iter, mask, 4,
|
||||
_pixman_gradient_walker_write_narrow,
|
||||
_pixman_gradient_walker_fill_narrow);
|
||||
}
|
||||
|
||||
|
||||
static uint32_t *
|
||||
linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return linear_get_scanline (iter, NULL, 16,
|
||||
_pixman_gradient_walker_write_wide,
|
||||
_pixman_gradient_walker_fill_wide);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
||||
{
|
||||
if (linear_gradient_is_horizontal (
|
||||
iter->image, iter->x, iter->y, iter->width, iter->height))
|
||||
{
|
||||
if (iter->iter_flags & ITER_NARROW)
|
||||
linear_get_scanline_narrow (iter, NULL);
|
||||
else
|
||||
linear_get_scanline_wide (iter, NULL);
|
||||
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iter->iter_flags & ITER_NARROW)
|
||||
iter->get_scanline = linear_get_scanline_narrow;
|
||||
else
|
||||
iter->get_scanline = linear_get_scanline_wide;
|
||||
}
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_linear_gradient (const pixman_point_fixed_t * p1,
|
||||
const pixman_point_fixed_t * p2,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
linear_gradient_t *linear;
|
||||
|
||||
image = _pixman_image_allocate ();
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
linear = &image->linear;
|
||||
|
||||
if (!_pixman_init_gradient (&linear->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
linear->p1 = *p1;
|
||||
linear->p2 = *p2;
|
||||
|
||||
image->type = LINEAR;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
1073
vendor/pixman/pixman/pixman-matrix.c
vendored
1073
vendor/pixman/pixman/pixman-matrix.c
vendored
File diff suppressed because it is too large
Load Diff
4283
vendor/pixman/pixman/pixman-mips-dspr2-asm.S
vendored
4283
vendor/pixman/pixman/pixman-mips-dspr2-asm.S
vendored
File diff suppressed because it is too large
Load Diff
711
vendor/pixman/pixman/pixman-mips-dspr2-asm.h
vendored
711
vendor/pixman/pixman/pixman-mips-dspr2-asm.h
vendored
@ -1,711 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_MIPS_DSPR2_ASM_H
|
||||
#define PIXMAN_MIPS_DSPR2_ASM_H
|
||||
|
||||
#define zero $0
|
||||
#define AT $1
|
||||
#define v0 $2
|
||||
#define v1 $3
|
||||
#define a0 $4
|
||||
#define a1 $5
|
||||
#define a2 $6
|
||||
#define a3 $7
|
||||
#define t0 $8
|
||||
#define t1 $9
|
||||
#define t2 $10
|
||||
#define t3 $11
|
||||
#define t4 $12
|
||||
#define t5 $13
|
||||
#define t6 $14
|
||||
#define t7 $15
|
||||
#define s0 $16
|
||||
#define s1 $17
|
||||
#define s2 $18
|
||||
#define s3 $19
|
||||
#define s4 $20
|
||||
#define s5 $21
|
||||
#define s6 $22
|
||||
#define s7 $23
|
||||
#define t8 $24
|
||||
#define t9 $25
|
||||
#define k0 $26
|
||||
#define k1 $27
|
||||
#define gp $28
|
||||
#define sp $29
|
||||
#define fp $30
|
||||
#define s8 $30
|
||||
#define ra $31
|
||||
|
||||
/*
|
||||
* LEAF_MIPS32R2 - declare leaf routine for MIPS32r2
|
||||
*/
|
||||
#define LEAF_MIPS32R2(symbol) \
|
||||
.globl symbol; \
|
||||
.align 2; \
|
||||
.hidden symbol; \
|
||||
.type symbol, @function; \
|
||||
.ent symbol, 0; \
|
||||
symbol: .frame sp, 0, ra; \
|
||||
.set push; \
|
||||
.set arch=mips32r2; \
|
||||
.set noreorder; \
|
||||
.set noat;
|
||||
|
||||
/*
|
||||
* LEAF_MIPS32R2 - declare leaf routine for MIPS DSPr2
|
||||
*/
|
||||
#define LEAF_MIPS_DSPR2(symbol) \
|
||||
LEAF_MIPS32R2(symbol) \
|
||||
.set dspr2;
|
||||
|
||||
/*
|
||||
* END - mark end of function
|
||||
*/
|
||||
#define END(function) \
|
||||
.set pop; \
|
||||
.end function; \
|
||||
.size function,.-function
|
||||
|
||||
/*
|
||||
* Checks if stack offset is big enough for storing/restoring regs_num
|
||||
* number of register to/from stack. Stack offset must be greater than
|
||||
* or equal to the number of bytes needed for storing registers (regs_num*4).
|
||||
* Since MIPS ABI allows usage of first 16 bytes of stack frame (this is
|
||||
* preserved for input arguments of the functions, already stored in a0-a3),
|
||||
* stack size can be further optimized by utilizing this space.
|
||||
*/
|
||||
.macro CHECK_STACK_OFFSET regs_num, stack_offset
|
||||
.if \stack_offset < \regs_num * 4 - 16
|
||||
.error "Stack offset too small."
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Saves set of registers on stack. Maximum number of registers that
|
||||
* can be saved on stack is limitted to 14 (a0-a3, v0-v1 and s0-s7).
|
||||
* Stack offset is number of bytes that are added to stack pointer (sp)
|
||||
* before registers are pushed in order to provide enough space on stack
|
||||
* (offset must be multiple of 4, and must be big enough, as described by
|
||||
* CHECK_STACK_OFFSET macro). This macro is intended to be used in
|
||||
* combination with RESTORE_REGS_FROM_STACK macro. Example:
|
||||
* SAVE_REGS_ON_STACK 4, v0, v1, s0, s1
|
||||
* RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
|
||||
*/
|
||||
.macro SAVE_REGS_ON_STACK stack_offset = 0, r1, \
|
||||
r2 = 0, r3 = 0, r4 = 0, \
|
||||
r5 = 0, r6 = 0, r7 = 0, \
|
||||
r8 = 0, r9 = 0, r10 = 0, \
|
||||
r11 = 0, r12 = 0, r13 = 0, \
|
||||
r14 = 0
|
||||
.if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4)
|
||||
.error "Stack offset must be pozitive and multiple of 4."
|
||||
.endif
|
||||
.if \stack_offset != 0
|
||||
addiu sp, sp, -\stack_offset
|
||||
.endif
|
||||
sw \r1, 0(sp)
|
||||
.if \r2 != 0
|
||||
sw \r2, 4(sp)
|
||||
.endif
|
||||
.if \r3 != 0
|
||||
sw \r3, 8(sp)
|
||||
.endif
|
||||
.if \r4 != 0
|
||||
sw \r4, 12(sp)
|
||||
.endif
|
||||
.if \r5 != 0
|
||||
CHECK_STACK_OFFSET 5, \stack_offset
|
||||
sw \r5, 16(sp)
|
||||
.endif
|
||||
.if \r6 != 0
|
||||
CHECK_STACK_OFFSET 6, \stack_offset
|
||||
sw \r6, 20(sp)
|
||||
.endif
|
||||
.if \r7 != 0
|
||||
CHECK_STACK_OFFSET 7, \stack_offset
|
||||
sw \r7, 24(sp)
|
||||
.endif
|
||||
.if \r8 != 0
|
||||
CHECK_STACK_OFFSET 8, \stack_offset
|
||||
sw \r8, 28(sp)
|
||||
.endif
|
||||
.if \r9 != 0
|
||||
CHECK_STACK_OFFSET 9, \stack_offset
|
||||
sw \r9, 32(sp)
|
||||
.endif
|
||||
.if \r10 != 0
|
||||
CHECK_STACK_OFFSET 10, \stack_offset
|
||||
sw \r10, 36(sp)
|
||||
.endif
|
||||
.if \r11 != 0
|
||||
CHECK_STACK_OFFSET 11, \stack_offset
|
||||
sw \r11, 40(sp)
|
||||
.endif
|
||||
.if \r12 != 0
|
||||
CHECK_STACK_OFFSET 12, \stack_offset
|
||||
sw \r12, 44(sp)
|
||||
.endif
|
||||
.if \r13 != 0
|
||||
CHECK_STACK_OFFSET 13, \stack_offset
|
||||
sw \r13, 48(sp)
|
||||
.endif
|
||||
.if \r14 != 0
|
||||
CHECK_STACK_OFFSET 14, \stack_offset
|
||||
sw \r14, 52(sp)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Restores set of registers from stack. Maximum number of registers that
|
||||
* can be restored from stack is limitted to 14 (a0-a3, v0-v1 and s0-s7).
|
||||
* Stack offset is number of bytes that are added to stack pointer (sp)
|
||||
* after registers are restored (offset must be multiple of 4, and must
|
||||
* be big enough, as described by CHECK_STACK_OFFSET macro). This macro is
|
||||
* intended to be used in combination with RESTORE_REGS_FROM_STACK macro.
|
||||
* Example:
|
||||
* SAVE_REGS_ON_STACK 4, v0, v1, s0, s1
|
||||
* RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1
|
||||
*/
|
||||
.macro RESTORE_REGS_FROM_STACK stack_offset = 0, r1, \
|
||||
r2 = 0, r3 = 0, r4 = 0, \
|
||||
r5 = 0, r6 = 0, r7 = 0, \
|
||||
r8 = 0, r9 = 0, r10 = 0, \
|
||||
r11 = 0, r12 = 0, r13 = 0, \
|
||||
r14 = 0
|
||||
.if (\stack_offset < 0) || (\stack_offset - (\stack_offset/4)*4)
|
||||
.error "Stack offset must be pozitive and multiple of 4."
|
||||
.endif
|
||||
lw \r1, 0(sp)
|
||||
.if \r2 != 0
|
||||
lw \r2, 4(sp)
|
||||
.endif
|
||||
.if \r3 != 0
|
||||
lw \r3, 8(sp)
|
||||
.endif
|
||||
.if \r4 != 0
|
||||
lw \r4, 12(sp)
|
||||
.endif
|
||||
.if \r5 != 0
|
||||
CHECK_STACK_OFFSET 5, \stack_offset
|
||||
lw \r5, 16(sp)
|
||||
.endif
|
||||
.if \r6 != 0
|
||||
CHECK_STACK_OFFSET 6, \stack_offset
|
||||
lw \r6, 20(sp)
|
||||
.endif
|
||||
.if \r7 != 0
|
||||
CHECK_STACK_OFFSET 7, \stack_offset
|
||||
lw \r7, 24(sp)
|
||||
.endif
|
||||
.if \r8 != 0
|
||||
CHECK_STACK_OFFSET 8, \stack_offset
|
||||
lw \r8, 28(sp)
|
||||
.endif
|
||||
.if \r9 != 0
|
||||
CHECK_STACK_OFFSET 9, \stack_offset
|
||||
lw \r9, 32(sp)
|
||||
.endif
|
||||
.if \r10 != 0
|
||||
CHECK_STACK_OFFSET 10, \stack_offset
|
||||
lw \r10, 36(sp)
|
||||
.endif
|
||||
.if \r11 != 0
|
||||
CHECK_STACK_OFFSET 11, \stack_offset
|
||||
lw \r11, 40(sp)
|
||||
.endif
|
||||
.if \r12 != 0
|
||||
CHECK_STACK_OFFSET 12, \stack_offset
|
||||
lw \r12, 44(sp)
|
||||
.endif
|
||||
.if \r13 != 0
|
||||
CHECK_STACK_OFFSET 13, \stack_offset
|
||||
lw \r13, 48(sp)
|
||||
.endif
|
||||
.if \r14 != 0
|
||||
CHECK_STACK_OFFSET 14, \stack_offset
|
||||
lw \r14, 52(sp)
|
||||
.endif
|
||||
.if \stack_offset != 0
|
||||
addiu sp, sp, \stack_offset
|
||||
.endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Conversion of single r5g6b5 pixel (in_565) to single a8r8g8b8 pixel
|
||||
* returned in (out_8888) register. Requires two temporary registers
|
||||
* (scratch1 and scratch2).
|
||||
*/
|
||||
.macro CONVERT_1x0565_TO_1x8888 in_565, \
|
||||
out_8888, \
|
||||
scratch1, scratch2
|
||||
lui \out_8888, 0xff00
|
||||
sll \scratch1, \in_565, 0x3
|
||||
andi \scratch2, \scratch1, 0xff
|
||||
ext \scratch1, \in_565, 0x2, 0x3
|
||||
or \scratch1, \scratch2, \scratch1
|
||||
or \out_8888, \out_8888, \scratch1
|
||||
|
||||
sll \scratch1, \in_565, 0x5
|
||||
andi \scratch1, \scratch1, 0xfc00
|
||||
srl \scratch2, \in_565, 0x1
|
||||
andi \scratch2, \scratch2, 0x300
|
||||
or \scratch2, \scratch1, \scratch2
|
||||
or \out_8888, \out_8888, \scratch2
|
||||
|
||||
andi \scratch1, \in_565, 0xf800
|
||||
srl \scratch2, \scratch1, 0x5
|
||||
andi \scratch2, \scratch2, 0xff00
|
||||
or \scratch1, \scratch1, \scratch2
|
||||
sll \scratch1, \scratch1, 0x8
|
||||
or \out_8888, \out_8888, \scratch1
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Conversion of two r5g6b5 pixels (in1_565 and in2_565) to two a8r8g8b8 pixels
|
||||
* returned in (out1_8888 and out2_8888) registers. Requires four scratch
|
||||
* registers (scratch1 ... scratch4). It also requires maskG and maskB for
|
||||
* color component extractions. These masks must have following values:
|
||||
* li maskG, 0x07e007e0
|
||||
* li maskB, 0x001F001F
|
||||
*/
|
||||
.macro CONVERT_2x0565_TO_2x8888 in1_565, in2_565, \
|
||||
out1_8888, out2_8888, \
|
||||
maskG, maskB, \
|
||||
scratch1, scratch2, scratch3, scratch4
|
||||
sll \scratch1, \in1_565, 16
|
||||
or \scratch1, \scratch1, \in2_565
|
||||
lui \out2_8888, 0xff00
|
||||
ori \out2_8888, \out2_8888, 0xff00
|
||||
shrl.ph \scratch2, \scratch1, 11
|
||||
and \scratch3, \scratch1, \maskG
|
||||
shra.ph \scratch4, \scratch2, 2
|
||||
shll.ph \scratch2, \scratch2, 3
|
||||
shll.ph \scratch3, \scratch3, 5
|
||||
or \scratch2, \scratch2, \scratch4
|
||||
shrl.qb \scratch4, \scratch3, 6
|
||||
or \out2_8888, \out2_8888, \scratch2
|
||||
or \scratch3, \scratch3, \scratch4
|
||||
and \scratch1, \scratch1, \maskB
|
||||
shll.ph \scratch2, \scratch1, 3
|
||||
shra.ph \scratch4, \scratch1, 2
|
||||
or \scratch2, \scratch2, \scratch4
|
||||
or \scratch3, \scratch2, \scratch3
|
||||
precrq.ph.w \out1_8888, \out2_8888, \scratch3
|
||||
precr_sra.ph.w \out2_8888, \scratch3, 0
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Conversion of single a8r8g8b8 pixel (in_8888) to single r5g6b5 pixel
|
||||
* returned in (out_565) register. Requires two temporary registers
|
||||
* (scratch1 and scratch2).
|
||||
*/
|
||||
.macro CONVERT_1x8888_TO_1x0565 in_8888, \
|
||||
out_565, \
|
||||
scratch1, scratch2
|
||||
ext \out_565, \in_8888, 0x3, 0x5
|
||||
srl \scratch1, \in_8888, 0x5
|
||||
andi \scratch1, \scratch1, 0x07e0
|
||||
srl \scratch2, \in_8888, 0x8
|
||||
andi \scratch2, \scratch2, 0xf800
|
||||
or \out_565, \out_565, \scratch1
|
||||
or \out_565, \out_565, \scratch2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Conversion of two a8r8g8b8 pixels (in1_8888 and in2_8888) to two r5g6b5
|
||||
* pixels returned in (out1_565 and out2_565) registers. Requires two temporary
|
||||
* registers (scratch1 and scratch2). It also requires maskR, maskG and maskB
|
||||
* for color component extractions. These masks must have following values:
|
||||
* li maskR, 0xf800f800
|
||||
* li maskG, 0x07e007e0
|
||||
* li maskB, 0x001F001F
|
||||
* Value of input register in2_8888 is lost.
|
||||
*/
|
||||
.macro CONVERT_2x8888_TO_2x0565 in1_8888, in2_8888, \
|
||||
out1_565, out2_565, \
|
||||
maskR, maskG, maskB, \
|
||||
scratch1, scratch2
|
||||
precr.qb.ph \scratch1, \in2_8888, \in1_8888
|
||||
precrq.qb.ph \in2_8888, \in2_8888, \in1_8888
|
||||
and \out1_565, \scratch1, \maskR
|
||||
shrl.ph \scratch1, \scratch1, 3
|
||||
shll.ph \in2_8888, \in2_8888, 3
|
||||
and \scratch1, \scratch1, \maskB
|
||||
or \out1_565, \out1_565, \scratch1
|
||||
and \in2_8888, \in2_8888, \maskG
|
||||
or \out1_565, \out1_565, \in2_8888
|
||||
srl \out2_565, \out1_565, 16
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Multiply pixel (a8) with single pixel (a8r8g8b8). It requires maskLSR needed
|
||||
* for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro MIPS_UN8x4_MUL_UN8 s_8888, \
|
||||
m_8, \
|
||||
d_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3
|
||||
replv.ph \m_8, \m_8 /* 0 | M | 0 | M */
|
||||
muleu_s.ph.qbl \scratch1, \s_8888, \m_8 /* A*M | R*M */
|
||||
muleu_s.ph.qbr \scratch2, \s_8888, \m_8 /* G*M | B*M */
|
||||
shra_r.ph \scratch3, \scratch1, 8
|
||||
shra_r.ph \d_8888, \scratch2, 8
|
||||
and \scratch3, \scratch3, \maskLSR /* 0 |A*M| 0 |R*M */
|
||||
and \d_8888, \d_8888, \maskLSR /* 0 |G*M| 0 |B*M */
|
||||
addq.ph \scratch1, \scratch1, \scratch3 /* A*M+A*M | R*M+R*M */
|
||||
addq.ph \scratch2, \scratch2, \d_8888 /* G*M+G*M | B*M+B*M */
|
||||
shra_r.ph \scratch1, \scratch1, 8
|
||||
shra_r.ph \scratch2, \scratch2, 8
|
||||
precr.qb.ph \d_8888, \scratch1, \scratch2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Multiply two pixels (a8) with two pixels (a8r8g8b8). It requires maskLSR
|
||||
* needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro MIPS_2xUN8x4_MUL_2xUN8 s1_8888, \
|
||||
s2_8888, \
|
||||
m1_8, \
|
||||
m2_8, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
replv.ph \m1_8, \m1_8 /* 0 | M1 | 0 | M1 */
|
||||
replv.ph \m2_8, \m2_8 /* 0 | M2 | 0 | M2 */
|
||||
muleu_s.ph.qbl \scratch1, \s1_8888, \m1_8 /* A1*M1 | R1*M1 */
|
||||
muleu_s.ph.qbr \scratch2, \s1_8888, \m1_8 /* G1*M1 | B1*M1 */
|
||||
muleu_s.ph.qbl \scratch3, \s2_8888, \m2_8 /* A2*M2 | R2*M2 */
|
||||
muleu_s.ph.qbr \scratch4, \s2_8888, \m2_8 /* G2*M2 | B2*M2 */
|
||||
shra_r.ph \scratch5, \scratch1, 8
|
||||
shra_r.ph \d1_8888, \scratch2, 8
|
||||
shra_r.ph \scratch6, \scratch3, 8
|
||||
shra_r.ph \d2_8888, \scratch4, 8
|
||||
and \scratch5, \scratch5, \maskLSR /* 0 |A1*M1| 0 |R1*M1 */
|
||||
and \d1_8888, \d1_8888, \maskLSR /* 0 |G1*M1| 0 |B1*M1 */
|
||||
and \scratch6, \scratch6, \maskLSR /* 0 |A2*M2| 0 |R2*M2 */
|
||||
and \d2_8888, \d2_8888, \maskLSR /* 0 |G2*M2| 0 |B2*M2 */
|
||||
addq.ph \scratch1, \scratch1, \scratch5
|
||||
addq.ph \scratch2, \scratch2, \d1_8888
|
||||
addq.ph \scratch3, \scratch3, \scratch6
|
||||
addq.ph \scratch4, \scratch4, \d2_8888
|
||||
shra_r.ph \scratch1, \scratch1, 8
|
||||
shra_r.ph \scratch2, \scratch2, 8
|
||||
shra_r.ph \scratch3, \scratch3, 8
|
||||
shra_r.ph \scratch4, \scratch4, 8
|
||||
precr.qb.ph \d1_8888, \scratch1, \scratch2
|
||||
precr.qb.ph \d2_8888, \scratch3, \scratch4
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Multiply pixel (a8r8g8b8) with single pixel (a8r8g8b8). It requires maskLSR
|
||||
* needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro MIPS_UN8x4_MUL_UN8x4 s_8888, \
|
||||
m_8888, \
|
||||
d_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, scratch4
|
||||
preceu.ph.qbl \scratch1, \m_8888 /* 0 | A | 0 | R */
|
||||
preceu.ph.qbr \scratch2, \m_8888 /* 0 | G | 0 | B */
|
||||
muleu_s.ph.qbl \scratch3, \s_8888, \scratch1 /* A*A | R*R */
|
||||
muleu_s.ph.qbr \scratch4, \s_8888, \scratch2 /* G*G | B*B */
|
||||
shra_r.ph \scratch1, \scratch3, 8
|
||||
shra_r.ph \scratch2, \scratch4, 8
|
||||
and \scratch1, \scratch1, \maskLSR /* 0 |A*A| 0 |R*R */
|
||||
and \scratch2, \scratch2, \maskLSR /* 0 |G*G| 0 |B*B */
|
||||
addq.ph \scratch1, \scratch1, \scratch3
|
||||
addq.ph \scratch2, \scratch2, \scratch4
|
||||
shra_r.ph \scratch1, \scratch1, 8
|
||||
shra_r.ph \scratch2, \scratch2, 8
|
||||
precr.qb.ph \d_8888, \scratch1, \scratch2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Multiply two pixels (a8r8g8b8) with two pixels (a8r8g8b8). It requires
|
||||
* maskLSR needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
|
||||
.macro MIPS_2xUN8x4_MUL_2xUN8x4 s1_8888, \
|
||||
s2_8888, \
|
||||
m1_8888, \
|
||||
m2_8888, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
preceu.ph.qbl \scratch1, \m1_8888 /* 0 | A | 0 | R */
|
||||
preceu.ph.qbr \scratch2, \m1_8888 /* 0 | G | 0 | B */
|
||||
preceu.ph.qbl \scratch3, \m2_8888 /* 0 | A | 0 | R */
|
||||
preceu.ph.qbr \scratch4, \m2_8888 /* 0 | G | 0 | B */
|
||||
muleu_s.ph.qbl \scratch5, \s1_8888, \scratch1 /* A*A | R*R */
|
||||
muleu_s.ph.qbr \scratch6, \s1_8888, \scratch2 /* G*G | B*B */
|
||||
muleu_s.ph.qbl \scratch1, \s2_8888, \scratch3 /* A*A | R*R */
|
||||
muleu_s.ph.qbr \scratch2, \s2_8888, \scratch4 /* G*G | B*B */
|
||||
shra_r.ph \scratch3, \scratch5, 8
|
||||
shra_r.ph \scratch4, \scratch6, 8
|
||||
shra_r.ph \d1_8888, \scratch1, 8
|
||||
shra_r.ph \d2_8888, \scratch2, 8
|
||||
and \scratch3, \scratch3, \maskLSR /* 0 |A*A| 0 |R*R */
|
||||
and \scratch4, \scratch4, \maskLSR /* 0 |G*G| 0 |B*B */
|
||||
and \d1_8888, \d1_8888, \maskLSR /* 0 |A*A| 0 |R*R */
|
||||
and \d2_8888, \d2_8888, \maskLSR /* 0 |G*G| 0 |B*B */
|
||||
addq.ph \scratch3, \scratch3, \scratch5
|
||||
addq.ph \scratch4, \scratch4, \scratch6
|
||||
addq.ph \d1_8888, \d1_8888, \scratch1
|
||||
addq.ph \d2_8888, \d2_8888, \scratch2
|
||||
shra_r.ph \scratch3, \scratch3, 8
|
||||
shra_r.ph \scratch4, \scratch4, 8
|
||||
shra_r.ph \scratch5, \d1_8888, 8
|
||||
shra_r.ph \scratch6, \d2_8888, 8
|
||||
precr.qb.ph \d1_8888, \scratch3, \scratch4
|
||||
precr.qb.ph \d2_8888, \scratch5, \scratch6
|
||||
.endm
|
||||
|
||||
/*
|
||||
* OVER operation on single a8r8g8b8 source pixel (s_8888) and single a8r8g8b8
|
||||
* destination pixel (d_8888) using a8 mask (m_8). It also requires maskLSR
|
||||
* needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro OVER_8888_8_8888 s_8888, \
|
||||
m_8, \
|
||||
d_8888, \
|
||||
out_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, scratch4
|
||||
MIPS_UN8x4_MUL_UN8 \s_8888, \m_8, \
|
||||
\scratch1, \maskLSR, \
|
||||
\scratch2, \scratch3, \scratch4
|
||||
|
||||
not \scratch2, \scratch1
|
||||
srl \scratch2, \scratch2, 24
|
||||
|
||||
MIPS_UN8x4_MUL_UN8 \d_8888, \scratch2, \
|
||||
\d_8888, \maskLSR, \
|
||||
\scratch3, \scratch4, \out_8888
|
||||
|
||||
addu_s.qb \out_8888, \d_8888, \scratch1
|
||||
.endm
|
||||
|
||||
/*
|
||||
* OVER operation on two a8r8g8b8 source pixels (s1_8888 and s2_8888) and two
|
||||
* a8r8g8b8 destination pixels (d1_8888 and d2_8888) using a8 masks (m1_8 and
|
||||
* m2_8). It also requires maskLSR needed for rounding process. maskLSR must
|
||||
* have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro OVER_2x8888_2x8_2x8888 s1_8888, \
|
||||
s2_8888, \
|
||||
m1_8, \
|
||||
m2_8, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
out1_8888, \
|
||||
out2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
MIPS_2xUN8x4_MUL_2xUN8 \s1_8888, \s2_8888, \
|
||||
\m1_8, \m2_8, \
|
||||
\scratch1, \scratch2, \
|
||||
\maskLSR, \
|
||||
\scratch3, \scratch4, \out1_8888, \
|
||||
\out2_8888, \scratch5, \scratch6
|
||||
|
||||
not \scratch3, \scratch1
|
||||
srl \scratch3, \scratch3, 24
|
||||
not \scratch4, \scratch2
|
||||
srl \scratch4, \scratch4, 24
|
||||
|
||||
MIPS_2xUN8x4_MUL_2xUN8 \d1_8888, \d2_8888, \
|
||||
\scratch3, \scratch4, \
|
||||
\d1_8888, \d2_8888, \
|
||||
\maskLSR, \
|
||||
\scratch5, \scratch6, \out1_8888, \
|
||||
\out2_8888, \scratch3, \scratch4
|
||||
|
||||
addu_s.qb \out1_8888, \d1_8888, \scratch1
|
||||
addu_s.qb \out2_8888, \d2_8888, \scratch2
|
||||
.endm
|
||||
|
||||
/*
|
||||
* OVER operation on single a8r8g8b8 source pixel (s_8888) and single a8r8g8b8
|
||||
* destination pixel (d_8888). It also requires maskLSR needed for rounding
|
||||
* process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro OVER_8888_8888 s_8888, \
|
||||
d_8888, \
|
||||
out_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, scratch4
|
||||
not \scratch1, \s_8888
|
||||
srl \scratch1, \scratch1, 24
|
||||
|
||||
MIPS_UN8x4_MUL_UN8 \d_8888, \scratch1, \
|
||||
\out_8888, \maskLSR, \
|
||||
\scratch2, \scratch3, \scratch4
|
||||
|
||||
addu_s.qb \out_8888, \out_8888, \s_8888
|
||||
.endm
|
||||
|
||||
/*
|
||||
* OVER operation on two a8r8g8b8 source pixels (s1_8888 and s2_8888) and two
|
||||
* a8r8g8b8 destination pixels (d1_8888 and d2_8888). It also requires maskLSR
|
||||
* needed for rounding process. maskLSR must have following value:
|
||||
* li maskLSR, 0x00ff00ff
|
||||
*/
|
||||
.macro OVER_2x8888_2x8888 s1_8888, \
|
||||
s2_8888, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
out1_8888, \
|
||||
out2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
not \scratch1, \s1_8888
|
||||
srl \scratch1, \scratch1, 24
|
||||
not \scratch2, \s2_8888
|
||||
srl \scratch2, \scratch2, 24
|
||||
MIPS_2xUN8x4_MUL_2xUN8 \d1_8888, \d2_8888, \
|
||||
\scratch1, \scratch2, \
|
||||
\out1_8888, \out2_8888, \
|
||||
\maskLSR, \
|
||||
\scratch3, \scratch4, \scratch5, \
|
||||
\scratch6, \d1_8888, \d2_8888
|
||||
|
||||
addu_s.qb \out1_8888, \out1_8888, \s1_8888
|
||||
addu_s.qb \out2_8888, \out2_8888, \s2_8888
|
||||
.endm
|
||||
|
||||
.macro MIPS_UN8x4_MUL_UN8_ADD_UN8x4 s_8888, \
|
||||
m_8, \
|
||||
d_8888, \
|
||||
out_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3
|
||||
MIPS_UN8x4_MUL_UN8 \s_8888, \m_8, \
|
||||
\out_8888, \maskLSR, \
|
||||
\scratch1, \scratch2, \scratch3
|
||||
|
||||
addu_s.qb \out_8888, \out_8888, \d_8888
|
||||
.endm
|
||||
|
||||
.macro MIPS_2xUN8x4_MUL_2xUN8_ADD_2xUN8x4 s1_8888, \
|
||||
s2_8888, \
|
||||
m1_8, \
|
||||
m2_8, \
|
||||
d1_8888, \
|
||||
d2_8888, \
|
||||
out1_8888, \
|
||||
out2_8888, \
|
||||
maskLSR, \
|
||||
scratch1, scratch2, scratch3, \
|
||||
scratch4, scratch5, scratch6
|
||||
MIPS_2xUN8x4_MUL_2xUN8 \s1_8888, \s2_8888, \
|
||||
\m1_8, \m2_8, \
|
||||
\out1_8888, \out2_8888, \
|
||||
\maskLSR, \
|
||||
\scratch1, \scratch2, \scratch3, \
|
||||
\scratch4, \scratch5, \scratch6
|
||||
|
||||
addu_s.qb \out1_8888, \out1_8888, \d1_8888
|
||||
addu_s.qb \out2_8888, \out2_8888, \d2_8888
|
||||
.endm
|
||||
|
||||
.macro BILINEAR_INTERPOLATE_SINGLE_PIXEL tl, tr, bl, br, \
|
||||
scratch1, scratch2, \
|
||||
alpha, red, green, blue \
|
||||
wt1, wt2, wb1, wb2
|
||||
andi \scratch1, \tl, 0xff
|
||||
andi \scratch2, \tr, 0xff
|
||||
andi \alpha, \bl, 0xff
|
||||
andi \red, \br, 0xff
|
||||
|
||||
multu $ac0, \wt1, \scratch1
|
||||
maddu $ac0, \wt2, \scratch2
|
||||
maddu $ac0, \wb1, \alpha
|
||||
maddu $ac0, \wb2, \red
|
||||
|
||||
ext \scratch1, \tl, 8, 8
|
||||
ext \scratch2, \tr, 8, 8
|
||||
ext \alpha, \bl, 8, 8
|
||||
ext \red, \br, 8, 8
|
||||
|
||||
multu $ac1, \wt1, \scratch1
|
||||
maddu $ac1, \wt2, \scratch2
|
||||
maddu $ac1, \wb1, \alpha
|
||||
maddu $ac1, \wb2, \red
|
||||
|
||||
ext \scratch1, \tl, 16, 8
|
||||
ext \scratch2, \tr, 16, 8
|
||||
ext \alpha, \bl, 16, 8
|
||||
ext \red, \br, 16, 8
|
||||
|
||||
mflo \blue, $ac0
|
||||
|
||||
multu $ac2, \wt1, \scratch1
|
||||
maddu $ac2, \wt2, \scratch2
|
||||
maddu $ac2, \wb1, \alpha
|
||||
maddu $ac2, \wb2, \red
|
||||
|
||||
ext \scratch1, \tl, 24, 8
|
||||
ext \scratch2, \tr, 24, 8
|
||||
ext \alpha, \bl, 24, 8
|
||||
ext \red, \br, 24, 8
|
||||
|
||||
mflo \green, $ac1
|
||||
|
||||
multu $ac3, \wt1, \scratch1
|
||||
maddu $ac3, \wt2, \scratch2
|
||||
maddu $ac3, \wb1, \alpha
|
||||
maddu $ac3, \wb2, \red
|
||||
|
||||
mflo \red, $ac2
|
||||
mflo \alpha, $ac3
|
||||
|
||||
precr.qb.ph \alpha, \alpha, \red
|
||||
precr.qb.ph \scratch1, \green, \blue
|
||||
precrq.qb.ph \tl, \alpha, \scratch1
|
||||
.endm
|
||||
|
||||
#endif //PIXMAN_MIPS_DSPR2_ASM_H
|
459
vendor/pixman/pixman/pixman-mips-dspr2.c
vendored
459
vendor/pixman/pixman/pixman-mips-dspr2.c
vendored
@ -1,459 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-mips-dspr2.h"
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_x888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_8888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0565_8888,
|
||||
uint16_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0565_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0888_0888,
|
||||
uint8_t, 3, uint8_t, 3)
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0888_8888_rev,
|
||||
uint8_t, 3, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0888_0565_rev,
|
||||
uint8_t, 3, uint16_t, 1)
|
||||
#endif
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_pixbuf_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_rpixbuf_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, over_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, over_8888_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, add_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, add_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, out_reverse_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, out_reverse_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (0, src_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (0, src_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_8888_ca,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_0565_ca,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, add_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, add_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_8888_n_0565,
|
||||
uint32_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_0565_n_0565,
|
||||
uint16_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, add_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_n_0565,
|
||||
uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_reverse_n_8888,
|
||||
uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_N_DST (0, in_n_8,
|
||||
uint8_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8_8_8, uint8_t, 1,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8888_8_8888, uint32_t, 1,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8888_8888_8888, uint32_t, 1,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_0565_8_0565, uint16_t, 1,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8_8888, uint32_t, 1,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8_0565, uint32_t, 1,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_0565_8_0565, uint16_t, 1,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8888_8888, uint32_t, 1,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (8888_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (8888_0565, OVER,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (0565_8888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 8888_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 8888_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 0565_8888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 0565_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, 8888_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, 8888_8888, ADD,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_0565,
|
||||
OVER, uint32_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, 0565_8_0565,
|
||||
OVER, uint16_t, uint16_t)
|
||||
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 8888_8_8888, SRC,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 8888_8_0565, SRC,
|
||||
uint32_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 0565_8_x888, SRC,
|
||||
uint16_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 0565_8_0565, SRC,
|
||||
uint16_t, uint16_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, OVER,
|
||||
uint32_t, uint32_t)
|
||||
PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, ADD,
|
||||
uint32_t, uint32_t)
|
||||
|
||||
static pixman_bool_t
|
||||
mips_dspr2_fill (pixman_implementation_t *imp,
|
||||
uint32_t * bits,
|
||||
int stride,
|
||||
int bpp,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t _xor)
|
||||
{
|
||||
uint8_t *byte_line;
|
||||
uint32_t byte_width;
|
||||
switch (bpp)
|
||||
{
|
||||
case 16:
|
||||
stride = stride * (int) sizeof (uint32_t) / 2;
|
||||
byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
|
||||
byte_width = width * 2;
|
||||
stride *= 2;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
uint8_t *dst = byte_line;
|
||||
byte_line += stride;
|
||||
pixman_fill_buff16_mips (dst, byte_width, _xor & 0xffff);
|
||||
}
|
||||
return TRUE;
|
||||
case 32:
|
||||
stride = stride * (int) sizeof (uint32_t) / 4;
|
||||
byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
|
||||
byte_width = width * 4;
|
||||
stride *= 4;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
uint8_t *dst = byte_line;
|
||||
byte_line += stride;
|
||||
pixman_fill_buff32_mips (dst, byte_width, _xor);
|
||||
}
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
mips_dspr2_blt (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
int src_stride,
|
||||
int dst_stride,
|
||||
int src_bpp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (src_bpp != dst_bpp)
|
||||
return FALSE;
|
||||
|
||||
uint8_t *src_bytes;
|
||||
uint8_t *dst_bytes;
|
||||
uint32_t byte_width;
|
||||
|
||||
switch (src_bpp)
|
||||
{
|
||||
case 16:
|
||||
src_stride = src_stride * (int) sizeof (uint32_t) / 2;
|
||||
dst_stride = dst_stride * (int) sizeof (uint32_t) / 2;
|
||||
src_bytes =(uint8_t *)(((uint16_t *)src_bits)
|
||||
+ src_stride * (src_y) + (src_x));
|
||||
dst_bytes = (uint8_t *)(((uint16_t *)dst_bits)
|
||||
+ dst_stride * (dest_y) + (dest_x));
|
||||
byte_width = width * 2;
|
||||
src_stride *= 2;
|
||||
dst_stride *= 2;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
uint8_t *src = src_bytes;
|
||||
uint8_t *dst = dst_bytes;
|
||||
src_bytes += src_stride;
|
||||
dst_bytes += dst_stride;
|
||||
pixman_mips_fast_memcpy (dst, src, byte_width);
|
||||
}
|
||||
return TRUE;
|
||||
case 32:
|
||||
src_stride = src_stride * (int) sizeof (uint32_t) / 4;
|
||||
dst_stride = dst_stride * (int) sizeof (uint32_t) / 4;
|
||||
src_bytes = (uint8_t *)(((uint32_t *)src_bits)
|
||||
+ src_stride * (src_y) + (src_x));
|
||||
dst_bytes = (uint8_t *)(((uint32_t *)dst_bits)
|
||||
+ dst_stride * (dest_y) + (dest_x));
|
||||
byte_width = width * 4;
|
||||
src_stride *= 4;
|
||||
dst_stride *= 4;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
uint8_t *src = src_bytes;
|
||||
uint8_t *dst = dst_bytes;
|
||||
src_bytes += src_stride;
|
||||
dst_bytes += dst_stride;
|
||||
pixman_mips_fast_memcpy (dst, src, byte_width);
|
||||
}
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t mips_dspr2_fast_paths[] =
|
||||
{
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, mips_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, mips_composite_src_0565_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, mips_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, mips_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, mips_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, mips_composite_src_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, mips_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, mips_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, mips_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, mips_composite_src_0565_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, mips_composite_src_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, mips_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, mips_composite_src_x888_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, mips_composite_src_0888_0888),
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, x8r8g8b8, mips_composite_src_0888_8888_rev),
|
||||
PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, r5g6b5, mips_composite_src_0888_0565_rev),
|
||||
#endif
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8r8g8b8, mips_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8b8g8r8, mips_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8r8g8b8, mips_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8b8g8r8, mips_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, mips_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, mips_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, mips_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, mips_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8, mips_composite_src_n_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, mips_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, mips_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, mips_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, mips_composite_over_n_8888_8888_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, mips_composite_over_n_8888_0565_ca),
|
||||
PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, mips_composite_over_n_8888_0565_ca),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8, mips_composite_over_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, mips_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, mips_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, mips_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, mips_composite_over_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, mips_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, mips_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, mips_composite_over_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, mips_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, mips_composite_over_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, mips_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, mips_composite_over_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, r5g6b5, mips_composite_over_8888_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, b5g6r5, mips_composite_over_8888_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, r5g6b5, solid, r5g6b5, mips_composite_over_0565_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, b5g6r5, solid, b5g6r5, mips_composite_over_0565_n_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, mips_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, mips_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, mips_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, mips_composite_over_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, r5g6b5, mips_composite_over_8888_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, b5g6r5, mips_composite_over_8888_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, r5g6b5, a8, r5g6b5, mips_composite_over_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, b5g6r5, a8, b5g6r5, mips_composite_over_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, mips_composite_over_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, mips_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, mips_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, mips_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, mips_composite_over_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, mips_composite_over_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, mips_composite_over_8888_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, mips_composite_add_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8r8g8b8, mips_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8b8g8r8, mips_composite_add_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, a8, a8, mips_composite_add_8_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, r5g6b5, a8, r5g6b5, mips_composite_add_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, b5g6r5, a8, b5g6r5, mips_composite_add_0565_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8, a8r8g8b8, mips_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, a8, a8b8g8r8, mips_composite_add_8888_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, a8r8g8b8, mips_composite_add_8888_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, solid, a8r8g8b8, mips_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, solid, a8b8g8r8, mips_composite_add_8888_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, mips_composite_add_8_8),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, mips_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, mips_composite_add_8888_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, r5g6b5, mips_composite_out_reverse_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, b5g6r5, mips_composite_out_reverse_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, mips_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, mips_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, mips_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, mips_composite_over_reverse_n_8888),
|
||||
PIXMAN_STD_FAST_PATH (IN, solid, null, a8, mips_composite_in_n_8),
|
||||
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8888),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mips_8888_8888),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mips_8888_8888),
|
||||
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, mips_8888_0565),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, mips_8888_0565),
|
||||
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, mips_0565_8888),
|
||||
PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8888),
|
||||
/* Note: NONE repeat is not supported yet */
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, r5g6b5, a8r8g8b8, mips_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (SRC, b5g6r5, a8b8g8r8, mips_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, r5g6b5, a8r8g8b8, mips_0565_8888),
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (SRC, b5g6r5, a8b8g8r8, mips_0565_8888),
|
||||
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8r8g8b8, r5g6b5, mips_8888_8_0565),
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8b8g8r8, b5g6r5, mips_8888_8_0565),
|
||||
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, r5g6b5, r5g6b5, mips_0565_8_0565),
|
||||
SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, b5g6r5, b5g6r5, mips_0565_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mips_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, r5g6b5, mips_8888_0565),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, r5g6b5, mips_8888_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, mips_0565_0565),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, mips_8888_8888),
|
||||
SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, mips_8888_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mips_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mips_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mips_8888_8_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, r5g6b5, mips_8888_8_0565),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, r5g6b5, mips_8888_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8_x888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, r5g6b5, mips_0565_8_0565),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8_8888),
|
||||
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, mips_8888_8_8888),
|
||||
SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, mips_8888_8_8888),
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
static void
|
||||
mips_dspr2_combine_over_u (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
if (mask)
|
||||
pixman_composite_over_8888_8888_8888_asm_mips (
|
||||
dest, (uint32_t *)src, (uint32_t *)mask, width);
|
||||
else
|
||||
pixman_composite_over_8888_8888_asm_mips (
|
||||
dest, (uint32_t *)src, width);
|
||||
}
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp =
|
||||
_pixman_implementation_create (fallback, mips_dspr2_fast_paths);
|
||||
|
||||
imp->combine_32[PIXMAN_OP_OVER] = mips_dspr2_combine_over_u;
|
||||
|
||||
imp->blt = mips_dspr2_blt;
|
||||
imp->fill = mips_dspr2_fill;
|
||||
|
||||
return imp;
|
||||
}
|
432
vendor/pixman/pixman/pixman-mips-dspr2.h
vendored
432
vendor/pixman/pixman/pixman-mips-dspr2.h
vendored
@ -1,432 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Nemanja Lukic (nemanja.lukic@rt-rk.com)
|
||||
*/
|
||||
|
||||
#ifndef PIXMAN_MIPS_DSPR2_H
|
||||
#define PIXMAN_MIPS_DSPR2_H
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
#define SKIP_ZERO_SRC 1
|
||||
#define SKIP_ZERO_MASK 2
|
||||
#define DO_FAST_MEMCPY 3
|
||||
|
||||
void
|
||||
pixman_mips_fast_memcpy (void *dst, void *src, uint32_t n_bytes);
|
||||
void
|
||||
pixman_fill_buff16_mips (void *dst, uint32_t n_bytes, uint16_t value);
|
||||
void
|
||||
pixman_fill_buff32_mips (void *dst, uint32_t n_bytes, uint32_t value);
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST(flags, name, \
|
||||
src_type, src_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
src_type *src, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
src_type *src_line, *src; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
int bpp = PIXMAN_FORMAT_BPP (dest_image->bits.format) / 8; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
src = src_line; \
|
||||
src_line += src_stride; \
|
||||
\
|
||||
if (flags == DO_FAST_MEMCPY) \
|
||||
pixman_mips_fast_memcpy (dst, src, width * bpp); \
|
||||
else \
|
||||
pixman_composite_##name##_asm_mips (dst, src, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_N_DST(flags, name, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
uint32_t src, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
int32_t dst_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
\
|
||||
pixman_composite_##name##_asm_mips (dst, src, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST(flags, name, \
|
||||
mask_type, mask_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
uint32_t src, \
|
||||
mask_type *mask, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
mask_type *mask_line, *mask; \
|
||||
int32_t dst_stride, mask_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
|
||||
mask_stride, mask_line, mask_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
mask = mask_line; \
|
||||
mask_line += mask_stride; \
|
||||
pixman_composite_##name##_asm_mips (dst, src, mask, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST(flags, name, \
|
||||
src_type, src_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
src_type *src, \
|
||||
uint32_t mask, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
src_type *src_line, *src; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
uint32_t mask; \
|
||||
\
|
||||
mask = _pixman_image_get_solid ( \
|
||||
imp, mask_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_MASK) && mask == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
src = src_line; \
|
||||
src_line += src_stride; \
|
||||
\
|
||||
pixman_composite_##name##_asm_mips (dst, src, mask, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST(name, src_type, src_cnt, \
|
||||
mask_type, mask_cnt, \
|
||||
dst_type, dst_cnt) \
|
||||
void \
|
||||
pixman_composite_##name##_asm_mips (dst_type *dst, \
|
||||
src_type *src, \
|
||||
mask_type *mask, \
|
||||
int32_t w); \
|
||||
\
|
||||
static void \
|
||||
mips_composite_##name (pixman_implementation_t *imp, \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line, *dst; \
|
||||
src_type *src_line, *src; \
|
||||
mask_type *mask_line, *mask; \
|
||||
int32_t dst_stride, src_stride, mask_stride; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
|
||||
src_stride, src_line, src_cnt); \
|
||||
PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
|
||||
mask_stride, mask_line, mask_cnt); \
|
||||
\
|
||||
while (height--) \
|
||||
{ \
|
||||
dst = dst_line; \
|
||||
dst_line += dst_stride; \
|
||||
mask = mask_line; \
|
||||
mask_line += mask_stride; \
|
||||
src = src_line; \
|
||||
src_line += src_stride; \
|
||||
pixman_composite_##name##_asm_mips (dst, src, mask, width); \
|
||||
} \
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST(name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_mips ( \
|
||||
dst_type * dst, \
|
||||
const src_type * src, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_nearest_scanline_mips_##name##_##op (dst_type * pd, \
|
||||
const src_type * ps, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_mips (pd, ps, w, \
|
||||
vx, unit_x); \
|
||||
} \
|
||||
\
|
||||
FAST_NEAREST_MAINLOOP (mips_##name##_cover_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, dst_type, COVER) \
|
||||
FAST_NEAREST_MAINLOOP (mips_##name##_none_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, dst_type, NONE) \
|
||||
FAST_NEAREST_MAINLOOP (mips_##name##_pad_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, dst_type, PAD)
|
||||
|
||||
/* Provide entries for the fast path table */
|
||||
#define PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \
|
||||
SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \
|
||||
SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \
|
||||
SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST(flags, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_mips ( \
|
||||
dst_type * dst, \
|
||||
const src_type * src, \
|
||||
const uint8_t * mask, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_nearest_scanline_mips_##name##_##op (const uint8_t * mask, \
|
||||
dst_type * pd, \
|
||||
const src_type * ps, \
|
||||
int32_t w, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_nearest_scanline_##name##_##op##_asm_mips (pd, ps, \
|
||||
mask, w, \
|
||||
vx, unit_x); \
|
||||
} \
|
||||
\
|
||||
FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_cover_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, COVER, TRUE, FALSE)\
|
||||
FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_none_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \
|
||||
FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_pad_##op, \
|
||||
scaled_nearest_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, PAD, TRUE, FALSE)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST(flags, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips( \
|
||||
dst_type * dst, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x); \
|
||||
static force_inline void \
|
||||
scaled_bilinear_scanline_mips_##name##_##op (dst_type * dst, \
|
||||
const uint32_t * mask, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips (dst, src_top, \
|
||||
src_bottom, w, \
|
||||
wt, wb, \
|
||||
vx, unit_x); \
|
||||
} \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, COVER, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NONE, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, PAD, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NORMAL, \
|
||||
FLAG_NONE)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, name, op, \
|
||||
src_type, dst_type) \
|
||||
void \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips ( \
|
||||
dst_type * dst, \
|
||||
const uint8_t * mask, \
|
||||
const src_type * top, \
|
||||
const src_type * bottom, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t x, \
|
||||
pixman_fixed_t ux, \
|
||||
int width); \
|
||||
\
|
||||
static force_inline void \
|
||||
scaled_bilinear_scanline_mips_##name##_##op (dst_type * dst, \
|
||||
const uint8_t * mask, \
|
||||
const src_type * src_top, \
|
||||
const src_type * src_bottom, \
|
||||
int32_t w, \
|
||||
int wt, \
|
||||
int wb, \
|
||||
pixman_fixed_t vx, \
|
||||
pixman_fixed_t unit_x, \
|
||||
pixman_fixed_t max_vx, \
|
||||
pixman_bool_t zero_src) \
|
||||
{ \
|
||||
if ((flags & SKIP_ZERO_SRC) && zero_src) \
|
||||
return; \
|
||||
pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips ( \
|
||||
dst, mask, src_top, src_bottom, wt, wb, vx, unit_x, w); \
|
||||
} \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, COVER, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NONE, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, PAD, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_mips_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NORMAL, \
|
||||
FLAG_HAVE_NON_SOLID_MASK)
|
||||
|
||||
#endif //PIXMAN_MIPS_DSPR2_H
|
382
vendor/pixman/pixman/pixman-mips-memcpy-asm.S
vendored
382
vendor/pixman/pixman/pixman-mips-memcpy-asm.S
vendored
@ -1,382 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "pixman-mips-dspr2-asm.h"
|
||||
|
||||
/*
|
||||
* This routine could be optimized for MIPS64. The current code only
|
||||
* uses MIPS32 instructions.
|
||||
*/
|
||||
|
||||
#ifdef EB
|
||||
# define LWHI lwl /* high part is left in big-endian */
|
||||
# define SWHI swl /* high part is left in big-endian */
|
||||
# define LWLO lwr /* low part is right in big-endian */
|
||||
# define SWLO swr /* low part is right in big-endian */
|
||||
#else
|
||||
# define LWHI lwr /* high part is right in little-endian */
|
||||
# define SWHI swr /* high part is right in little-endian */
|
||||
# define LWLO lwl /* low part is left in big-endian */
|
||||
# define SWLO swl /* low part is left in big-endian */
|
||||
#endif
|
||||
|
||||
LEAF_MIPS32R2(pixman_mips_fast_memcpy)
|
||||
|
||||
slti AT, a2, 8
|
||||
bne AT, zero, $last8
|
||||
move v0, a0 /* memcpy returns the dst pointer */
|
||||
|
||||
/* Test if the src and dst are word-aligned, or can be made word-aligned */
|
||||
xor t8, a1, a0
|
||||
andi t8, t8, 0x3 /* t8 is a0/a1 word-displacement */
|
||||
|
||||
bne t8, zero, $unaligned
|
||||
negu a3, a0
|
||||
|
||||
andi a3, a3, 0x3 /* we need to copy a3 bytes to make a0/a1 aligned */
|
||||
beq a3, zero, $chk16w /* when a3=0 then the dst (a0) is word-aligned */
|
||||
subu a2, a2, a3 /* now a2 is the remining bytes count */
|
||||
|
||||
LWHI t8, 0(a1)
|
||||
addu a1, a1, a3
|
||||
SWHI t8, 0(a0)
|
||||
addu a0, a0, a3
|
||||
|
||||
/* Now the dst/src are mutually word-aligned with word-aligned addresses */
|
||||
$chk16w: andi t8, a2, 0x3f /* any whole 64-byte chunks? */
|
||||
/* t8 is the byte count after 64-byte chunks */
|
||||
|
||||
beq a2, t8, $chk8w /* if a2==t8, no 64-byte chunks */
|
||||
/* There will be at most 1 32-byte chunk after it */
|
||||
subu a3, a2, t8 /* subtract from a2 the reminder */
|
||||
/* Here a3 counts bytes in 16w chunks */
|
||||
addu a3, a0, a3 /* Now a3 is the final dst after 64-byte chunks */
|
||||
|
||||
addu t0, a0, a2 /* t0 is the "past the end" address */
|
||||
|
||||
/*
|
||||
* When in the loop we exercise "pref 30, x(a0)", the a0+x should not be past
|
||||
* the "t0-32" address
|
||||
* This means: for x=128 the last "safe" a0 address is "t0-160"
|
||||
* Alternatively, for x=64 the last "safe" a0 address is "t0-96"
|
||||
* In the current version we use "pref 30, 128(a0)", so "t0-160" is the limit
|
||||
*/
|
||||
subu t9, t0, 160 /* t9 is the "last safe pref 30, 128(a0)" address */
|
||||
|
||||
pref 0, 0(a1) /* bring the first line of src, addr 0 */
|
||||
pref 0, 32(a1) /* bring the second line of src, addr 32 */
|
||||
pref 0, 64(a1) /* bring the third line of src, addr 64 */
|
||||
pref 30, 32(a0) /* safe, as we have at least 64 bytes ahead */
|
||||
/* In case the a0 > t9 don't use "pref 30" at all */
|
||||
sgtu v1, a0, t9
|
||||
bgtz v1, $loop16w /* skip "pref 30, 64(a0)" for too short arrays */
|
||||
nop
|
||||
/* otherwise, start with using pref30 */
|
||||
pref 30, 64(a0)
|
||||
$loop16w:
|
||||
pref 0, 96(a1)
|
||||
lw t0, 0(a1)
|
||||
bgtz v1, $skip_pref30_96 /* skip "pref 30, 96(a0)" */
|
||||
lw t1, 4(a1)
|
||||
pref 30, 96(a0) /* continue setting up the dest, addr 96 */
|
||||
$skip_pref30_96:
|
||||
lw t2, 8(a1)
|
||||
lw t3, 12(a1)
|
||||
lw t4, 16(a1)
|
||||
lw t5, 20(a1)
|
||||
lw t6, 24(a1)
|
||||
lw t7, 28(a1)
|
||||
pref 0, 128(a1) /* bring the next lines of src, addr 128 */
|
||||
|
||||
sw t0, 0(a0)
|
||||
sw t1, 4(a0)
|
||||
sw t2, 8(a0)
|
||||
sw t3, 12(a0)
|
||||
sw t4, 16(a0)
|
||||
sw t5, 20(a0)
|
||||
sw t6, 24(a0)
|
||||
sw t7, 28(a0)
|
||||
|
||||
lw t0, 32(a1)
|
||||
bgtz v1, $skip_pref30_128 /* skip "pref 30, 128(a0)" */
|
||||
lw t1, 36(a1)
|
||||
pref 30, 128(a0) /* continue setting up the dest, addr 128 */
|
||||
$skip_pref30_128:
|
||||
lw t2, 40(a1)
|
||||
lw t3, 44(a1)
|
||||
lw t4, 48(a1)
|
||||
lw t5, 52(a1)
|
||||
lw t6, 56(a1)
|
||||
lw t7, 60(a1)
|
||||
pref 0, 160(a1) /* bring the next lines of src, addr 160 */
|
||||
|
||||
sw t0, 32(a0)
|
||||
sw t1, 36(a0)
|
||||
sw t2, 40(a0)
|
||||
sw t3, 44(a0)
|
||||
sw t4, 48(a0)
|
||||
sw t5, 52(a0)
|
||||
sw t6, 56(a0)
|
||||
sw t7, 60(a0)
|
||||
|
||||
addiu a0, a0, 64 /* adding 64 to dest */
|
||||
sgtu v1, a0, t9
|
||||
bne a0, a3, $loop16w
|
||||
addiu a1, a1, 64 /* adding 64 to src */
|
||||
move a2, t8
|
||||
|
||||
/* Here we have src and dest word-aligned but less than 64-bytes to go */
|
||||
|
||||
$chk8w:
|
||||
pref 0, 0x0(a1)
|
||||
andi t8, a2, 0x1f /* is there a 32-byte chunk? */
|
||||
/* the t8 is the reminder count past 32-bytes */
|
||||
beq a2, t8, $chk1w /* when a2=t8, no 32-byte chunk */
|
||||
nop
|
||||
|
||||
lw t0, 0(a1)
|
||||
lw t1, 4(a1)
|
||||
lw t2, 8(a1)
|
||||
lw t3, 12(a1)
|
||||
lw t4, 16(a1)
|
||||
lw t5, 20(a1)
|
||||
lw t6, 24(a1)
|
||||
lw t7, 28(a1)
|
||||
addiu a1, a1, 32
|
||||
|
||||
sw t0, 0(a0)
|
||||
sw t1, 4(a0)
|
||||
sw t2, 8(a0)
|
||||
sw t3, 12(a0)
|
||||
sw t4, 16(a0)
|
||||
sw t5, 20(a0)
|
||||
sw t6, 24(a0)
|
||||
sw t7, 28(a0)
|
||||
addiu a0, a0, 32
|
||||
|
||||
$chk1w:
|
||||
andi a2, t8, 0x3 /* now a2 is the reminder past 1w chunks */
|
||||
beq a2, t8, $last8
|
||||
subu a3, t8, a2 /* a3 is count of bytes in 1w chunks */
|
||||
addu a3, a0, a3 /* now a3 is the dst address past the 1w chunks */
|
||||
|
||||
/* copying in words (4-byte chunks) */
|
||||
$wordCopy_loop:
|
||||
lw t3, 0(a1) /* the first t3 may be equal t0 ... optimize? */
|
||||
addiu a1, a1, 4
|
||||
addiu a0, a0, 4
|
||||
bne a0, a3, $wordCopy_loop
|
||||
sw t3, -4(a0)
|
||||
|
||||
/* For the last (<8) bytes */
|
||||
$last8:
|
||||
blez a2, leave
|
||||
addu a3, a0, a2 /* a3 is the last dst address */
|
||||
$last8loop:
|
||||
lb v1, 0(a1)
|
||||
addiu a1, a1, 1
|
||||
addiu a0, a0, 1
|
||||
bne a0, a3, $last8loop
|
||||
sb v1, -1(a0)
|
||||
|
||||
leave: j ra
|
||||
nop
|
||||
|
||||
/*
|
||||
* UNALIGNED case
|
||||
*/
|
||||
|
||||
$unaligned:
|
||||
/* got here with a3="negu a0" */
|
||||
andi a3, a3, 0x3 /* test if the a0 is word aligned */
|
||||
beqz a3, $ua_chk16w
|
||||
subu a2, a2, a3 /* bytes left after initial a3 bytes */
|
||||
|
||||
LWHI v1, 0(a1)
|
||||
LWLO v1, 3(a1)
|
||||
addu a1, a1, a3 /* a3 may be here 1, 2 or 3 */
|
||||
SWHI v1, 0(a0)
|
||||
addu a0, a0, a3 /* below the dst will be word aligned (NOTE1) */
|
||||
|
||||
$ua_chk16w: andi t8, a2, 0x3f /* any whole 64-byte chunks? */
|
||||
/* t8 is the byte count after 64-byte chunks */
|
||||
beq a2, t8, $ua_chk8w /* if a2==t8, no 64-byte chunks */
|
||||
/* There will be at most 1 32-byte chunk after it */
|
||||
subu a3, a2, t8 /* subtract from a2 the reminder */
|
||||
/* Here a3 counts bytes in 16w chunks */
|
||||
addu a3, a0, a3 /* Now a3 is the final dst after 64-byte chunks */
|
||||
|
||||
addu t0, a0, a2 /* t0 is the "past the end" address */
|
||||
|
||||
subu t9, t0, 160 /* t9 is the "last safe pref 30, 128(a0)" address */
|
||||
|
||||
pref 0, 0(a1) /* bring the first line of src, addr 0 */
|
||||
pref 0, 32(a1) /* bring the second line of src, addr 32 */
|
||||
pref 0, 64(a1) /* bring the third line of src, addr 64 */
|
||||
pref 30, 32(a0) /* safe, as we have at least 64 bytes ahead */
|
||||
/* In case the a0 > t9 don't use "pref 30" at all */
|
||||
sgtu v1, a0, t9
|
||||
bgtz v1, $ua_loop16w /* skip "pref 30, 64(a0)" for too short arrays */
|
||||
nop
|
||||
/* otherwise, start with using pref30 */
|
||||
pref 30, 64(a0)
|
||||
$ua_loop16w:
|
||||
pref 0, 96(a1)
|
||||
LWHI t0, 0(a1)
|
||||
LWLO t0, 3(a1)
|
||||
LWHI t1, 4(a1)
|
||||
bgtz v1, $ua_skip_pref30_96
|
||||
LWLO t1, 7(a1)
|
||||
pref 30, 96(a0) /* continue setting up the dest, addr 96 */
|
||||
$ua_skip_pref30_96:
|
||||
LWHI t2, 8(a1)
|
||||
LWLO t2, 11(a1)
|
||||
LWHI t3, 12(a1)
|
||||
LWLO t3, 15(a1)
|
||||
LWHI t4, 16(a1)
|
||||
LWLO t4, 19(a1)
|
||||
LWHI t5, 20(a1)
|
||||
LWLO t5, 23(a1)
|
||||
LWHI t6, 24(a1)
|
||||
LWLO t6, 27(a1)
|
||||
LWHI t7, 28(a1)
|
||||
LWLO t7, 31(a1)
|
||||
pref 0, 128(a1) /* bring the next lines of src, addr 128 */
|
||||
|
||||
sw t0, 0(a0)
|
||||
sw t1, 4(a0)
|
||||
sw t2, 8(a0)
|
||||
sw t3, 12(a0)
|
||||
sw t4, 16(a0)
|
||||
sw t5, 20(a0)
|
||||
sw t6, 24(a0)
|
||||
sw t7, 28(a0)
|
||||
|
||||
LWHI t0, 32(a1)
|
||||
LWLO t0, 35(a1)
|
||||
LWHI t1, 36(a1)
|
||||
bgtz v1, $ua_skip_pref30_128
|
||||
LWLO t1, 39(a1)
|
||||
pref 30, 128(a0) /* continue setting up the dest, addr 128 */
|
||||
$ua_skip_pref30_128:
|
||||
LWHI t2, 40(a1)
|
||||
LWLO t2, 43(a1)
|
||||
LWHI t3, 44(a1)
|
||||
LWLO t3, 47(a1)
|
||||
LWHI t4, 48(a1)
|
||||
LWLO t4, 51(a1)
|
||||
LWHI t5, 52(a1)
|
||||
LWLO t5, 55(a1)
|
||||
LWHI t6, 56(a1)
|
||||
LWLO t6, 59(a1)
|
||||
LWHI t7, 60(a1)
|
||||
LWLO t7, 63(a1)
|
||||
pref 0, 160(a1) /* bring the next lines of src, addr 160 */
|
||||
|
||||
sw t0, 32(a0)
|
||||
sw t1, 36(a0)
|
||||
sw t2, 40(a0)
|
||||
sw t3, 44(a0)
|
||||
sw t4, 48(a0)
|
||||
sw t5, 52(a0)
|
||||
sw t6, 56(a0)
|
||||
sw t7, 60(a0)
|
||||
|
||||
addiu a0, a0, 64 /* adding 64 to dest */
|
||||
sgtu v1, a0, t9
|
||||
bne a0, a3, $ua_loop16w
|
||||
addiu a1, a1, 64 /* adding 64 to src */
|
||||
move a2, t8
|
||||
|
||||
/* Here we have src and dest word-aligned but less than 64-bytes to go */
|
||||
|
||||
$ua_chk8w:
|
||||
pref 0, 0x0(a1)
|
||||
andi t8, a2, 0x1f /* is there a 32-byte chunk? */
|
||||
/* the t8 is the reminder count */
|
||||
beq a2, t8, $ua_chk1w /* when a2=t8, no 32-byte chunk */
|
||||
|
||||
LWHI t0, 0(a1)
|
||||
LWLO t0, 3(a1)
|
||||
LWHI t1, 4(a1)
|
||||
LWLO t1, 7(a1)
|
||||
LWHI t2, 8(a1)
|
||||
LWLO t2, 11(a1)
|
||||
LWHI t3, 12(a1)
|
||||
LWLO t3, 15(a1)
|
||||
LWHI t4, 16(a1)
|
||||
LWLO t4, 19(a1)
|
||||
LWHI t5, 20(a1)
|
||||
LWLO t5, 23(a1)
|
||||
LWHI t6, 24(a1)
|
||||
LWLO t6, 27(a1)
|
||||
LWHI t7, 28(a1)
|
||||
LWLO t7, 31(a1)
|
||||
addiu a1, a1, 32
|
||||
|
||||
sw t0, 0(a0)
|
||||
sw t1, 4(a0)
|
||||
sw t2, 8(a0)
|
||||
sw t3, 12(a0)
|
||||
sw t4, 16(a0)
|
||||
sw t5, 20(a0)
|
||||
sw t6, 24(a0)
|
||||
sw t7, 28(a0)
|
||||
addiu a0, a0, 32
|
||||
|
||||
$ua_chk1w:
|
||||
andi a2, t8, 0x3 /* now a2 is the reminder past 1w chunks */
|
||||
beq a2, t8, $ua_smallCopy
|
||||
subu a3, t8, a2 /* a3 is count of bytes in 1w chunks */
|
||||
addu a3, a0, a3 /* now a3 is the dst address past the 1w chunks */
|
||||
|
||||
/* copying in words (4-byte chunks) */
|
||||
$ua_wordCopy_loop:
|
||||
LWHI v1, 0(a1)
|
||||
LWLO v1, 3(a1)
|
||||
addiu a1, a1, 4
|
||||
addiu a0, a0, 4 /* note: dst=a0 is word aligned here, see NOTE1 */
|
||||
bne a0, a3, $ua_wordCopy_loop
|
||||
sw v1, -4(a0)
|
||||
|
||||
/* Now less than 4 bytes (value in a2) left to copy */
|
||||
$ua_smallCopy:
|
||||
beqz a2, leave
|
||||
addu a3, a0, a2 /* a3 is the last dst address */
|
||||
$ua_smallCopy_loop:
|
||||
lb v1, 0(a1)
|
||||
addiu a1, a1, 1
|
||||
addiu a0, a0, 1
|
||||
bne a0, a3, $ua_smallCopy_loop
|
||||
sb v1, -1(a0)
|
||||
|
||||
j ra
|
||||
nop
|
||||
|
||||
END(pixman_mips_fast_memcpy)
|
94
vendor/pixman/pixman/pixman-mips.c
vendored
94
vendor/pixman/pixman/pixman-mips.c
vendored
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#if defined(USE_MIPS_DSPR2) || defined(USE_LOONGSON_MMI)
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static pixman_bool_t
|
||||
have_feature (const char *search_string)
|
||||
{
|
||||
#if defined (__linux__) /* linux ELF */
|
||||
/* Simple detection of MIPS features at runtime for Linux.
|
||||
* It is based on /proc/cpuinfo, which reveals hardware configuration
|
||||
* to user-space applications. According to MIPS (early 2010), no similar
|
||||
* facility is universally available on the MIPS architectures, so it's up
|
||||
* to individual OSes to provide such.
|
||||
*/
|
||||
const char *file_name = "/proc/cpuinfo";
|
||||
char cpuinfo_line[256];
|
||||
FILE *f = NULL;
|
||||
|
||||
if ((f = fopen (file_name, "r")) == NULL)
|
||||
return FALSE;
|
||||
|
||||
while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL)
|
||||
{
|
||||
if (strstr (cpuinfo_line, search_string) != NULL)
|
||||
{
|
||||
fclose (f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
#endif
|
||||
|
||||
/* Did not find string in the proc file, or not Linux ELF. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_mips_get_implementations (pixman_implementation_t *imp)
|
||||
{
|
||||
#ifdef USE_LOONGSON_MMI
|
||||
/* I really don't know if some Loongson CPUs don't have MMI. */
|
||||
if (!_pixman_disabled ("loongson-mmi") && have_feature ("Loongson"))
|
||||
imp = _pixman_implementation_create_mmx (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MIPS_DSPR2
|
||||
if (!_pixman_disabled ("mips-dspr2"))
|
||||
{
|
||||
int already_compiling_everything_for_dspr2 = 0;
|
||||
#if defined(__mips_dsp) && (__mips_dsp_rev >= 2)
|
||||
already_compiling_everything_for_dspr2 = 1;
|
||||
#endif
|
||||
if (already_compiling_everything_for_dspr2 ||
|
||||
/* Only currently available MIPS core that supports DSPr2 is 74K. */
|
||||
have_feature ("MIPS 74K"))
|
||||
{
|
||||
imp = _pixman_implementation_create_mips_dspr2 (imp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return imp;
|
||||
}
|
4153
vendor/pixman/pixman/pixman-mmx.c
vendored
4153
vendor/pixman/pixman/pixman-mmx.c
vendored
File diff suppressed because it is too large
Load Diff
161
vendor/pixman/pixman/pixman-noop.c
vendored
161
vendor/pixman/pixman/pixman-noop.c
vendored
@ -1,161 +0,0 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
* Copyright © 2011 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-combine32.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
static void
|
||||
noop_composite (pixman_implementation_t *imp,
|
||||
pixman_composite_info_t *info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
uint32_t *result = iter->buffer;
|
||||
|
||||
iter->buffer += iter->image->bits.rowstride;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
noop_init_solid_narrow (pixman_iter_t *iter,
|
||||
const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
uint32_t *buffer = iter->buffer;
|
||||
uint32_t *end = buffer + iter->width;
|
||||
uint32_t color;
|
||||
|
||||
if (iter->image->type == SOLID)
|
||||
color = image->solid.color_32;
|
||||
else
|
||||
color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
|
||||
|
||||
while (buffer < end)
|
||||
*(buffer++) = color;
|
||||
}
|
||||
|
||||
static void
|
||||
noop_init_solid_wide (pixman_iter_t *iter,
|
||||
const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
argb_t *buffer = (argb_t *)iter->buffer;
|
||||
argb_t *end = buffer + iter->width;
|
||||
argb_t color;
|
||||
|
||||
if (iter->image->type == SOLID)
|
||||
color = image->solid.color_float;
|
||||
else
|
||||
color = image->bits.fetch_pixel_float (&image->bits, 0, 0);
|
||||
|
||||
while (buffer < end)
|
||||
*(buffer++) = color;
|
||||
}
|
||||
|
||||
static void
|
||||
noop_init_direct_buffer (pixman_iter_t *iter, const pixman_iter_info_t *info)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
|
||||
iter->buffer =
|
||||
image->bits.bits + iter->y * image->bits.rowstride + iter->x;
|
||||
}
|
||||
|
||||
static void
|
||||
dest_write_back_direct (pixman_iter_t *iter)
|
||||
{
|
||||
iter->buffer += iter->image->bits.rowstride;
|
||||
}
|
||||
|
||||
static const pixman_iter_info_t noop_iters[] =
|
||||
{
|
||||
/* Source iters */
|
||||
{ PIXMAN_any,
|
||||
0, ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_SRC,
|
||||
NULL,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
NULL
|
||||
},
|
||||
{ PIXMAN_solid,
|
||||
FAST_PATH_NO_ALPHA_MAP, ITER_NARROW | ITER_SRC,
|
||||
noop_init_solid_narrow,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
NULL,
|
||||
},
|
||||
{ PIXMAN_solid,
|
||||
FAST_PATH_NO_ALPHA_MAP, ITER_WIDE | ITER_SRC,
|
||||
noop_init_solid_wide,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
NULL
|
||||
},
|
||||
{ PIXMAN_a8r8g8b8,
|
||||
FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM |
|
||||
FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST,
|
||||
ITER_NARROW | ITER_SRC,
|
||||
noop_init_direct_buffer,
|
||||
noop_get_scanline,
|
||||
NULL
|
||||
},
|
||||
/* Dest iters */
|
||||
{ PIXMAN_a8r8g8b8,
|
||||
FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST,
|
||||
noop_init_direct_buffer,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
dest_write_back_direct
|
||||
},
|
||||
{ PIXMAN_x8r8g8b8,
|
||||
FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST | ITER_LOCALIZED_ALPHA,
|
||||
noop_init_direct_buffer,
|
||||
_pixman_iter_get_scanline_noop,
|
||||
dest_write_back_direct
|
||||
},
|
||||
{ PIXMAN_null },
|
||||
};
|
||||
|
||||
static const pixman_fast_path_t noop_fast_paths[] =
|
||||
{
|
||||
{ PIXMAN_OP_DST, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, noop_composite },
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_noop (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp =
|
||||
_pixman_implementation_create (fallback, noop_fast_paths);
|
||||
|
||||
imp->iter_info = noop_iters;
|
||||
|
||||
return imp;
|
||||
}
|
173
vendor/pixman/pixman/pixman-ppc.c
vendored
173
vendor/pixman/pixman/pixman-ppc.c
vendored
@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of SuSE not be used in advertising or
|
||||
* publicity pertaining to distribution of the software without specific,
|
||||
* written prior permission. SuSE makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
|
||||
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#ifdef USE_VMX
|
||||
|
||||
/* The CPU detection code needs to be in a file not compiled with
|
||||
* "-maltivec -mabi=altivec", as gcc would try to save vector register
|
||||
* across function calls causing SIGILL on cpus without Altivec/vmx.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
int error, have_vmx;
|
||||
size_t length = sizeof(have_vmx);
|
||||
|
||||
error = sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0);
|
||||
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#elif defined (__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
int error, have_vmx;
|
||||
int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC };
|
||||
size_t length = sizeof(have_vmx);
|
||||
|
||||
error = sysctl (mib, 2, &have_vmx, &length, NULL, 0);
|
||||
|
||||
if (error != 0)
|
||||
return FALSE;
|
||||
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#elif defined (__FreeBSD__)
|
||||
#include <machine/cpu.h>
|
||||
#include <sys/auxv.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
|
||||
unsigned long cpufeatures;
|
||||
int have_vmx;
|
||||
|
||||
if (elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)))
|
||||
return FALSE;
|
||||
|
||||
have_vmx = cpufeatures & PPC_FEATURE_HAS_ALTIVEC;
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#elif defined (__linux__)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <linux/auxvec.h>
|
||||
#include <asm/cputable.h>
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
int have_vmx = FALSE;
|
||||
int fd;
|
||||
struct
|
||||
{
|
||||
unsigned long type;
|
||||
unsigned long value;
|
||||
} aux;
|
||||
|
||||
fd = open ("/proc/self/auxv", O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
while (read (fd, &aux, sizeof (aux)) == sizeof (aux))
|
||||
{
|
||||
if (aux.type == AT_HWCAP && (aux.value & PPC_FEATURE_HAS_ALTIVEC))
|
||||
{
|
||||
have_vmx = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close (fd);
|
||||
}
|
||||
|
||||
return have_vmx;
|
||||
}
|
||||
|
||||
#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
static jmp_buf jump_env;
|
||||
|
||||
static void
|
||||
vmx_test (int sig,
|
||||
siginfo_t *si,
|
||||
void * unused)
|
||||
{
|
||||
longjmp (jump_env, 1);
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
pixman_have_vmx (void)
|
||||
{
|
||||
struct sigaction sa, osa;
|
||||
int jmp_result;
|
||||
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sa.sa_sigaction = vmx_test;
|
||||
sigaction (SIGILL, &sa, &osa);
|
||||
jmp_result = setjmp (jump_env);
|
||||
if (jmp_result == 0)
|
||||
{
|
||||
asm volatile ( "vor 0, 0, 0" );
|
||||
}
|
||||
sigaction (SIGILL, &osa, NULL);
|
||||
return (jmp_result == 0);
|
||||
}
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
#endif /* USE_VMX */
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_ppc_get_implementations (pixman_implementation_t *imp)
|
||||
{
|
||||
#ifdef USE_VMX
|
||||
if (!_pixman_disabled ("vmx") && pixman_have_vmx ())
|
||||
imp = _pixman_implementation_create_vmx (imp);
|
||||
#endif
|
||||
|
||||
return imp;
|
||||
}
|
1193
vendor/pixman/pixman/pixman-private.h
vendored
1193
vendor/pixman/pixman/pixman-private.h
vendored
File diff suppressed because it is too large
Load Diff
509
vendor/pixman/pixman/pixman-radial-gradient.c
vendored
509
vendor/pixman/pixman/pixman-radial-gradient.c
vendored
@ -1,509 +0,0 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
*
|
||||
* Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
|
||||
* Copyright © 2000 SuSE, Inc.
|
||||
* 2005 Lars Knoll & Zack Rusin, Trolltech
|
||||
* Copyright © 2007 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <pixman-config.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static inline pixman_fixed_32_32_t
|
||||
dot (pixman_fixed_48_16_t x1,
|
||||
pixman_fixed_48_16_t y1,
|
||||
pixman_fixed_48_16_t z1,
|
||||
pixman_fixed_48_16_t x2,
|
||||
pixman_fixed_48_16_t y2,
|
||||
pixman_fixed_48_16_t z2)
|
||||
{
|
||||
/*
|
||||
* Exact computation, assuming that the input values can
|
||||
* be represented as pixman_fixed_16_16_t
|
||||
*/
|
||||
return x1 * x2 + y1 * y2 + z1 * z2;
|
||||
}
|
||||
|
||||
static inline double
|
||||
fdot (double x1,
|
||||
double y1,
|
||||
double z1,
|
||||
double x2,
|
||||
double y2,
|
||||
double z2)
|
||||
{
|
||||
/*
|
||||
* Error can be unbound in some special cases.
|
||||
* Using clever dot product algorithms (for example compensated
|
||||
* dot product) would improve this but make the code much less
|
||||
* obvious
|
||||
*/
|
||||
return x1 * x2 + y1 * y2 + z1 * z2;
|
||||
}
|
||||
|
||||
static void
|
||||
radial_write_color (double a,
|
||||
double b,
|
||||
double c,
|
||||
double inva,
|
||||
double dr,
|
||||
double mindr,
|
||||
pixman_gradient_walker_t *walker,
|
||||
pixman_repeat_t repeat,
|
||||
int Bpp,
|
||||
pixman_gradient_walker_write_t write_pixel,
|
||||
uint32_t *buffer)
|
||||
{
|
||||
/*
|
||||
* In this function error propagation can lead to bad results:
|
||||
* - discr can have an unbound error (if b*b-a*c is very small),
|
||||
* potentially making it the opposite sign of what it should have been
|
||||
* (thus clearing a pixel that would have been colored or vice-versa)
|
||||
* or propagating the error to sqrtdiscr;
|
||||
* if discr has the wrong sign or b is very small, this can lead to bad
|
||||
* results
|
||||
*
|
||||
* - the algorithm used to compute the solutions of the quadratic
|
||||
* equation is not numerically stable (but saves one division compared
|
||||
* to the numerically stable one);
|
||||
* this can be a problem if a*c is much smaller than b*b
|
||||
*
|
||||
* - the above problems are worse if a is small (as inva becomes bigger)
|
||||
*/
|
||||
double discr;
|
||||
|
||||
if (a == 0)
|
||||
{
|
||||
double t;
|
||||
|
||||
if (b == 0)
|
||||
{
|
||||
memset (buffer, 0, Bpp);
|
||||
return;
|
||||
}
|
||||
|
||||
t = pixman_fixed_1 / 2 * c / b;
|
||||
if (repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (0 <= t && t <= pixman_fixed_1)
|
||||
{
|
||||
write_pixel (walker, t, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t * dr >= mindr)
|
||||
{
|
||||
write_pixel (walker, t, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
memset (buffer, 0, Bpp);
|
||||
return;
|
||||
}
|
||||
|
||||
discr = fdot (b, a, 0, b, -c, 0);
|
||||
if (discr >= 0)
|
||||
{
|
||||
double sqrtdiscr, t0, t1;
|
||||
|
||||
sqrtdiscr = sqrt (discr);
|
||||
t0 = (b + sqrtdiscr) * inva;
|
||||
t1 = (b - sqrtdiscr) * inva;
|
||||
|
||||
/*
|
||||
* The root that must be used is the biggest one that belongs
|
||||
* to the valid range ([0,1] for PIXMAN_REPEAT_NONE, any
|
||||
* solution that results in a positive radius otherwise).
|
||||
*
|
||||
* If a > 0, t0 is the biggest solution, so if it is valid, it
|
||||
* is the correct result.
|
||||
*
|
||||
* If a < 0, only one of the solutions can be valid, so the
|
||||
* order in which they are tested is not important.
|
||||
*/
|
||||
if (repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (0 <= t0 && t0 <= pixman_fixed_1)
|
||||
{
|
||||
write_pixel (walker, t0, buffer);
|
||||
return;
|
||||
}
|
||||
else if (0 <= t1 && t1 <= pixman_fixed_1)
|
||||
{
|
||||
write_pixel (walker, t1, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t0 * dr >= mindr)
|
||||
{
|
||||
write_pixel (walker, t0, buffer);
|
||||
return;
|
||||
}
|
||||
else if (t1 * dr >= mindr)
|
||||
{
|
||||
write_pixel (walker, t1, buffer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset (buffer, 0, Bpp);
|
||||
return;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
radial_get_scanline (pixman_iter_t *iter,
|
||||
const uint32_t *mask,
|
||||
int Bpp,
|
||||
pixman_gradient_walker_write_t write_pixel)
|
||||
{
|
||||
/*
|
||||
* Implementation of radial gradients following the PDF specification.
|
||||
* See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference
|
||||
* Manual (PDF 32000-1:2008 at the time of this writing).
|
||||
*
|
||||
* In the radial gradient problem we are given two circles (c₁,r₁) and
|
||||
* (c₂,r₂) that define the gradient itself.
|
||||
*
|
||||
* Mathematically the gradient can be defined as the family of circles
|
||||
*
|
||||
* ((1-t)·c₁ + t·(c₂), (1-t)·r₁ + t·r₂)
|
||||
*
|
||||
* excluding those circles whose radius would be < 0. When a point
|
||||
* belongs to more than one circle, the one with a bigger t is the only
|
||||
* one that contributes to its color. When a point does not belong
|
||||
* to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0).
|
||||
* Further limitations on the range of values for t are imposed when
|
||||
* the gradient is not repeated, namely t must belong to [0,1].
|
||||
*
|
||||
* The graphical result is the same as drawing the valid (radius > 0)
|
||||
* circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient
|
||||
* is not repeated) using SOURCE operator composition.
|
||||
*
|
||||
* It looks like a cone pointing towards the viewer if the ending circle
|
||||
* is smaller than the starting one, a cone pointing inside the page if
|
||||
* the starting circle is the smaller one and like a cylinder if they
|
||||
* have the same radius.
|
||||
*
|
||||
* What we actually do is, given the point whose color we are interested
|
||||
* in, compute the t values for that point, solving for t in:
|
||||
*
|
||||
* length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂
|
||||
*
|
||||
* Let's rewrite it in a simpler way, by defining some auxiliary
|
||||
* variables:
|
||||
*
|
||||
* cd = c₂ - c₁
|
||||
* pd = p - c₁
|
||||
* dr = r₂ - r₁
|
||||
* length(t·cd - pd) = r₁ + t·dr
|
||||
*
|
||||
* which actually means
|
||||
*
|
||||
* hypot(t·cdx - pdx, t·cdy - pdy) = r₁ + t·dr
|
||||
*
|
||||
* or
|
||||
*
|
||||
* ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = r₁ + t·dr.
|
||||
*
|
||||
* If we impose (as stated earlier) that r₁ + t·dr >= 0, it becomes:
|
||||
*
|
||||
* (t·cdx - pdx)² + (t·cdy - pdy)² = (r₁ + t·dr)²
|
||||
*
|
||||
* where we can actually expand the squares and solve for t:
|
||||
*
|
||||
* t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² =
|
||||
* = r₁² + 2·r₁·t·dr + t²·dr²
|
||||
*
|
||||
* (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + r₁·dr)t +
|
||||
* (pdx² + pdy² - r₁²) = 0
|
||||
*
|
||||
* A = cdx² + cdy² - dr²
|
||||
* B = pdx·cdx + pdy·cdy + r₁·dr
|
||||
* C = pdx² + pdy² - r₁²
|
||||
* At² - 2Bt + C = 0
|
||||
*
|
||||
* The solutions (unless the equation degenerates because of A = 0) are:
|
||||
*
|
||||
* t = (B ± ⎷(B² - A·C)) / A
|
||||
*
|
||||
* The solution we are going to prefer is the bigger one, unless the
|
||||
* radius associated to it is negative (or it falls outside the valid t
|
||||
* range).
|
||||
*
|
||||
* Additional observations (useful for optimizations):
|
||||
* A does not depend on p
|
||||
*
|
||||
* A < 0 <=> one of the two circles completely contains the other one
|
||||
* <=> for every p, the radiuses associated with the two t solutions
|
||||
* have opposite sign
|
||||
*/
|
||||
pixman_image_t *image = iter->image;
|
||||
int x = iter->x;
|
||||
int y = iter->y;
|
||||
int width = iter->width;
|
||||
uint32_t *buffer = iter->buffer;
|
||||
|
||||
gradient_t *gradient = (gradient_t *)image;
|
||||
radial_gradient_t *radial = (radial_gradient_t *)image;
|
||||
uint32_t *end = buffer + width * (Bpp / 4);
|
||||
pixman_gradient_walker_t walker;
|
||||
pixman_vector_t v, unit;
|
||||
|
||||
/* reference point is the center of the pixel */
|
||||
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
|
||||
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
_pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
|
||||
|
||||
if (image->common.transform)
|
||||
{
|
||||
if (!pixman_transform_point_3d (image->common.transform, &v))
|
||||
return iter->buffer;
|
||||
|
||||
unit.vector[0] = image->common.transform->matrix[0][0];
|
||||
unit.vector[1] = image->common.transform->matrix[1][0];
|
||||
unit.vector[2] = image->common.transform->matrix[2][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
unit.vector[0] = pixman_fixed_1;
|
||||
unit.vector[1] = 0;
|
||||
unit.vector[2] = 0;
|
||||
}
|
||||
|
||||
if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1)
|
||||
{
|
||||
/*
|
||||
* Given:
|
||||
*
|
||||
* t = (B ± ⎷(B² - A·C)) / A
|
||||
*
|
||||
* where
|
||||
*
|
||||
* A = cdx² + cdy² - dr²
|
||||
* B = pdx·cdx + pdy·cdy + r₁·dr
|
||||
* C = pdx² + pdy² - r₁²
|
||||
* det = B² - A·C
|
||||
*
|
||||
* Since we have an affine transformation, we know that (pdx, pdy)
|
||||
* increase linearly with each pixel,
|
||||
*
|
||||
* pdx = pdx₀ + n·ux,
|
||||
* pdy = pdy₀ + n·uy,
|
||||
*
|
||||
* we can then express B, C and det through multiple differentiation.
|
||||
*/
|
||||
pixman_fixed_32_32_t b, db, c, dc, ddc;
|
||||
|
||||
/* warning: this computation may overflow */
|
||||
v.vector[0] -= radial->c1.x;
|
||||
v.vector[1] -= radial->c1.y;
|
||||
|
||||
/*
|
||||
* B and C are computed and updated exactly.
|
||||
* If fdot was used instead of dot, in the worst case it would
|
||||
* lose 11 bits of precision in each of the multiplication and
|
||||
* summing up would zero out all the bit that were preserved,
|
||||
* thus making the result 0 instead of the correct one.
|
||||
* This would mean a worst case of unbound relative error or
|
||||
* about 2^10 absolute error
|
||||
*/
|
||||
b = dot (v.vector[0], v.vector[1], radial->c1.radius,
|
||||
radial->delta.x, radial->delta.y, radial->delta.radius);
|
||||
db = dot (unit.vector[0], unit.vector[1], 0,
|
||||
radial->delta.x, radial->delta.y, 0);
|
||||
|
||||
c = dot (v.vector[0], v.vector[1],
|
||||
-((pixman_fixed_48_16_t) radial->c1.radius),
|
||||
v.vector[0], v.vector[1], radial->c1.radius);
|
||||
dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0],
|
||||
2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1],
|
||||
0,
|
||||
unit.vector[0], unit.vector[1], 0);
|
||||
ddc = 2 * dot (unit.vector[0], unit.vector[1], 0,
|
||||
unit.vector[0], unit.vector[1], 0);
|
||||
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
radial_write_color (radial->a, b, c,
|
||||
radial->inva,
|
||||
radial->delta.radius,
|
||||
radial->mindr,
|
||||
&walker,
|
||||
image->common.repeat,
|
||||
Bpp,
|
||||
write_pixel,
|
||||
buffer);
|
||||
}
|
||||
|
||||
b += db;
|
||||
c += dc;
|
||||
dc += ddc;
|
||||
buffer += (Bpp / 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* projective */
|
||||
/* Warning:
|
||||
* error propagation guarantees are much looser than in the affine case
|
||||
*/
|
||||
while (buffer < end)
|
||||
{
|
||||
if (!mask || *mask++)
|
||||
{
|
||||
if (v.vector[2] != 0)
|
||||
{
|
||||
double pdx, pdy, invv2, b, c;
|
||||
|
||||
invv2 = 1. * pixman_fixed_1 / v.vector[2];
|
||||
|
||||
pdx = v.vector[0] * invv2 - radial->c1.x;
|
||||
/* / pixman_fixed_1 */
|
||||
|
||||
pdy = v.vector[1] * invv2 - radial->c1.y;
|
||||
/* / pixman_fixed_1 */
|
||||
|
||||
b = fdot (pdx, pdy, radial->c1.radius,
|
||||
radial->delta.x, radial->delta.y,
|
||||
radial->delta.radius);
|
||||
/* / pixman_fixed_1 / pixman_fixed_1 */
|
||||
|
||||
c = fdot (pdx, pdy, -radial->c1.radius,
|
||||
pdx, pdy, radial->c1.radius);
|
||||
/* / pixman_fixed_1 / pixman_fixed_1 */
|
||||
|
||||
radial_write_color (radial->a, b, c,
|
||||
radial->inva,
|
||||
radial->delta.radius,
|
||||
radial->mindr,
|
||||
&walker,
|
||||
image->common.repeat,
|
||||
Bpp,
|
||||
write_pixel,
|
||||
buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (buffer, 0, Bpp);
|
||||
}
|
||||
}
|
||||
|
||||
buffer += (Bpp / 4);
|
||||
|
||||
v.vector[0] += unit.vector[0];
|
||||
v.vector[1] += unit.vector[1];
|
||||
v.vector[2] += unit.vector[2];
|
||||
}
|
||||
}
|
||||
|
||||
iter->y++;
|
||||
return iter->buffer;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return radial_get_scanline (iter, mask, 4,
|
||||
_pixman_gradient_walker_write_narrow);
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return radial_get_scanline (iter, NULL, 16,
|
||||
_pixman_gradient_walker_write_wide);
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
||||
{
|
||||
if (iter->iter_flags & ITER_NARROW)
|
||||
iter->get_scanline = radial_get_scanline_narrow;
|
||||
else
|
||||
iter->get_scanline = radial_get_scanline_wide;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_radial_gradient (const pixman_point_fixed_t * inner,
|
||||
const pixman_point_fixed_t * outer,
|
||||
pixman_fixed_t inner_radius,
|
||||
pixman_fixed_t outer_radius,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
int n_stops)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
radial_gradient_t *radial;
|
||||
|
||||
image = _pixman_image_allocate ();
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
radial = &image->radial;
|
||||
|
||||
if (!_pixman_init_gradient (&radial->common, stops, n_stops))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image->type = RADIAL;
|
||||
|
||||
radial->c1.x = inner->x;
|
||||
radial->c1.y = inner->y;
|
||||
radial->c1.radius = inner_radius;
|
||||
radial->c2.x = outer->x;
|
||||
radial->c2.y = outer->y;
|
||||
radial->c2.radius = outer_radius;
|
||||
|
||||
/* warning: this computations may overflow */
|
||||
radial->delta.x = radial->c2.x - radial->c1.x;
|
||||
radial->delta.y = radial->c2.y - radial->c1.y;
|
||||
radial->delta.radius = radial->c2.radius - radial->c1.radius;
|
||||
|
||||
/* computed exactly, then cast to double -> every bit of the double
|
||||
representation is correct (53 bits) */
|
||||
radial->a = dot (radial->delta.x, radial->delta.y, -radial->delta.radius,
|
||||
radial->delta.x, radial->delta.y, radial->delta.radius);
|
||||
if (radial->a != 0)
|
||||
radial->inva = 1. * pixman_fixed_1 / radial->a;
|
||||
|
||||
radial->mindr = -1. * pixman_fixed_1 * radial->c1.radius;
|
||||
|
||||
return image;
|
||||
}
|
2800
vendor/pixman/pixman/pixman-region.c
vendored
2800
vendor/pixman/pixman/pixman-region.c
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user