cogl: Remove now empty conform test suite

All working tests have already migrated to the test suite using mutter;
move the old unported tests over too, and remove the conform test
framework, as it is no longer used.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2555>
This commit is contained in:
Jonas Ådahl
2022-08-04 23:22:54 +02:00
committed by Marge Bot
parent 5d40a5eeea
commit 4ebaa433ee
14 changed files with 10 additions and 203 deletions

View File

@@ -41,6 +41,16 @@ cogl_tests = [
[ 'test-fence', [] ],
]
#unported = [
# "test-multitexture",
# "test-npot-texture",
# "test-object",
# "test-readpixels",
# "test-texture-mipmaps",
# "test-texture-pixmap-x11",
# "test-viewport",
#]
cogl_test_conformance_includes = [
tests_includepath,
cogl_includepath,

View File

@@ -0,0 +1,208 @@
#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,
ClutterPaintContext *paint_context,
TestState *state)
{
CoglHandle tex0, tex1;
CoglPipeline *pipeline;
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);
pipeline = cogl_pipeline_new ();
/* An arbitrary color which should be replaced by the first texture layer */
cogl_pipeline_set_color4ub (pipeline, 0x80, 0x80, 0x80, 0x80);
cogl_pipekine_set_blend (pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL);
cogl_pipeline_set_layer_texture (pipeline, 0, tex0);
cogl_pipeline_set_layer_combine (pipeline, 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_pipeline_set_layer_filters (pipeline, 0,
COGL_PIPELINE_FILTER_NEAREST,
COGL_PIPELINE_FILTER_NEAREST);
cogl_pipeline_set_layer (pipeline, 1, tex1);
cogl_pipeline_set_layer_filters (pipeline, 1,
COGL_PIPELINE_FILTER_NEAREST,
COGL_PIPELINE_FILTER_NEAREST);
status = cogl_pipeline_set_layer_combine (pipeline, 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 (pipeline);
cogl_rectangle_with_multitexture_coords (0, 0, QUAD_WIDTH, QUAD_WIDTH,
tex_coords, 8);
cogl_object_unref (pipeline);
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_test_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_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
group = clutter_actor_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
/* We force continuous redrawing in case someone comments out the
* clutter_test_quit and wants visual feedback for the test since we
* won't 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 (stage);
clutter_test_main ();
g_clear_handle_id (&idle_source, g_source_remove);
if (cogl_test_verbose ())
g_print ("OK\n");
}

View File

@@ -0,0 +1,86 @@
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <string.h>
#include "test-conform-common.h"
CoglUserDataKey private_key0;
CoglUserDataKey private_key1;
CoglUserDataKey private_key2;
static int user_data0;
static int user_data1;
static int user_data2;
static int destroy0_count = 0;
static int destroy1_count = 0;
static int destroy2_count = 0;
static void
destroy0_cb (void *user_data)
{
g_assert (user_data == &user_data0);
destroy0_count++;
}
static void
destroy1_cb (void *user_data)
{
g_assert (user_data == &user_data1);
destroy1_count++;
}
static void
destroy2_cb (void *user_data)
{
g_assert (user_data == &user_data2);
destroy2_count++;
}
void
test_object (TestUtilsGTestFixture *fixture,
void *data)
{
CoglPipeline *pipeline;
/* Assuming that COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES == 2
* test associating 2 pointers to private data with an object */
cogl_pipeline_new ();
pipeline = cogl_pipeline_path ();
cogl_object_set_user_data (COGL_OBJECT (pipeline),
&private_key0,
&user_data0,
destroy0_cb);
cogl_object_set_user_data (COGL_OBJECT (pipeline),
&private_key1,
&user_data1,
destroy1_cb);
cogl_object_set_user_data (COGL_OBJECT (pipeline),
&private_key2,
&user_data2,
destroy2_cb);
cogl_object_set_user_data (COGL_OBJECT (pipeline),
&private_key1,
NULL,
destroy1_cb);
cogl_object_set_user_data (COGL_OBJECT (pipeline),
&private_key1,
&user_data1,
destroy1_cb);
cogl_object_unref (pipeline);
g_assert_cmpint (destroy0_count, ==, 1);
g_assert_cmpint (destroy1_count, ==, 2);
g_assert_cmpint (destroy2_count, ==, 1);
if (cogl_test_verbose ())
g_print ("OK\n");
}

View File

@@ -0,0 +1,178 @@
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include "test-conform-common.h"
#define RED 0
#define GREEN 1
#define BLUE 2
#define FRAMEBUFFER_WIDTH 640
#define FRAMEBUFFER_HEIGHT 480
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
static void
on_after_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
void *state)
{
float saved_viewport[4];
graphene_matrix_t saved_projection;
graphene_matrix_t projection;
graphene_matrix_t modelview;
guchar *data;
CoglHandle tex;
CoglHandle offscreen;
uint32_t *pixels;
uint8_t *pixelsc;
/* Save the Clutter viewport/matrices and load identity matrices */
cogl_get_viewport (saved_viewport);
cogl_get_projection_matrix (&saved_projection);
cogl_push_matrix ();
graphene_matrix_init_identity (&projection);
graphene_matrix_init_identity (&modelview);
cogl_set_projection_matrix (&projection);
cogl_set_modelview_matrix (&modelview);
/* All offscreen rendering is done upside down so the first thing we
* verify is reading back grid of colors from a CoglOffscreen framebuffer
*/
data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
tex = test_utils_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
TEST_UTILS_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */
COGL_PIXEL_FORMAT_ANY, /* internal fmt */
FRAMEBUFFER_WIDTH * 4, /* rowstride */
data);
g_free (data);
offscreen = cogl_offscreen_new_with_texture (tex);
cogl_push_framebuffer (offscreen);
/* red, top left */
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
cogl_rectangle (-1, 1, 0, 0);
/* green, top right */
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
cogl_rectangle (0, 1, 1, 0);
/* blue, bottom left */
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
cogl_rectangle (-1, 0, 0, -1);
/* white, bottom right */
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_rectangle (0, 0, 1, -1);
pixels = g_malloc0 (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
(guchar *)pixels);
g_assert_cmpint (pixels[0], ==, 0xff0000ff);
g_assert_cmpint (pixels[FRAMEBUFFER_WIDTH - 1], ==, 0xff00ff00);
g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH], ==, 0xffff0000);
g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH + FRAMEBUFFER_WIDTH - 1], ==, 0xffffffff);
g_free (pixels);
cogl_pop_framebuffer ();
g_object_unref (offscreen);
/* Now verify reading back from an onscreen framebuffer...
*/
cogl_set_source_texture (tex);
cogl_rectangle (-1, 1, 1, -1);
pixels = g_malloc0 (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
(guchar *)pixels);
g_assert_cmpint (pixels[0], ==, 0xff0000ff);
g_assert_cmpint (pixels[FRAMEBUFFER_WIDTH - 1], ==, 0xff00ff00);
g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH], ==, 0xffff0000);
g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH + FRAMEBUFFER_WIDTH - 1], ==, 0xffffffff);
g_free (pixels);
/* Verify using BGR format */
cogl_set_source_texture (tex);
cogl_rectangle (-1, 1, 1, -1);
pixelsc = g_malloc0 (FRAMEBUFFER_WIDTH * 3 * FRAMEBUFFER_HEIGHT);
cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_BGR_888,
(guchar *)pixelsc);
g_assert_cmpint (pixelsc[0], ==, 0x00);
g_assert_cmpint (pixelsc[1], ==, 0x00);
g_assert_cmpint (pixelsc[2], ==, 0xff);
g_assert_cmpint (pixelsc[(FRAMEBUFFER_WIDTH - 1) * 3 + 0], ==, 0x00);
g_assert_cmpint (pixelsc[(FRAMEBUFFER_WIDTH - 1) * 3 + 1], ==, 0xff);
g_assert_cmpint (pixelsc[(FRAMEBUFFER_WIDTH - 1) * 3 + 2], ==, 0x00);
g_free (pixelsc);
cogl_object_unref (tex);
/* Restore the viewport and matrices state */
cogl_set_viewport (saved_viewport[0],
saved_viewport[1],
saved_viewport[2],
saved_viewport[3]);
cogl_set_projection_matrix (&saved_projection);
cogl_pop_matrix ();
/* Comment this out if you want visual feedback of what this test
* paints.
*/
clutter_test_quit ();
}
static gboolean
queue_redraw (void *stage)
{
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
return TRUE;
}
void
test_readpixels (TestUtilsGTestFixture *fixture,
void *data)
{
unsigned int idle_source;
ClutterActor *stage;
stage = clutter_stage_get_default ();
clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
/* We force continuous redrawing of the stage, since we need to skip
* the first few frames, and we won't be doing anything else that
* will trigger redrawing. */
idle_source = g_idle_add (queue_redraw, stage);
g_signal_connect (CLUTTER_STAGE (stage), "after-paint", G_CALLBACK (on_after_paint), NULL);
clutter_actor_show (stage);
clutter_test_main ();
g_clear_handle_id (&idle_source, g_source_remove);
/* Remove all of the actors from the stage */
clutter_actor_remove_all_children (stage);
if (cogl_test_verbose ())
g_print ("OK\n");
}

