mirror of
https://github.com/brl/mutter.git
synced 2024-12-03 13:20:41 -05:00
8e172aeecb
It makes sure we do not forget to zero the id and lets us avoid zero checks before. We use it for all new code, lets clean up the existing code base. https://gitlab.gnome.org/GNOME/mutter/merge_requests/947
207 lines
5.7 KiB
C
207 lines
5.7 KiB
C
#include <clutter/clutter.h>
|
|
#include <cogl/cogl.h>
|
|
#include <string.h>
|
|
|
|
#include "test-conform-common.h"
|
|
|
|
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
|
|
|
#define QUAD_WIDTH 20
|
|
|
|
#define RED 0
|
|
#define GREEN 1
|
|
#define BLUE 2
|
|
#define ALPHA 3
|
|
|
|
typedef struct _TestState
|
|
{
|
|
unsigned int padding;
|
|
} TestState;
|
|
|
|
static void
|
|
assert_region_color (int x,
|
|
int y,
|
|
int width,
|
|
int height,
|
|
uint8_t red,
|
|
uint8_t green,
|
|
uint8_t blue,
|
|
uint8_t alpha)
|
|
{
|
|
uint8_t *data = g_malloc0 (width * height * 4);
|
|
cogl_read_pixels (x, y, width, height,
|
|
COGL_READ_PIXELS_COLOR_BUFFER,
|
|
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
|
data);
|
|
for (y = 0; y < height; y++)
|
|
for (x = 0; x < width; x++)
|
|
{
|
|
uint8_t *pixel = &data[y * width * 4 + x * 4];
|
|
#if 1
|
|
g_assert (pixel[RED] == red &&
|
|
pixel[GREEN] == green &&
|
|
pixel[BLUE] == blue);
|
|
#endif
|
|
}
|
|
g_free (data);
|
|
}
|
|
|
|
/* Creates a texture divided into 4 quads with colors arranged as follows:
|
|
* (The same value are used in all channels for each texel)
|
|
*
|
|
* |-----------|
|
|
* |0x11 |0x00 |
|
|
* |+ref | |
|
|
* |-----------|
|
|
* |0x00 |0x33 |
|
|
* | |+ref |
|
|
* |-----------|
|
|
*
|
|
*
|
|
*/
|
|
static CoglHandle
|
|
make_texture (guchar ref)
|
|
{
|
|
int x;
|
|
int y;
|
|
guchar *tex_data, *p;
|
|
CoglHandle tex;
|
|
guchar val;
|
|
|
|
tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 16);
|
|
|
|
for (y = 0; y < QUAD_WIDTH * 2; y++)
|
|
for (x = 0; x < QUAD_WIDTH * 2; x++)
|
|
{
|
|
p = tex_data + (QUAD_WIDTH * 8 * y) + x * 4;
|
|
if (x < QUAD_WIDTH && y < QUAD_WIDTH)
|
|
val = 0x11 + ref;
|
|
else if (x >= QUAD_WIDTH && y >= QUAD_WIDTH)
|
|
val = 0x33 + ref;
|
|
else
|
|
val = 0x00;
|
|
p[0] = p[1] = p[2] = p[3] = val;
|
|
}
|
|
|
|
/* Note: we don't use COGL_PIXEL_FORMAT_ANY for the internal format here
|
|
* since we don't want to allow Cogl to premultiply our data. */
|
|
tex = test_utils_texture_new_from_data (QUAD_WIDTH * 2,
|
|
QUAD_WIDTH * 2,
|
|
TEST_UTILS_TEXTURE_NONE,
|
|
COGL_PIXEL_FORMAT_RGBA_8888,
|
|
COGL_PIXEL_FORMAT_RGBA_8888,
|
|
QUAD_WIDTH * 8,
|
|
tex_data);
|
|
|
|
g_free (tex_data);
|
|
|
|
return tex;
|
|
}
|
|
|
|
static void
|
|
on_paint (ClutterActor *actor, TestState *state)
|
|
{
|
|
CoglHandle tex0, tex1;
|
|
CoglHandle material;
|
|
gboolean status;
|
|
GError *error = NULL;
|
|
float tex_coords[] = {
|
|
0, 0, 0.5, 0.5, /* tex0 */
|
|
0.5, 0.5, 1, 1 /* tex1 */
|
|
};
|
|
|
|
tex0 = make_texture (0x00);
|
|
tex1 = make_texture (0x11);
|
|
|
|
material = cogl_material_new ();
|
|
|
|
/* An arbitrary color which should be replaced by the first texture layer */
|
|
cogl_material_set_color4ub (material, 0x80, 0x80, 0x80, 0x80);
|
|
cogl_material_set_blend (material, "RGBA = ADD (SRC_COLOR, 0)", NULL);
|
|
|
|
cogl_material_set_layer (material, 0, tex0);
|
|
cogl_material_set_layer_combine (material, 0,
|
|
"RGBA = REPLACE (TEXTURE)", NULL);
|
|
/* We'll use nearest filtering mode on the textures, otherwise the
|
|
edge of the quad can pull in texels from the neighbouring
|
|
quarters of the texture due to imprecision */
|
|
cogl_material_set_layer_filters (material, 0,
|
|
COGL_MATERIAL_FILTER_NEAREST,
|
|
COGL_MATERIAL_FILTER_NEAREST);
|
|
|
|
cogl_material_set_layer (material, 1, tex1);
|
|
cogl_material_set_layer_filters (material, 1,
|
|
COGL_MATERIAL_FILTER_NEAREST,
|
|
COGL_MATERIAL_FILTER_NEAREST);
|
|
status = cogl_material_set_layer_combine (material, 1,
|
|
"RGBA = ADD (PREVIOUS, TEXTURE)",
|
|
&error);
|
|
if (!status)
|
|
{
|
|
/* It's not strictly a test failure; you need a more capable GPU or
|
|
* driver to test this texture combine string. */
|
|
g_debug ("Failed to setup texture combine string "
|
|
"RGBA = ADD (PREVIOUS, TEXTURE): %s",
|
|
error->message);
|
|
}
|
|
|
|
cogl_set_source (material);
|
|
cogl_rectangle_with_multitexture_coords (0, 0, QUAD_WIDTH, QUAD_WIDTH,
|
|
tex_coords, 8);
|
|
|
|
cogl_object_unref (material);
|
|
cogl_object_unref (tex0);
|
|
cogl_object_unref (tex1);
|
|
|
|
/* See what we got... */
|
|
|
|
assert_region_color (0, 0, QUAD_WIDTH, QUAD_WIDTH,
|
|
0x55, 0x55, 0x55, 0x55);
|
|
|
|
/* Comment this out if you want visual feedback for what this test paints */
|
|
#if 1
|
|
clutter_main_quit ();
|
|
#endif
|
|
}
|
|
|
|
static gboolean
|
|
queue_redraw (void *stage)
|
|
{
|
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
test_multitexture (TestUtilsGTestFixture *fixture,
|
|
void *data)
|
|
{
|
|
TestState state;
|
|
ClutterActor *stage;
|
|
ClutterActor *group;
|
|
unsigned int idle_source;
|
|
|
|
stage = clutter_stage_get_default ();
|
|
|
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
|
|
|
group = clutter_group_new ();
|
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
|
|
|
|
/* We force continuous redrawing incase someone comments out the
|
|
* clutter_main_quit and wants visual feedback for the test since we
|
|
* wont be doing anything else that will trigger redrawing. */
|
|
idle_source = g_idle_add (queue_redraw, stage);
|
|
|
|
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
|
|
|
|
clutter_actor_show_all (stage);
|
|
|
|
clutter_main ();
|
|
|
|
g_clear_handle_id (&idle_source, g_source_remove);
|
|
|
|
if (cogl_test_verbose ())
|
|
g_print ("OK\n");
|
|
}
|