179 lines
5.5 KiB
C
179 lines
5.5 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 FRAMEBUFFER_WIDTH 640
|
|
#define FRAMEBUFFER_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;
|
|
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 ();
|
|
|
|
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 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 ();
|
|
cogl_handle_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_handle_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_main_quit ();
|
|
}
|
|
|
|
static CoglBool
|
|
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_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
|
|
|
/* 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 (cogl_test_verbose ())
|
|
g_print ("OK\n");
|
|
}
|
|
|