View File

@@ -0,0 +1,138 @@
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <string.h>
#include "test-conform-common.h"
static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
#define TEX_SIZE 64
typedef struct _TestState
{
unsigned int padding;
} TestState;
/* Creates a texture where the pixels are evenly divided between
selecting just one of the R,G and B components */
static CoglHandle
make_texture (void)
{
guchar *tex_data = g_malloc (TEX_SIZE * TEX_SIZE * 3), *p = tex_data;
CoglHandle tex;
int x, y;
for (y = 0; y < TEX_SIZE; y++)
for (x = 0; x < TEX_SIZE; x++)
{
memset (p, 0, 3);
/* Set one of the components to full. The components should be
evenly represented so that each gets a third of the
texture */
p[(p - tex_data) / (TEX_SIZE * TEX_SIZE * 3 / 3)] = 255;
p += 3;
}
tex = test_utils_texture_new_from_data (TEX_SIZE, TEX_SIZE, TEST_UTILS_TEXTURE_NONE,
COGL_PIXEL_FORMAT_RGB_888,
COGL_PIXEL_FORMAT_ANY,
TEX_SIZE * 3,
tex_data);
g_free (tex_data);
return tex;
}
static void
on_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{
CoglHandle tex;
CoglPipeline *pipeline;
uint8_t pixels[8];
tex = make_texture ();
pipeline = cogl_pipeline_new ();
cogl_pipeline_set_layer (pipeline, 0, tex);
cogl_object_unref (tex);
/* Render a 1x1 pixel quad without mipmaps */
cogl_set_source (pipeline);
cogl_pipeline_set_layer_filters (pipeline, 0,
COGL_PIPELINE_FILTER_NEAREST,
COGL_PIPELINE_FILTER_NEAREST);
cogl_rectangle (0, 0, 1, 1);
/* Then with mipmaps */
cogl_pipeline_set_layer_filters (pipeline, 0,
COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST,
COGL_PIPELINE_FILTER_NEAREST);
cogl_rectangle (1, 0, 2, 1);
cogl_object_unref (pipeline);
/* Read back the two pixels we rendered */
cogl_read_pixels (0, 0, 2, 1,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
pixels);
/* The first pixel should be just one of the colors from the
texture. It doesn't matter which one */
g_assert ((pixels[0] == 255 && pixels[1] == 0 && pixels[2] == 0) ||
(pixels[0] == 0 && pixels[1] == 255 && pixels[2] == 0) ||
(pixels[0] == 0 && pixels[1] == 0 && pixels[2] == 255));
/* The second pixel should be more or less the average of all of the
pixels in the texture. Each component gets a third of the image
so each component should be approximately 255/3 */
g_assert (ABS (pixels[4] - 255 / 3) <= 3 &&
ABS (pixels[5] - 255 / 3) <= 3 &&
ABS (pixels[6] - 255 / 3) <= 3);
/* Comment this out if you want visual feedback for what this test paints */
#if 1
clutter_test_quit ();
#endif
}
static gboolean
queue_redraw (void *stage)
{
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
return TRUE;
}
void
test_texture_mipmaps (TestUtilsGTestFixture *fixture,
void *data)
{
TestState state;
ClutterActor *stage;
ClutterActor *group;
unsigned int idle_source;
stage = clutter_stage_get_default ();
clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
group = clutter_actor_new ();
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
/* We force continuous redrawing of the stage, since we need to skip
* the first few frames, and we won't 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 (stage);
clutter_test_main ();
g_clear_handle_id (&idle_source, g_source_remove);
if (cogl_test_verbose ())
g_print ("OK\n");
}

View File

@@ -0,0 +1,247 @@
#include <clutter/clutter.h>
#include "test-conform-common.h"
static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
#ifdef COGL_HAS_XLIB
#include <clutter/x11/clutter-x11.h>
#include <cogl/cogl-texture-pixmap-x11.h>
#define PIXMAP_WIDTH 512
#define PIXMAP_HEIGHT 256
#define GRID_SQUARE_SIZE 16
/* Coordinates of a square that we'll update */
#define PIXMAP_CHANGE_X 1
#define PIXMAP_CHANGE_Y 1
typedef struct _TestState
{
ClutterActor *stage;
CoglHandle tfp;
Pixmap pixmap;
unsigned int frame_count;
Display *display;
} TestState;
static Pixmap
create_pixmap (TestState *state)
{
Pixmap pixmap;
XGCValues gc_values = { 0, };
GC black_gc, white_gc;
int screen = DefaultScreen (state->display);
int x, y;
pixmap = XCreatePixmap (state->display,
DefaultRootWindow (state->display),
PIXMAP_WIDTH, PIXMAP_HEIGHT,
DefaultDepth (state->display, screen));
gc_values.foreground = BlackPixel (state->display, screen);
black_gc = XCreateGC (state->display, pixmap, GCForeground, &gc_values);
gc_values.foreground = WhitePixel (state->display, screen);
white_gc = XCreateGC (state->display, pixmap, GCForeground, &gc_values);
/* Draw a grid of alternative black and white rectangles to the
pixmap */
for (y = 0; y < PIXMAP_HEIGHT / GRID_SQUARE_SIZE; y++)
for (x = 0; x < PIXMAP_WIDTH / GRID_SQUARE_SIZE; x++)
XFillRectangle (state->display, pixmap,
((x ^ y) & 1) ? black_gc : white_gc,
x * GRID_SQUARE_SIZE,
y * GRID_SQUARE_SIZE,
GRID_SQUARE_SIZE,
GRID_SQUARE_SIZE);
XFreeGC (state->display, black_gc);
XFreeGC (state->display, white_gc);
return pixmap;
}
static void
update_pixmap (TestState *state)
{
XGCValues gc_values = { 0, };
GC black_gc;
int screen = DefaultScreen (state->display);
gc_values.foreground = BlackPixel (state->display, screen);
black_gc = XCreateGC (state->display, state->pixmap,
GCForeground, &gc_values);
/* Fill in one the rectangles with black */
XFillRectangle (state->display, state->pixmap,
black_gc,
PIXMAP_CHANGE_X * GRID_SQUARE_SIZE,
PIXMAP_CHANGE_Y * GRID_SQUARE_SIZE,
GRID_SQUARE_SIZE, GRID_SQUARE_SIZE);
XFreeGC (state->display, black_gc);
}
static gboolean
check_paint (TestState *state, int x, int y, int scale)
{
uint8_t *data, *p, update_value = 0;
p = data = g_malloc (PIXMAP_WIDTH * PIXMAP_HEIGHT * 4);
cogl_read_pixels (x, y, PIXMAP_WIDTH / scale, PIXMAP_HEIGHT / scale,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
data);
for (y = 0; y < PIXMAP_HEIGHT / scale; y++)
for (x = 0; x < PIXMAP_WIDTH / scale; x++)
{
int grid_x = x * scale / GRID_SQUARE_SIZE;
int grid_y = y * scale / GRID_SQUARE_SIZE;
/* If this is the updatable square then we'll let it be either
color but we'll return which one it was */
if (grid_x == PIXMAP_CHANGE_X && grid_y == PIXMAP_CHANGE_Y)
{
if (x % (GRID_SQUARE_SIZE / scale) == 0 &&
y % (GRID_SQUARE_SIZE / scale) == 0)
update_value = *p;
else
g_assert_cmpint (p[0], ==, update_value);
g_assert (p[1] == update_value);
g_assert (p[2] == update_value);
p += 4;
}
else
{
uint8_t value = ((grid_x ^ grid_y) & 1) ? 0x00 : 0xff;
g_assert_cmpint (*(p++), ==, value);
g_assert_cmpint (*(p++), ==, value);
g_assert_cmpint (*(p++), ==, value);
p++;
}
}
g_free (data);
return update_value == 0x00;
}
/* We skip these frames first */
#define FRAME_COUNT_BASE 5
/* First paint the tfp with no mipmaps */
#define FRAME_COUNT_NORMAL 6
/* Then use mipmaps */
#define FRAME_COUNT_MIPMAP 7
/* After this frame will start waiting for the pixmap to change */
#define FRAME_COUNT_UPDATED 8
static void
on_after_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
TestState *state)
{
CoglPipeline *pipeline;
pipeline = cogl_pipeline_new ();
cogl_pipeline_set_layer (pipeline, 0, state->tfp);
if (state->frame_count == FRAME_COUNT_MIPMAP)
{
const CoglPipelineFilter min_filter =
COGL_PIPELINE_FILTER_NEAREST_MIPMAP_NEAREST;;
cogl_pipeline_set_layer_filters (pipeline, 0,
min_filter,
COGL_PIPELINE_FILTER_NEAREST);
}
else
cogl_pipeline_set_layer_filters (pipeline, 0,
COGL_PIPELINE_FILTER_NEAREST,
COGL_PIPELINE_FILTER_NEAREST);
cogl_set_source (pipeline);
cogl_rectangle (0, 0, PIXMAP_WIDTH, PIXMAP_HEIGHT);
cogl_rectangle (0, PIXMAP_HEIGHT,
PIXMAP_WIDTH / 4, PIXMAP_HEIGHT * 5 / 4);
if (state->frame_count >= 5)
{
gboolean big_updated, small_updated;
big_updated = check_paint (state, 0, 0, 1);
small_updated = check_paint (state, 0, PIXMAP_HEIGHT, 4);
g_assert (big_updated == small_updated);
if (state->frame_count < FRAME_COUNT_UPDATED)
g_assert (big_updated == FALSE);
else if (state->frame_count == FRAME_COUNT_UPDATED)
/* Change the pixmap and keep drawing until it updates */
update_pixmap (state);
else if (big_updated)
/* If we successfully got the update then the test is over */
clutter_test_quit ();
}
state->frame_count++;
}
static gboolean
queue_redraw (void *stage)
{
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
return TRUE;
}
#endif /* COGL_HAS_XLIB */
void
test_texture_pixmap_x11 (TestUtilsGTestFixture *fixture,
void *data)
{
#ifdef COGL_HAS_XLIB
TestState state;
unsigned int idle_handler;
unsigned long paint_handler;
state.frame_count = 0;
state.stage = clutter_stage_get_default ();
state.display = clutter_x11_get_default_display ();
state.pixmap = create_pixmap (&state);
state.tfp = cogl_texture_pixmap_x11_new (state.pixmap, TRUE);
clutter_actor_set_background_color (CLUTTER_ACTOR (state.stage), &stage_color);
paint_handler = g_signal_connect (CLUTTER_STAGE (state.stage), "after-paint",
G_CALLBACK (on_after_paint), &state);
idle_handler = g_idle_add (queue_redraw, state.stage);
clutter_actor_show (state.stage);
clutter_test_main ();
g_clear_signal_handler (&paint_handler, state.stage);
g_clear_handle_id (&idle_handler, g_source_remove);
XFreePixmap (state.display, state.pixmap);
if (cogl_test_verbose ())
g_print ("OK\n");
#else /* COGL_HAS_XLIB */
if (cogl_test_verbose ())
g_print ("Skipping\n");
#endif /* COGL_HAS_XLIB */
}

