1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkRandom.h"
9#include "SkUtils.h"
10#include "Test.h"
11
12static void set_zero(void* dst, size_t bytes) {
13    char* ptr = (char*)dst;
14    for (size_t i = 0; i < bytes; ++i) {
15        ptr[i] = 0;
16    }
17}
18
19#define MAX_ALIGNMENT   64
20#define MAX_COUNT       ((MAX_ALIGNMENT) * 32)
21#define PAD             32
22#define TOTAL           (PAD + MAX_ALIGNMENT + MAX_COUNT + PAD)
23
24#define VALUE16         0x1234
25#define VALUE32         0x12345678
26
27static void compare16(skiatest::Reporter* r, const uint16_t base[],
28                      uint16_t value, int count) {
29    for (int i = 0; i < count; ++i) {
30        if (base[i] != value) {
31            ERRORF(r, "[%d] expected %x found %x\n", i, value, base[i]);
32            return;
33        }
34    }
35}
36
37static void compare32(skiatest::Reporter* r, const uint32_t base[],
38                      uint32_t value, int count) {
39    for (int i = 0; i < count; ++i) {
40        if (base[i] != value) {
41            ERRORF(r, "[%d] expected %x found %x\n", i, value, base[i]);
42            return;
43        }
44    }
45}
46
47static void test_16(skiatest::Reporter* reporter) {
48    uint16_t buffer[TOTAL];
49
50    for (int count = 0; count < MAX_COUNT; ++count) {
51        for (int alignment = 0; alignment < MAX_ALIGNMENT; ++alignment) {
52            set_zero(buffer, sizeof(buffer));
53
54            uint16_t* base = &buffer[PAD + alignment];
55            sk_memset16(base, VALUE16, count);
56
57            compare16(reporter, buffer,       0,       PAD + alignment);
58            compare16(reporter, base,         VALUE16, count);
59            compare16(reporter, base + count, 0,       TOTAL - count - PAD - alignment);
60        }
61    }
62}
63
64static void test_32(skiatest::Reporter* reporter) {
65    uint32_t buffer[TOTAL];
66
67    for (int count = 0; count < MAX_COUNT; ++count) {
68        for (int alignment = 0; alignment < MAX_ALIGNMENT; ++alignment) {
69            set_zero(buffer, sizeof(buffer));
70
71            uint32_t* base = &buffer[PAD + alignment];
72            sk_memset32(base, VALUE32, count);
73
74            compare32(reporter, buffer,       0,       PAD + alignment);
75            compare32(reporter, base,         VALUE32, count);
76            compare32(reporter, base + count, 0,       TOTAL - count - PAD - alignment);
77        }
78    }
79}
80
81/**
82 *  Test sk_memset16 and sk_memset32.
83 *  For performance considerations, implementations may take different paths
84 *  depending on the alignment of the dst, and/or the size of the count.
85 */
86DEF_TEST(Memset, reporter) {
87    test_16(reporter);
88    test_32(reporter);
89}
90