mirror of
https://github.com/brl/mutter.git
synced 2025-08-09 18:04:44 +00:00
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:
@@ -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,
|
||||
|
208
src/tests/cogl/conform/test-multitexture.c
Normal file
208
src/tests/cogl/conform/test-multitexture.c
Normal 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");
|
||||
}
|
86
src/tests/cogl/conform/test-object.c
Normal file
86
src/tests/cogl/conform/test-object.c
Normal 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");
|
||||
}
|
||||
|
178
src/tests/cogl/conform/test-readpixels.c
Normal file
178
src/tests/cogl/conform/test-readpixels.c
Normal 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");
|
||||
}
|
||||
|
138
src/tests/cogl/conform/test-texture-mipmaps.c
Normal file
138
src/tests/cogl/conform/test-texture-mipmaps.c
Normal 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");
|
||||
}
|
247
src/tests/cogl/conform/test-texture-pixmap-x11.c
Normal file
247
src/tests/cogl/conform/test-texture-pixmap-x11.c
Normal 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 */
|
||||
}
|
||||
|
416
src/tests/cogl/conform/test-viewport.c
Normal file
416
src/tests/cogl/conform/test-viewport.c
Normal 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");
|
||||
}
|
||||
|
Reference in New Issue
Block a user