summaryrefslogtreecommitdiff
path: root/tests/conform/test-texture-get-set-data.c
blob: cf24e4d715ee83d9c2917e81260c0750f2616e93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <cogl/cogl.h>

#include <string.h>

#include "test-utils.h"

static void
check_texture (int width, int height, CoglTextureFlags flags)
{
  CoglTexture *tex;
  uint8_t *data, *p;
  int y, x;
  int rowstride;

  p = data = g_malloc (width * height * 4);
  for (y = 0; y < height; y++)
    for (x = 0; x < width; x++)
      {
        *(p++) = x;
        *(p++) = y;
        *(p++) = 128;
        *(p++) = (x ^ y);
      }

  tex = cogl_texture_new_from_data (test_ctx,
                                    width, height,
                                    flags,
                                    COGL_PIXEL_FORMAT_RGBA_8888,
                                    COGL_PIXEL_FORMAT_RGBA_8888,
                                    width * 4,
                                    data,
                                    NULL); /* abort on error */

  /* Replace the bottom right quarter of the data with negated data to
     test set_region */
  rowstride = width * 4;
  p = data + (height / 2) * rowstride + rowstride / 2;
  for (y = 0; y < height / 2; y++)
    {
      for (x = 0; x < width / 2; x++)
        {
          p[0] = ~p[0];
          p[1] = ~p[1];
          p[2] = ~p[2];
          p[3] = ~p[3];
          p += 4;
        }
      p += width * 2;
    }
  cogl_texture_set_region (tex,
                           width / 2, /* region width */
                           height / 2, /* region height */
                           COGL_PIXEL_FORMAT_RGBA_8888,
                           rowstride,
                           data + (height / 2) * rowstride + rowstride / 2,
                           width / 2, /* dest x */
                           height / 2, /* dest y */
                           0, /* mipmap level 0 */
                           NULL); /* abort on error */

  /* Check passing a NULL pointer and a zero rowstride. The texture
     should calculate the needed data size and return it */
  g_assert_cmpint (cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_ANY, 0, NULL),
                   ==,
                   width * height * 4);

  /* Try first receiving the data as RGB. This should cause a
   * conversion */
  memset (data, 0, width * height * 4);

  cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_RGB_888,
                         width * 3, data);

  p = data;

  for (y = 0; y < height; y++)
    for (x = 0; x < width; x++)
      {
        if (x >= width / 2 && y >= height / 2)
          {
            g_assert_cmpint (p[0], ==, ~x & 0xff);
            g_assert_cmpint (p[1], ==, ~y & 0xff);
            g_assert_cmpint (p[2], ==, ~128 & 0xff);
          }
        else
          {
            g_assert_cmpint (p[0], ==, x & 0xff);
            g_assert_cmpint (p[1], ==, y & 0xff);
            g_assert_cmpint (p[2], ==, 128);
          }
        p += 3;
      }

  /* Now try receiving the data as RGBA. This should not cause a
   * conversion and no unpremultiplication because we explicitly set
   * the internal format when we created the texture */
  memset (data, 0, width * height * 4);

  cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_RGBA_8888,
                         width * 4, data);

  p = data;

  for (y = 0; y < height; y++)
    for (x = 0; x < width; x++)
      {
        if (x >= width / 2 && y >= height / 2)
          {
            g_assert_cmpint (p[0], ==, ~x & 0xff);
            g_assert_cmpint (p[1], ==, ~y & 0xff);
            g_assert_cmpint (p[2], ==, ~128 & 0xff);
            g_assert_cmpint (p[3], ==, ~(x ^ y) & 0xff);
          }
        else
          {
            g_assert_cmpint (p[0], ==, x & 0xff);
            g_assert_cmpint (p[1], ==, y & 0xff);
            g_assert_cmpint (p[2], ==, 128);
            g_assert_cmpint (p[3], ==, (x ^ y) & 0xff);
          }
        p += 4;
      }

  cogl_object_unref (tex);
  g_free (data);
}

void
test_texture_get_set_data (void)
{
  /* First try without atlasing */
  check_texture (256, 256, COGL_TEXTURE_NO_ATLAS);
  /* Try again with atlasing. This should end up testing the atlas
     backend and the sub texture backend */
  check_texture (256, 256, 0);
  /* Try with a really big texture in the hope that it will end up
     sliced. */
  check_texture (4, 5128, COGL_TEXTURE_NO_ATLAS);
  /* And in the other direction. */
  check_texture (5128, 4, COGL_TEXTURE_NO_ATLAS);
}