mirror of
https://github.com/brl/mutter.git
synced 2024-12-26 21:02:14 +00:00
60b642f5d6
Mostly this was written to verify that we don't flip the data read back from an offscreen draw buffer. (since all offscreen rendering is done upside down)
154 lines
4.6 KiB
C
154 lines
4.6 KiB
C
|
|
#include <clutter/clutter.h>
|
|
#include <cogl/cogl.h>
|
|
|
|
#include "test-conform-common.h"
|
|
|
|
#define RED 0
|
|
#define GREEN 1
|
|
#define BLUE 2
|
|
|
|
#define DRAW_BUFFER_WIDTH 640
|
|
#define DRAW_BUFFER_HEIGHT 480
|
|
|
|
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
|
|
|
|
|
static void
|
|
on_paint (ClutterActor *actor, void *state)
|
|
{
|
|
float saved_viewport[4];
|
|
CoglMatrix saved_projection;
|
|
CoglMatrix projection;
|
|
CoglMatrix modelview;
|
|
guchar *data;
|
|
CoglHandle tex;
|
|
CoglHandle offscreen;
|
|
guint32 *pixels;
|
|
|
|
/* Save the Clutter viewport/matrices and load identity matrices */
|
|
|
|
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);
|
|
|
|
/* All offscreen rendering is done upside down so the first thing we
|
|
* verify is reading back grid of colors from a CoglOffscreen draw buffer
|
|
*/
|
|
|
|
data = g_malloc (DRAW_BUFFER_WIDTH * 4 * DRAW_BUFFER_HEIGHT);
|
|
tex = cogl_texture_new_from_data (DRAW_BUFFER_WIDTH, DRAW_BUFFER_HEIGHT,
|
|
COGL_TEXTURE_NO_SLICING,
|
|
COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */
|
|
COGL_PIXEL_FORMAT_ANY, /* internal fmt */
|
|
DRAW_BUFFER_WIDTH * 4, /* rowstride */
|
|
data);
|
|
g_free (data);
|
|
offscreen = cogl_offscreen_new_to_texture (tex);
|
|
|
|
cogl_push_draw_buffer ();
|
|
cogl_set_draw_buffer (0 /* unused */, 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 (DRAW_BUFFER_WIDTH * 4 * DRAW_BUFFER_HEIGHT);
|
|
cogl_read_pixels (0, 0, DRAW_BUFFER_WIDTH, DRAW_BUFFER_HEIGHT,
|
|
COGL_READ_PIXELS_COLOR_BUFFER,
|
|
COGL_PIXEL_FORMAT_RGBA_8888,
|
|
(guchar *)pixels);
|
|
|
|
g_assert (pixels[0] == 0xff0000ff);
|
|
g_assert (pixels[DRAW_BUFFER_WIDTH - 1] == 0xff00ff00);
|
|
g_assert (pixels[(DRAW_BUFFER_HEIGHT - 1) * DRAW_BUFFER_WIDTH] == 0xffff0000);
|
|
g_assert (pixels[(DRAW_BUFFER_HEIGHT - 1) * DRAW_BUFFER_WIDTH +
|
|
DRAW_BUFFER_WIDTH - 1] == 0xffffffff);
|
|
g_free (pixels);
|
|
|
|
cogl_pop_draw_buffer ();
|
|
cogl_handle_unref (offscreen);
|
|
|
|
/* Now verify reading back from an onscreen draw buffer...
|
|
*/
|
|
|
|
cogl_set_source_texture (tex);
|
|
cogl_rectangle (-1, 1, 1, -1);
|
|
|
|
pixels = g_malloc0 (DRAW_BUFFER_WIDTH * 4 * DRAW_BUFFER_HEIGHT);
|
|
cogl_read_pixels (0, 0, DRAW_BUFFER_WIDTH, DRAW_BUFFER_HEIGHT,
|
|
COGL_READ_PIXELS_COLOR_BUFFER,
|
|
COGL_PIXEL_FORMAT_RGBA_8888,
|
|
(guchar *)pixels);
|
|
|
|
g_assert (pixels[0] == 0xff0000ff);
|
|
g_assert (pixels[DRAW_BUFFER_WIDTH - 1] == 0xff00ff00);
|
|
g_assert (pixels[(DRAW_BUFFER_HEIGHT - 1) * DRAW_BUFFER_WIDTH] == 0xffff0000);
|
|
g_assert (pixels[(DRAW_BUFFER_HEIGHT - 1) * DRAW_BUFFER_WIDTH +
|
|
DRAW_BUFFER_WIDTH - 1] == 0xffffffff);
|
|
g_free (pixels);
|
|
|
|
cogl_handle_unref (tex);
|
|
|
|
|
|
/* 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
|
|
test_cogl_readpixels (TestConformSimpleFixture *fixture,
|
|
gconstpointer data)
|
|
{
|
|
guint idle_source;
|
|
ClutterActor *stage;
|
|
|
|
stage = clutter_stage_get_default ();
|
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
|
clutter_actor_set_size (stage, DRAW_BUFFER_WIDTH, DRAW_BUFFER_HEIGHT);
|
|
|
|
/* We force continuous redrawing of the stage, since we need to skip
|
|
* 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 ())
|
|
g_print ("OK\n");
|
|
}
|
|
|