View File

@@ -0,0 +1,416 @@
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include "test-conform-common.h"
#define RED 0
#define GREEN 1
#define BLUE 2
#define ALPHA 3
#define FRAMEBUFFER_WIDTH 640
#define FRAMEBUFFER_HEIGHT 480
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
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 &&
pixel[ALPHA] == alpha);
#endif
}
g_free (data);
}
static void
assert_rectangle_color_and_black_border (int x,
int y,
int width,
int height,
uint8_t red,
uint8_t green,
uint8_t blue)
{
/* check the rectangle itself... */
assert_region_color (x, y, width, height, red, green, blue, 0xff);
/* black to left of the rectangle */
assert_region_color (x-10, y-10, 10, height+20, 0x00, 0x00, 0x00, 0xff);
/* black to right of the rectangle */
assert_region_color (x+width, y-10, 10, height+20, 0x00, 0x00, 0x00, 0xff);
/* black above the rectangle */
assert_region_color (x-10, y-10, width+20, 10, 0x00, 0x00, 0x00, 0xff);
/* and black below the rectangle */
assert_region_color (x-10, y+height, width+20, 10, 0x00, 0x00, 0x00, 0xff);
}
static void
on_after_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
void *state)
{
float saved_viewport[4];
graphene_matrix_t saved_projection;
graphene_matrix_t projection;
graphene_matrix_t modelview;
guchar *data;
CoglHandle tex;
CoglHandle offscreen;
CoglColor black;
float x0;
float y0;
float width;
float height;
/* for clearing the offscreen framebuffer to black... */
cogl_color_init_from_4ub (&black, 0x00, 0x00, 0x00, 0xff);
cogl_get_viewport (saved_viewport);
cogl_get_projection_matrix (&saved_projection);
cogl_push_matrix ();
graphene_matrix_init_identity (&projection);
graphene_matrix_init_identity (&modelview);
cogl_set_projection_matrix (&projection);
cogl_set_modelview_matrix (&modelview);
/* - Create a 100x200 viewport (i.e. smaller than the onscreen framebuffer)
* and position it a (20, 10) inside the framebuffer.
* - Fill the whole viewport with a purple rectangle
* - Verify that the framebuffer is black with a 100x200 purple rectangle at
* (20, 10)
*/
cogl_set_viewport (20, /* x */
10, /* y */
100, /* width */
200); /* height */
/* clear everything... */
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
/* fill the viewport with purple.. */
cogl_set_source_color4ub (0xff, 0x00, 0xff, 0xff);
cogl_rectangle (-1, 1, 1, -1);
assert_rectangle_color_and_black_border (20, 10, 100, 200,
0xff, 0x00, 0xff);
/* - Create a viewport twice the size of the onscreen framebuffer with
* a negative offset positioning it at (-20, -10) relative to the
* buffer itself.
* - Draw a 100x200 green rectangle at (40, 20) within the viewport (which
* is (20, 10) within the framebuffer)
* - Verify that the framebuffer is black with a 100x200 green rectangle at
* (20, 10)
*/
cogl_set_viewport (-20, /* x */
-10, /* y */
FRAMEBUFFER_WIDTH * 2, /* width */
FRAMEBUFFER_HEIGHT * 2); /* height */
/* clear everything... */
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
/* draw a 100x200 green rectangle offset into the viewport such that its
* top left corner should be found at (20, 10) in the offscreen buffer */
/* (offset 40 pixels right from the left of the viewport) */
x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f;
/* (offset 20 pixels down from the top of the viewport) */
y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f;
width = (1.0f / FRAMEBUFFER_WIDTH) * 100;
height = (1.0f / FRAMEBUFFER_HEIGHT) * 200;
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
cogl_rectangle (x0, y0, x0 + width, y0 - height);
assert_rectangle_color_and_black_border (20, 10, 100, 200,
0x00, 0xff, 0x00);
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
* buffer.
* - Push a 100x200 window space clip rectangle at (20, 10)
* - Fill the whole viewport with a blue rectangle
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
* (20, 10)
*/
cogl_set_viewport (20, /* x */
10, /* y */
200, /* width */
400); /* height */
/* clear everything... */
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
cogl_clip_push_window_rectangle (20, 10, 100, 200);
/* fill the viewport with blue.. */
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
cogl_rectangle (-1, 1, 1, -1);
cogl_clip_pop ();
assert_rectangle_color_and_black_border (20, 10, 100, 200,
0x00, 0x00, 0xff);
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
* buffer.
* - Push a 100x200 model space clip rectangle at (20, 10) in the viewport
* (i.e. (40, 20) inside the framebuffer)
* - Fill the whole viewport with a green rectangle
* - Verify that the framebuffer is black with a 100x200 green rectangle at
* (40, 20)
*/
cogl_set_viewport (20, /* x */
10, /* y */
200, /* width */
400); /* height */
/* clear everything... */
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
/* figure out where to position our clip rectangle in model space
* coordinates... */
/* (offset 40 pixels right from the left of the viewport) */
x0 = -1.0f + (2.0f / 200) * 20.f;
/* (offset 20 pixels down from the top of the viewport) */
y0 = 1.0f - (2.0f / 400) * 10.0f;
width = (2.0f / 200) * 100;
height = (2.0f / 400) * 200;
/* add the clip rectangle... */
cogl_push_matrix ();
cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0);
/* XXX: Rotate just enough to stop Cogl from converting our model space
* rectangle into a window space rectangle.. */
cogl_rotate (0.1, 0, 0, 1);
cogl_clip_push_rectangle (-(width/2.0), -(height/2.0),
width/2.0, height/2.0);
cogl_pop_matrix ();
/* fill the viewport with green.. */
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
cogl_rectangle (-1, 1, 1, -1);
cogl_clip_pop ();
assert_rectangle_color_and_black_border (40, 20, 100, 200,
0x00, 0xff, 0x00);
/* Set the viewport to something specific so we can verify that it gets
* restored after we are done testing with an offscreen framebuffer... */
cogl_set_viewport (20, 10, 100, 200);
/*
* Next test offscreen drawing...
*/
data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
tex = test_utils_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
TEST_UTILS_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */
COGL_PIXEL_FORMAT_ANY, /* internal fmt */
FRAMEBUFFER_WIDTH * 4, /* rowstride */
data);
g_free (data);
offscreen = cogl_offscreen_new_with_texture (tex);
cogl_push_framebuffer (offscreen);
/* - Create a 100x200 viewport (i.e. smaller than the offscreen framebuffer)
* and position it a (20, 10) inside the framebuffer.
* - Fill the whole viewport with a blue rectangle
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
* (20, 10)
*/
cogl_set_viewport (20, /* x */
10, /* y */
100, /* width */
200); /* height */
/* clear everything... */
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
/* fill the viewport with blue.. */
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
cogl_rectangle (-1, 1, 1, -1);
assert_rectangle_color_and_black_border (20, 10, 100, 200,
0x00, 0x00, 0xff);
/* - Create a viewport twice the size of the offscreen framebuffer with
* a negative offset positioning it at (-20, -10) relative to the
* buffer itself.
* - Draw a 100x200 red rectangle at (40, 20) within the viewport (which
* is (20, 10) within the framebuffer)
* - Verify that the framebuffer is black with a 100x200 red rectangle at
* (20, 10)
*/
cogl_set_viewport (-20, /* x */
-10, /* y */
FRAMEBUFFER_WIDTH * 2, /* width */
FRAMEBUFFER_HEIGHT * 2); /* height */
/* clear everything... */
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
/* draw a 100x200 red rectangle offset into the viewport such that its
* top left corner should be found at (20, 10) in the offscreen buffer */
/* (offset 40 pixels right from the left of the viewport) */
x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f;
/* (offset 20 pixels down from the top of the viewport) */
y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f;
width = (1.0f / FRAMEBUFFER_WIDTH) * 100;
height = (1.0f / FRAMEBUFFER_HEIGHT) * 200;
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
cogl_rectangle (x0, y0, x0 + width, y0 - height);
assert_rectangle_color_and_black_border (20, 10, 100, 200,
0xff, 0x00, 0x00);
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
* buffer.
* - Push a 100x200 window space clip rectangle at (20, 10)
* - Fill the whole viewport with a blue rectangle
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
* (20, 10)
*/
cogl_set_viewport (20, /* x */
10, /* y */
200, /* width */
400); /* height */
/* clear everything... */
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
cogl_clip_push_window_rectangle (20, 10, 100, 200);
/* fill the viewport with blue.. */
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
cogl_rectangle (-1, 1, 1, -1);
cogl_clip_pop ();
assert_rectangle_color_and_black_border (20, 10, 100, 200,
0x00, 0x00, 0xff);
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
* buffer.
* - Push a 100x200 model space clip rectangle at (20, 10) in the viewport
* (i.e. (40, 20) inside the framebuffer)
* - Fill the whole viewport with a green rectangle
* - Verify that the framebuffer is black with a 100x200 green rectangle at
* (40, 20)
*/
cogl_set_viewport (20, /* x */
10, /* y */
200, /* width */
400); /* height */
/* clear everything... */
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
/* figure out where to position our clip rectangle in model space
* coordinates... */
/* (offset 40 pixels right from the left of the viewport) */
x0 = -1.0f + (2.0f / 200) * 20.f;
/* (offset 20 pixels down from the top of the viewport) */
y0 = 1.0f - (2.0f / 400) * 10.0f;
width = (2.0f / 200) * 100;
height = (2.0f / 400) * 200;
/* add the clip rectangle... */
cogl_push_matrix ();
cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0);
/* XXX: Rotate just enough to stop Cogl from converting our model space
* rectangle into a window space rectangle.. */
cogl_rotate (0.1, 0, 0, 1);
cogl_clip_push_rectangle (-(width/2.0), -(height/2.0),
width/2, height/2);
cogl_pop_matrix ();
/* fill the viewport with green.. */
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
cogl_rectangle (-1, 1, 1, -1);
cogl_clip_pop ();
assert_rectangle_color_and_black_border (40, 20, 100, 200,
0x00, 0xff, 0x00);
/* Set the viewport to something obscure to verify that it gets
* replace when we switch back to the onscreen framebuffer... */
cogl_set_viewport (0, 0, 10, 10);
cogl_pop_framebuffer ();
g_object_unref (offscreen);
/*
* Verify that the previous onscreen framebuffer's viewport was restored
* by drawing a white rectangle across the whole viewport. This should
* draw a 100x200 rectangle at (20,10) relative to the onscreen draw
* buffer...
*/
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_rectangle (-1, 1, 1, -1);
assert_rectangle_color_and_black_border (20, 10, 100, 200,
0xff, 0xff, 0xff);
/* Uncomment to display the last contents of the offscreen framebuffer */
#if 1
graphene_matrix_init_identity (&projection);
graphene_matrix_init_identity (&modelview);
cogl_set_viewport (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
cogl_set_projection_matrix (&projection);
cogl_set_modelview_matrix (&modelview);
cogl_set_source_texture (tex);
cogl_rectangle (-1, 1, 1, -1);
#endif
cogl_object_unref (tex);
/* Finally restore the stage's original state... */
cogl_pop_matrix ();
cogl_set_projection_matrix (&saved_projection);
cogl_set_viewport (saved_viewport[0], saved_viewport[1],
saved_viewport[2], saved_viewport[3]);
/* Comment this out if you want visual feedback of what this test
* paints.
*/
clutter_test_quit ();
}
static gboolean
queue_redraw (void *stage)
{
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
return TRUE;
}
void
test_viewport (TestUtilsGTestFixture *fixture,
void *data)
{
unsigned int idle_source;
ClutterActor *stage;
stage = clutter_stage_get_default ();
clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
/* We force continuous redrawing of the stage, since we need to skip
* the first few frames, and we won't be doing anything else that
* will trigger redrawing. */
idle_source = g_idle_add (queue_redraw, stage);
g_signal_connect (CLUTTER_STAGE (stage), "after-paint", G_CALLBACK (on_after_paint), NULL);
clutter_actor_show (stage);
clutter_test_main ();
g_clear_handle_id (&idle_source, g_source_remove);
/* Remove all of the actors from the stage */
clutter_actor_remove_all_children (stage);
if (cogl_test_verbose ())
g_print ("OK\n");
}