kms_crtc_background_color.c 5.93 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * Copyright © 2013,2014 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 */

25
#include "igt.h"
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#include <math.h>


IGT_TEST_DESCRIPTION("Test crtc background color feature");

typedef struct {
	int gfx_fd;
	igt_display_t display;
	struct igt_fb fb;
	igt_crc_t ref_crc;
	igt_pipe_crc_t *pipe_crc;
} data_t;

#define BLACK      0x000000           /* BGR 8bpc */
#define CYAN       0xFFFF00           /* BGR 8bpc */
#define PURPLE     0xFF00FF           /* BGR 8bpc */
#define WHITE      0xFFFFFF           /* BGR 8bpc */

#define BLACK64    0x000000000000     /* BGR 16bpc */
#define CYAN64     0xFFFFFFFF0000     /* BGR 16bpc */
#define PURPLE64   0xFFFF0000FFFF     /* BGR 16bpc */
#define YELLOW64   0x0000FFFFFFFF     /* BGR 16bpc */
#define WHITE64    0xFFFFFFFFFFFF     /* BGR 16bpc */
#define RED64      0x00000000FFFF     /* BGR 16bpc */
#define GREEN64    0x0000FFFF0000     /* BGR 16bpc */
#define BLUE64     0xFFFF00000000     /* BGR 16bpc */

static void
paint_background(data_t *data, struct igt_fb *fb, drmModeModeInfo *mode,
		uint32_t background, double alpha)
{
	cairo_t *cr;
	int w, h;
	double r, g, b;

	w = mode->hdisplay;
	h = mode->vdisplay;

	cr = igt_get_cairo_ctx(data->gfx_fd, &data->fb);

	/* Paint with background color */
	r = (double) (background & 0xFF) / 255.0;
	g = (double) ((background & 0xFF00) >> 8) / 255.0;
	b = (double) ((background & 0xFF0000) >> 16) / 255.0;
	igt_paint_color_alpha(cr, 0, 0, w, h, r, g, b, alpha);

72
	igt_put_cairo_ctx(data->gfx_fd, &data->fb, cr);
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
}

static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
			igt_plane_t *plane, int opaque_buffer, int plane_color,
			uint64_t pipe_background_color)
{
	drmModeModeInfo *mode;
	igt_display_t *display = &data->display;
	int fb_id;
	double alpha;

	igt_output_set_pipe(output, pipe);

	/* create the pipe_crc object for this pipe */
	igt_pipe_crc_free(data->pipe_crc);
88
	data->pipe_crc = igt_pipe_crc_new(data->gfx_fd, pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
89 90 91 92 93 94 95 96 97 98 99

	mode = igt_output_get_mode(output);

	fb_id = igt_create_fb(data->gfx_fd,
			mode->hdisplay, mode->vdisplay,
			DRM_FORMAT_XRGB8888,
			LOCAL_DRM_FORMAT_MOD_NONE, /* tiled */
			&data->fb);
	igt_assert(fb_id);

	/* To make FB pixel win with background color, set alpha as full opaque */
100
	igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, pipe_background_color);
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
	if (opaque_buffer)
		alpha = 1.0;    /* alpha 1 is fully opque */
	else
		alpha = 0.0;    /* alpha 0 is fully transparent */
	paint_background(data, &data->fb, mode, plane_color, alpha);

	igt_plane_set_fb(plane, &data->fb);
	igt_display_commit2(display, COMMIT_UNIVERSAL);
}

static void cleanup_crtc(data_t *data, igt_output_t *output, igt_plane_t *plane)
{
	igt_display_t *display = &data->display;

	igt_pipe_crc_free(data->pipe_crc);
	data->pipe_crc = NULL;

	igt_remove_fb(data->gfx_fd, &data->fb);

120
	igt_pipe_obj_set_prop_value(plane->pipe, IGT_CRTC_BACKGROUND, BLACK64);
121 122 123 124 125 126 127 128 129 130 131 132 133
	igt_plane_set_fb(plane, NULL);
	igt_output_set_pipe(output, PIPE_ANY);

	igt_display_commit2(display, COMMIT_UNIVERSAL);
}

static void test_crtc_background(data_t *data)
{
	igt_display_t *display = &data->display;
	igt_output_t *output;
	enum pipe pipe;
	int valid_tests = 0;

134
	for_each_pipe_with_valid_output(display, pipe, output) {
135 136 137 138
		igt_plane_t *plane;

		igt_output_set_pipe(output, pipe);

139
		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
140
		igt_require(igt_pipe_has_prop(display, pipe, IGT_CRTC_BACKGROUND));
141 142 143 144 145 146

		prepare_crtc(data, output, pipe, plane, 1, PURPLE, BLACK64);

		/* Now set background without using a plane, i.e.,
		 * Disable the plane to let hw background color win blend. */
		igt_plane_set_fb(plane, NULL);
147
		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, PURPLE64);
148 149 150
		igt_display_commit2(display, COMMIT_UNIVERSAL);

		/* Try few other background colors */
151
		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, CYAN64);
152 153
		igt_display_commit2(display, COMMIT_UNIVERSAL);

154
		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, YELLOW64);
155 156
		igt_display_commit2(display, COMMIT_UNIVERSAL);

157
		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, RED64);
158 159
		igt_display_commit2(display, COMMIT_UNIVERSAL);

160
		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, GREEN64);
161 162
		igt_display_commit2(display, COMMIT_UNIVERSAL);

163
		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, BLUE64);
164 165
		igt_display_commit2(display, COMMIT_UNIVERSAL);

166
		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, WHITE64);
167 168 169 170 171 172 173 174 175 176 177 178 179 180
		igt_display_commit2(display, COMMIT_UNIVERSAL);

		valid_tests++;
		cleanup_crtc(data, output, plane);
	}
	igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
}

igt_simple_main
{
	data_t data = {};

	igt_skip_on_simulation();

181
	data.gfx_fd = drm_open_driver(DRIVER_INTEL);
182
	igt_require_pipe_crc(data.gfx_fd);
183
	igt_display_require(&data.display, data.gfx_fd);
184 185 186 187 188

	test_crtc_background(&data);

	igt_display_fini(&data.display);
}