Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 The Chromium OS Authors. All rights reserved. |
| 3 | * Use of this source code is governed by a BSD-style license that can be |
| 4 | * found in the LICENSE file. |
| 5 | */ |
| 6 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 7 | #include "bs_drm.h" |
| 8 | |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 9 | #include <getopt.h> |
| 10 | #include <math.h> |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 11 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 12 | #define TABLE_LINEAR 0 |
| 13 | #define TABLE_NEGATIVE 1 |
| 14 | #define TABLE_POW 2 |
| 15 | #define TABLE_STEP 3 |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 16 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 17 | #define FLAG_INTERNAL 'i' |
| 18 | #define FLAG_EXTERNAL 'e' |
| 19 | #define FLAG_GAMMA 'g' |
| 20 | #define FLAG_LINEAR 'l' |
| 21 | #define FLAG_NEGATIVE 'n' |
| 22 | #define FLAG_TIME 't' |
| 23 | #define FLAG_CRTCS 'c' |
| 24 | #define FLAG_PERSIST 'p' |
| 25 | #define FLAG_STEP 's' |
| 26 | #define FLAG_HELP 'h' |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 27 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 28 | static struct option command_options[] = { { "internal", no_argument, NULL, FLAG_INTERNAL }, |
| 29 | { "external", no_argument, NULL, FLAG_EXTERNAL }, |
| 30 | { "gamma", required_argument, NULL, FLAG_GAMMA }, |
| 31 | { "linear", no_argument, NULL, FLAG_LINEAR }, |
| 32 | { "negative", no_argument, NULL, FLAG_NEGATIVE }, |
| 33 | { "time", required_argument, NULL, FLAG_TIME }, |
| 34 | { "crtcs", required_argument, NULL, FLAG_CRTCS }, |
| 35 | { "persist", no_argument, NULL, FLAG_PERSIST }, |
| 36 | { "step", no_argument, NULL, FLAG_STEP }, |
| 37 | { "help", no_argument, NULL, FLAG_HELP }, |
| 38 | { NULL, 0, NULL, 0 } }; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 39 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 40 | static void gamma_linear(uint16_t *table, int size) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 41 | { |
| 42 | int i; |
| 43 | for (i = 0; i < size; i++) { |
| 44 | float v = (float)(i) / (float)(size - 1); |
| 45 | v *= 65535.0f; |
| 46 | table[i] = (uint16_t)v; |
| 47 | } |
| 48 | } |
| 49 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 50 | static void gamma_inv(uint16_t *table, int size) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 51 | { |
| 52 | int i; |
| 53 | for (i = 0; i < size; i++) { |
| 54 | float v = (float)(size - 1 - i) / (float)(size - 1); |
| 55 | v *= 65535.0f; |
| 56 | table[i] = (uint16_t)v; |
| 57 | } |
| 58 | } |
| 59 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 60 | static void gamma_pow(uint16_t *table, int size, float p) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 61 | { |
| 62 | int i; |
| 63 | for (i = 0; i < size; i++) { |
| 64 | float v = (float)(i) / (float)(size - 1); |
| 65 | v = pow(v, p); |
| 66 | v *= 65535.0f; |
| 67 | table[i] = (uint16_t)v; |
| 68 | } |
| 69 | } |
| 70 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 71 | static void gamma_step(uint16_t *table, int size) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 72 | { |
| 73 | int i; |
| 74 | for (i = 0; i < size; i++) { |
| 75 | table[i] = (i < size / 2) ? 0 : 65535; |
| 76 | } |
| 77 | } |
| 78 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 79 | static void fsleep(double secs) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 80 | { |
| 81 | usleep((useconds_t)(1000000.0f * secs)); |
| 82 | } |
| 83 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 84 | static drmModeModeInfoPtr find_best_mode(int mode_count, drmModeModeInfoPtr modes) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 85 | { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 86 | assert(mode_count >= 0); |
| 87 | if (mode_count == 0) |
| 88 | return NULL; |
| 89 | |
| 90 | assert(modes); |
| 91 | |
| 92 | for (int m = 0; m < mode_count; m++) |
| 93 | if (modes[m].type & DRM_MODE_TYPE_PREFERRED) |
| 94 | return &modes[m]; |
| 95 | |
| 96 | return &modes[0]; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 97 | } |
| 98 | |
Dongseong Hwang | 9093afe | 2017-03-20 19:16:28 -0700 | [diff] [blame] | 99 | static bool draw_pattern(struct bs_mapper *mapper, struct gbm_bo *bo) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 100 | { |
Satyajit Sahu | b7e47dd | 2018-05-07 12:35:50 +0530 | [diff] [blame^] | 101 | uint32_t stride; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 102 | const uint32_t height = gbm_bo_get_height(bo); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 103 | const uint32_t stripw = gbm_bo_get_width(bo) / 256; |
| 104 | const uint32_t striph = height / 4; |
| 105 | |
Dongseong Hwang | 9093afe | 2017-03-20 19:16:28 -0700 | [diff] [blame] | 106 | void *map_data; |
Satyajit Sahu | b7e47dd | 2018-05-07 12:35:50 +0530 | [diff] [blame^] | 107 | uint8_t *bo_ptr = bs_mapper_map(mapper, bo, 0, &map_data, &stride); |
Dongseong Hwang | 9093afe | 2017-03-20 19:16:28 -0700 | [diff] [blame] | 108 | if (bo_ptr == MAP_FAILED) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 109 | bs_debug_error("failed to mmap buffer while drawing pattern"); |
| 110 | return false; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 111 | } |
Satyajit Sahu | b7e47dd | 2018-05-07 12:35:50 +0530 | [diff] [blame^] | 112 | const uint32_t bo_size = stride * height; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 113 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 114 | bool success = true; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 115 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 116 | memset(bo_ptr, 0, bo_size); |
| 117 | for (uint32_t s = 0; s < 4; s++) { |
| 118 | uint8_t r = 0, g = 0, b = 0; |
| 119 | switch (s) { |
| 120 | case 0: |
| 121 | r = g = b = 1; |
| 122 | break; |
| 123 | case 1: |
| 124 | r = 1; |
| 125 | break; |
| 126 | case 2: |
| 127 | g = 1; |
| 128 | break; |
| 129 | case 3: |
| 130 | b = 1; |
| 131 | break; |
| 132 | default: |
| 133 | assert("invalid strip" && false); |
| 134 | success = false; |
| 135 | goto out; |
| 136 | } |
| 137 | for (uint32_t y = s * striph; y < (s + 1) * striph; y++) { |
| 138 | uint8_t *row_ptr = &bo_ptr[y * stride]; |
| 139 | for (uint32_t i = 0; i < 256; i++) { |
| 140 | for (uint32_t x = i * stripw; x < (i + 1) * stripw; x++) { |
| 141 | row_ptr[x * 4 + 0] = b * i; |
| 142 | row_ptr[x * 4 + 1] = g * i; |
| 143 | row_ptr[x * 4 + 2] = r * i; |
| 144 | row_ptr[x * 4 + 3] = 0; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 145 | } |
| 146 | } |
| 147 | } |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 148 | } |
| 149 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 150 | out: |
Dongseong Hwang | 9093afe | 2017-03-20 19:16:28 -0700 | [diff] [blame] | 151 | bs_mapper_unmap(mapper, bo, map_data); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 152 | return success; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 153 | } |
| 154 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 155 | static int set_gamma(int fd, uint32_t crtc_id, int gamma_size, int gamma_table, float gamma) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 156 | { |
| 157 | int res; |
| 158 | uint16_t *r, *g, *b; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 159 | r = calloc(gamma_size, sizeof(*r)); |
| 160 | g = calloc(gamma_size, sizeof(*g)); |
| 161 | b = calloc(gamma_size, sizeof(*b)); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 162 | |
| 163 | printf("Setting gamma table %d\n", gamma_table); |
| 164 | switch (gamma_table) { |
| 165 | case TABLE_LINEAR: |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 166 | gamma_linear(r, gamma_size); |
| 167 | gamma_linear(g, gamma_size); |
| 168 | gamma_linear(b, gamma_size); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 169 | break; |
| 170 | case TABLE_NEGATIVE: |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 171 | gamma_inv(r, gamma_size); |
| 172 | gamma_inv(g, gamma_size); |
| 173 | gamma_inv(b, gamma_size); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 174 | break; |
| 175 | case TABLE_POW: |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 176 | gamma_pow(r, gamma_size, gamma); |
| 177 | gamma_pow(g, gamma_size, gamma); |
| 178 | gamma_pow(b, gamma_size, gamma); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 179 | break; |
| 180 | case TABLE_STEP: |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 181 | gamma_step(r, gamma_size); |
| 182 | gamma_step(g, gamma_size); |
| 183 | gamma_step(b, gamma_size); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 184 | break; |
| 185 | } |
| 186 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 187 | res = drmModeCrtcSetGamma(fd, crtc_id, gamma_size, r, g, b); |
| 188 | if (res) |
| 189 | bs_debug_error("drmModeCrtcSetGamma(%d) failed: %s", crtc_id, strerror(errno)); |
| 190 | free(r); |
| 191 | free(g); |
| 192 | free(b); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 193 | return res; |
| 194 | } |
| 195 | |
| 196 | void help(void) |
| 197 | { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 198 | printf( |
| 199 | "\ |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 200 | gamma test\n\ |
| 201 | command line options:\ |
| 202 | \n\ |
| 203 | --help - this\n\ |
| 204 | --linear - set linear gamma table\n\ |
| 205 | --negative - set negative linear gamma table\n\ |
| 206 | --step - set step gamma table\n\ |
| 207 | --gamma=f - set pow(gamma) gamma table with gamma=f\n\ |
| 208 | --time=f - set test time\n\ |
| 209 | --crtcs=n - set mask of crtcs to test\n\ |
| 210 | --persist - do not reset gamma table at the end of the test\n\ |
| 211 | --internal - display tests on internal display\n\ |
| 212 | --external - display tests on external display\n\ |
| 213 | "); |
| 214 | } |
| 215 | |
| 216 | int main(int argc, char **argv) |
| 217 | { |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 218 | int internal = 1; |
| 219 | int persist = 0; |
| 220 | float time = 5.0; |
| 221 | float gamma = 2.2f; |
| 222 | float table = TABLE_LINEAR; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 223 | uint32_t crtcs = 0xFFFF; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 224 | |
| 225 | for (;;) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 226 | int c = getopt_long(argc, argv, "", command_options, NULL); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 227 | |
| 228 | if (c == -1) |
| 229 | break; |
| 230 | |
| 231 | switch (c) { |
| 232 | case FLAG_HELP: |
| 233 | help(); |
| 234 | return 0; |
| 235 | |
| 236 | case FLAG_INTERNAL: |
| 237 | internal = 1; |
| 238 | break; |
| 239 | |
| 240 | case FLAG_EXTERNAL: |
| 241 | internal = 0; |
| 242 | break; |
| 243 | |
| 244 | case FLAG_GAMMA: |
| 245 | gamma = strtof(optarg, NULL); |
| 246 | table = TABLE_POW; |
| 247 | break; |
| 248 | |
| 249 | case FLAG_LINEAR: |
| 250 | table = TABLE_LINEAR; |
| 251 | break; |
| 252 | |
| 253 | case FLAG_NEGATIVE: |
| 254 | table = TABLE_NEGATIVE; |
| 255 | break; |
| 256 | |
| 257 | case FLAG_STEP: |
| 258 | table = TABLE_STEP; |
| 259 | break; |
| 260 | |
| 261 | case FLAG_TIME: |
| 262 | time = strtof(optarg, NULL); |
| 263 | break; |
| 264 | |
| 265 | case FLAG_CRTCS: |
| 266 | crtcs = strtoul(optarg, NULL, 0); |
| 267 | break; |
| 268 | |
| 269 | case FLAG_PERSIST: |
| 270 | persist = 1; |
| 271 | break; |
| 272 | } |
| 273 | } |
| 274 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 275 | drmModeConnector *connector = NULL; |
| 276 | struct bs_drm_pipe pipe = { 0 }; |
| 277 | struct bs_drm_pipe_plumber *plumber = bs_drm_pipe_plumber_new(); |
| 278 | bs_drm_pipe_plumber_connector_ptr(plumber, &connector); |
| 279 | bs_drm_pipe_plumber_crtc_mask(plumber, crtcs); |
| 280 | if (!internal) |
| 281 | bs_drm_pipe_plumber_connector_ranks(plumber, bs_drm_connectors_external_rank); |
| 282 | if (!bs_drm_pipe_plumber_make(plumber, &pipe)) { |
| 283 | bs_debug_error("failed to make pipe"); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 284 | return 1; |
| 285 | } |
| 286 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 287 | int fd = pipe.fd; |
| 288 | bs_drm_pipe_plumber_fd(plumber, fd); |
| 289 | drmModeRes *resources = drmModeGetResources(fd); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 290 | if (!resources) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 291 | bs_debug_error("failed to get drm resources"); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 292 | return 1; |
| 293 | } |
| 294 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 295 | struct gbm_device *gbm = gbm_create_device(fd); |
| 296 | if (!gbm) { |
| 297 | bs_debug_error("failed to create gbm"); |
| 298 | return 1; |
| 299 | } |
| 300 | |
Shirish S | 99c916e | 2017-07-07 15:57:57 +0530 | [diff] [blame] | 301 | struct bs_mapper *mapper = bs_mapper_gem_new(); |
Dongseong Hwang | 9093afe | 2017-03-20 19:16:28 -0700 | [diff] [blame] | 302 | if (mapper == NULL) { |
| 303 | bs_debug_error("failed to create mapper object"); |
| 304 | return 1; |
| 305 | } |
| 306 | |
Gurchetan Singh | 5dd7b70 | 2017-02-24 17:56:33 -0800 | [diff] [blame] | 307 | uint32_t num_success = 0; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 308 | for (int c = 0; c < resources->count_crtcs && (crtcs >> c); c++) { |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 309 | int ret; |
| 310 | drmModeCrtc *crtc; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 311 | uint32_t crtc_mask = 1u << c; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 312 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 313 | if (!(crtcs & crtc_mask)) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 314 | continue; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 315 | |
| 316 | if (connector != NULL) { |
| 317 | drmModeFreeConnector(connector); |
| 318 | connector = NULL; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 319 | } |
| 320 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 321 | bs_drm_pipe_plumber_crtc_mask(plumber, crtc_mask); |
| 322 | if (!bs_drm_pipe_plumber_make(plumber, &pipe)) { |
Gurchetan Singh | 5dd7b70 | 2017-02-24 17:56:33 -0800 | [diff] [blame] | 323 | printf("unable to make pipe with crtc mask: %x\n", crtc_mask); |
| 324 | continue; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 325 | } |
| 326 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 327 | crtc = drmModeGetCrtc(fd, pipe.crtc_id); |
| 328 | if (!crtc) { |
| 329 | bs_debug_error("drmModeGetCrtc(%d) failed: %s\n", pipe.crtc_id, |
| 330 | strerror(errno)); |
| 331 | return 1; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 332 | } |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 333 | int gamma_size = crtc->gamma_size; |
| 334 | drmModeFreeCrtc(crtc); |
| 335 | |
| 336 | if (!gamma_size) { |
| 337 | bs_debug_error("CRTC %d has no gamma table", crtc->crtc_id); |
| 338 | continue; |
| 339 | } |
| 340 | |
| 341 | printf("CRTC:%d gamma size:%d\n", pipe.crtc_id, gamma_size); |
| 342 | |
| 343 | printf("Using CRTC:%u ENCODER:%u CONNECTOR:%u\n", pipe.crtc_id, pipe.encoder_id, |
| 344 | pipe.connector_id); |
| 345 | |
| 346 | drmModeModeInfoPtr mode = find_best_mode(connector->count_modes, connector->modes); |
| 347 | if (!mode) { |
| 348 | bs_debug_error("Could not find mode for CRTC %d", pipe.crtc_id); |
| 349 | continue; |
| 350 | } |
| 351 | |
| 352 | printf("Using mode %s\n", mode->name); |
| 353 | |
| 354 | printf("Creating buffer %ux%u\n", mode->hdisplay, mode->vdisplay); |
| 355 | struct gbm_bo *bo = |
Zach Reizner | a21d9eb | 2016-09-28 11:40:13 -0700 | [diff] [blame] | 356 | gbm_bo_create(gbm, mode->hdisplay, mode->vdisplay, GBM_FORMAT_XRGB8888, |
Gurchetan Singh | 18a0599 | 2017-11-08 15:43:57 -0800 | [diff] [blame] | 357 | GBM_BO_USE_SCANOUT | GBM_BO_USE_SW_WRITE_RARELY); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 358 | if (!bo) { |
| 359 | bs_debug_error("failed to create buffer object"); |
| 360 | return 1; |
| 361 | } |
| 362 | |
| 363 | uint32_t fb_id = bs_drm_fb_create_gbm(bo); |
| 364 | if (!fb_id) { |
| 365 | bs_debug_error("failed to create frame buffer for buffer object"); |
| 366 | return 1; |
| 367 | } |
| 368 | |
Dongseong Hwang | 9093afe | 2017-03-20 19:16:28 -0700 | [diff] [blame] | 369 | if (!draw_pattern(mapper, bo)) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 370 | bs_debug_error("failed to draw pattern on buffer object"); |
| 371 | return 1; |
| 372 | } |
| 373 | |
| 374 | ret = drmModeSetCrtc(fd, pipe.crtc_id, fb_id, 0, 0, &pipe.connector_id, 1, mode); |
| 375 | if (ret < 0) { |
| 376 | bs_debug_error("Could not set mode on CRTC %d %s", pipe.crtc_id, |
| 377 | strerror(errno)); |
| 378 | return 1; |
| 379 | } |
| 380 | |
| 381 | ret = set_gamma(fd, pipe.crtc_id, gamma_size, table, gamma); |
| 382 | if (ret) |
| 383 | return ret; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 384 | |
| 385 | fsleep(time); |
| 386 | |
| 387 | if (!persist) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 388 | ret = set_gamma(fd, pipe.crtc_id, gamma_size, TABLE_LINEAR, 0.0f); |
| 389 | if (ret) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 390 | return ret; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 391 | } |
| 392 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 393 | ret = drmModeSetCrtc(fd, pipe.crtc_id, 0, 0, 0, NULL, 0, NULL); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 394 | if (ret < 0) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 395 | bs_debug_error("Could disable CRTC %d %s\n", pipe.crtc_id, strerror(errno)); |
Gurchetan Singh | 5dd7b70 | 2017-02-24 17:56:33 -0800 | [diff] [blame] | 396 | return 1; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 397 | } |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 398 | |
| 399 | drmModeRmFB(fd, fb_id); |
| 400 | gbm_bo_destroy(bo); |
Gurchetan Singh | 5dd7b70 | 2017-02-24 17:56:33 -0800 | [diff] [blame] | 401 | num_success++; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 402 | } |
Dongseong Hwang | 9093afe | 2017-03-20 19:16:28 -0700 | [diff] [blame] | 403 | bs_mapper_destroy(mapper); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 404 | |
| 405 | if (connector != NULL) { |
| 406 | drmModeFreeConnector(connector); |
| 407 | connector = NULL; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 408 | } |
| 409 | |
| 410 | drmModeFreeResources(resources); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 411 | bs_drm_pipe_plumber_destroy(&plumber); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 412 | |
Gurchetan Singh | 5dd7b70 | 2017-02-24 17:56:33 -0800 | [diff] [blame] | 413 | if (!num_success) { |
| 414 | bs_debug_error("unable to set gamma table on any CRTC"); |
| 415 | return 1; |
| 416 | } |
| 417 | |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 418 | return 0; |
| 419 | } |