tests: Port test-offscreen

This ports the test-offscreen test from being a Clutter test to a
straight Cogl test.

https://bugzilla.gnome.org/show_bug.cgi?id=668913

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2012-01-28 13:19:01 +00:00
parent ba89a00576
commit bd6810de10
3 changed files with 61 additions and 101 deletions

View File

@ -17,7 +17,6 @@ unported_test_sources = \
test-multitexture.c \ test-multitexture.c \
test-npot-texture.c \ test-npot-texture.c \
test-object.c \ test-object.c \
test-offscreen.c \
test-pixel-buffer.c \ test-pixel-buffer.c \
test-premult.c \ test-premult.c \
test-readpixels.c \ test-readpixels.c \
@ -47,6 +46,7 @@ test_sources = \
test-wrap-modes.c \ test-wrap-modes.c \
test-sub-texture.c \ test-sub-texture.c \
test-custom-attributes.c \ test-custom-attributes.c \
test-offscreen.c \
$(NULL) $(NULL)
test_conformance_SOURCES = $(common_sources) $(test_sources) test_conformance_SOURCES = $(common_sources) $(test_sources)

View File

@ -167,10 +167,11 @@ main (int argc, char **argv)
ADD_TEST ("/cogl/internal/bitmask", test_cogl_bitmask); ADD_TEST ("/cogl/internal/bitmask", test_cogl_bitmask);
ADD_TEST ("/cogl", test_cogl_offscreen);
/* left to the end because they aren't currently very orthogonal and tend to /* left to the end because they aren't currently very orthogonal and tend to
* break subsequent tests! */ * break subsequent tests! */
UNPORTED_TEST ("/cogl", test_cogl_viewport); UNPORTED_TEST ("/cogl", test_cogl_viewport);
UNPORTED_TEST ("/cogl", test_cogl_offscreen);
return g_test_run (); return g_test_run ();
} }

View File

@ -1,61 +1,66 @@
#include <clutter/clutter.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include "test-conform-common.h" #include "test-utils.h"
#define RED 0 #define RED 0
#define GREEN 1 #define GREEN 1
#define BLUE 2 #define BLUE 2
#define FRAMEBUFFER_WIDTH 640 typedef struct _TestState
#define FRAMEBUFFER_HEIGHT 480 {
CoglContext *context;
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; int fb_width;
int fb_height;
} TestState;
static void static void
on_paint (ClutterActor *actor, void *state) check_quadrant (TestState *state,
int qx,
int qy,
guint32 expected_rgba)
{ {
float saved_viewport[4]; /* The quadrants are all stuffed into the top right corner of the
CoglMatrix saved_projection; framebuffer */
CoglMatrix projection; int x = state->fb_width * qx / 4 + state->fb_width / 2;
CoglMatrix modelview; int y = state->fb_height * qy / 4;
guchar *data; int width = state->fb_width / 4;
CoglHandle tex; int height = state->fb_height / 4;
/* Subtract a two-pixel gap around the edges to allow some rounding
differences */
x += 2;
y += 2;
width -= 4;
height -= 4;
test_utils_check_region (x, y, width, height, expected_rgba);
}
static void
paint (TestState *state)
{
CoglTexture2D *tex_2d;
CoglTexture *tex;
CoglHandle offscreen; CoglHandle offscreen;
guint8 pixel[4];
/* Save the Clutter viewport/matrices and load identity matrices */ tex_2d = cogl_texture_2d_new_with_size (state->context,
state->fb_width,
state->fb_height,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
NULL);
tex = COGL_TEXTURE (tex_2d);
cogl_get_viewport (saved_viewport);
cogl_get_projection_matrix (&saved_projection);
cogl_push_matrix ();
cogl_matrix_init_identity (&projection);
cogl_matrix_init_identity (&modelview);
cogl_set_projection_matrix (&projection);
cogl_set_modelview_matrix (&modelview);
data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
tex = cogl_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
COGL_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_to_texture (tex); offscreen = cogl_offscreen_new_to_texture (tex);
/* Set a scale and translate transform on the window framebuffer before /* Set a scale and translate transform on the window framebuffer
* switching to the offscreen framebuffer so we can verify it gets restored * before switching to the offscreen framebuffer so we can verify it
* when we switch back * gets restored when we switch back
* *
* The test is going to draw a grid of 4 colors to a texture which we * The test is going to draw a grid of 4 colors to a texture which
* subsequently draw to the window with a fullscreen rectangle. This * we subsequently draw to the window with a fullscreen rectangle.
* transform will flip the texture left to right, scale it to a quater of the * This transform will flip the texture left to right, scale it to a
* window size and slide it to the top right of the window. * quarter of the window size and slide it to the top right of the
* window.
*/ */
cogl_translate (0.5, 0.5, 0); cogl_translate (0.5, 0.5, 0);
cogl_scale (-0.5, 0.5, 1); cogl_scale (-0.5, 0.5, 1);
@ -88,80 +93,34 @@ on_paint (ClutterActor *actor, void *state)
cogl_set_source_texture (tex); cogl_set_source_texture (tex);
cogl_rectangle (-1, 1, 1, -1); cogl_rectangle (-1, 1, 1, -1);
cogl_handle_unref (tex); cogl_object_unref (tex_2d);
/* NB: The texture is drawn flipped horizontally and scaled to fit in the /* NB: The texture is drawn flipped horizontally and scaled to fit in the
* top right corner of the window. */ * top right corner of the window. */
/* red, top right */ /* red, top right */
cogl_read_pixels (FRAMEBUFFER_WIDTH - 1, 0, 1, 1, check_quadrant (state, 1, 0, 0xff0000ff);
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
pixel);
g_assert (pixel[RED] == 0xff && pixel[GREEN] == 0x00 && pixel[BLUE] == 0x00);
/* green, top left */ /* green, top left */
cogl_read_pixels ((FRAMEBUFFER_WIDTH/2), 0, 1, 1, check_quadrant (state, 0, 0, 0x00ff00ff);
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
pixel);
g_assert (pixel[RED] == 0x00 && pixel[GREEN] == 0xff && pixel[BLUE] == 0x00);
/* blue, bottom right */ /* blue, bottom right */
cogl_read_pixels (FRAMEBUFFER_WIDTH - 1, (FRAMEBUFFER_HEIGHT/2) - 1, 1, 1, check_quadrant (state, 1, 1, 0x0000ffff);
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
pixel);
g_assert (pixel[RED] == 0x00 && pixel[GREEN] == 0x00 && pixel[BLUE] == 0xff);
/* white, bottom left */ /* white, bottom left */
cogl_read_pixels ((FRAMEBUFFER_WIDTH/2), (FRAMEBUFFER_HEIGHT/2) - 1, 1, 1, check_quadrant (state, 0, 1, 0xffffffff);
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
pixel);
g_assert (pixel[RED] == 0xff && pixel[GREEN] == 0xff && pixel[BLUE] == 0xff);
/* Comment this out if you want visual feedback of what this test
* paints.
*/
clutter_main_quit ();
}
static gboolean
queue_redraw (gpointer stage)
{
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
return TRUE;
} }
void void
test_cogl_offscreen (TestUtilsGTestFixture *fixture, test_cogl_offscreen (TestUtilsGTestFixture *fixture,
void *data) void *data)
{ {
unsigned int idle_source; TestUtilsSharedState *shared_state = data;
ClutterActor *stage; TestState state;
stage = clutter_stage_get_default (); state.context = shared_state->ctx;
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); state.fb_width = cogl_framebuffer_get_width (shared_state->fb);
state.fb_height = cogl_framebuffer_get_height (shared_state->fb);
/* We force continuous redrawing of the stage, since we need to skip paint (&state);
* the first few frames, and we wont be doing anything else that
* will trigger redrawing. */
idle_source = g_idle_add (queue_redraw, stage);
g_signal_connect_after (stage, "paint", G_CALLBACK (on_paint), NULL);
clutter_actor_show (stage);
clutter_main ();
g_source_remove (idle_source);
/* Remove all of the actors from the stage */
clutter_container_foreach (CLUTTER_CONTAINER (stage),
(ClutterCallback) clutter_actor_destroy,
NULL);
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("OK\n"); g_print ("OK\n");
} }