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 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 99 | static bool draw_pattern(struct gbm_bo *bo) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 100 | { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 101 | const uint32_t stride = gbm_bo_get_stride(bo); |
| 102 | const uint32_t height = gbm_bo_get_height(bo); |
| 103 | const uint32_t bo_size = stride * height; |
| 104 | const uint32_t stripw = gbm_bo_get_width(bo) / 256; |
| 105 | const uint32_t striph = height / 4; |
| 106 | |
Dongseong Hwang | 2193f5c | 2016-04-22 17:25:58 +0300 | [diff] [blame] | 107 | uint8_t *bo_ptr = bs_dma_buf_mmap(bo); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 108 | if (!bo_ptr) { |
| 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 | } |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 112 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 113 | bool success = true; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 114 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 115 | memset(bo_ptr, 0, bo_size); |
| 116 | for (uint32_t s = 0; s < 4; s++) { |
| 117 | uint8_t r = 0, g = 0, b = 0; |
| 118 | switch (s) { |
| 119 | case 0: |
| 120 | r = g = b = 1; |
| 121 | break; |
| 122 | case 1: |
| 123 | r = 1; |
| 124 | break; |
| 125 | case 2: |
| 126 | g = 1; |
| 127 | break; |
| 128 | case 3: |
| 129 | b = 1; |
| 130 | break; |
| 131 | default: |
| 132 | assert("invalid strip" && false); |
| 133 | success = false; |
| 134 | goto out; |
| 135 | } |
| 136 | for (uint32_t y = s * striph; y < (s + 1) * striph; y++) { |
| 137 | uint8_t *row_ptr = &bo_ptr[y * stride]; |
| 138 | for (uint32_t i = 0; i < 256; i++) { |
| 139 | for (uint32_t x = i * stripw; x < (i + 1) * stripw; x++) { |
| 140 | row_ptr[x * 4 + 0] = b * i; |
| 141 | row_ptr[x * 4 + 1] = g * i; |
| 142 | row_ptr[x * 4 + 2] = r * i; |
| 143 | row_ptr[x * 4 + 3] = 0; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 144 | } |
| 145 | } |
| 146 | } |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 147 | } |
| 148 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 149 | out: |
Dongseong Hwang | 2193f5c | 2016-04-22 17:25:58 +0300 | [diff] [blame] | 150 | bs_dma_buf_unmmap(bo, bo_ptr); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 151 | return success; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 152 | } |
| 153 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 154 | 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] | 155 | { |
| 156 | int res; |
| 157 | uint16_t *r, *g, *b; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 158 | r = calloc(gamma_size, sizeof(*r)); |
| 159 | g = calloc(gamma_size, sizeof(*g)); |
| 160 | b = calloc(gamma_size, sizeof(*b)); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 161 | |
| 162 | printf("Setting gamma table %d\n", gamma_table); |
| 163 | switch (gamma_table) { |
| 164 | case TABLE_LINEAR: |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 165 | gamma_linear(r, gamma_size); |
| 166 | gamma_linear(g, gamma_size); |
| 167 | gamma_linear(b, gamma_size); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 168 | break; |
| 169 | case TABLE_NEGATIVE: |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 170 | gamma_inv(r, gamma_size); |
| 171 | gamma_inv(g, gamma_size); |
| 172 | gamma_inv(b, gamma_size); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 173 | break; |
| 174 | case TABLE_POW: |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 175 | gamma_pow(r, gamma_size, gamma); |
| 176 | gamma_pow(g, gamma_size, gamma); |
| 177 | gamma_pow(b, gamma_size, gamma); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 178 | break; |
| 179 | case TABLE_STEP: |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 180 | gamma_step(r, gamma_size); |
| 181 | gamma_step(g, gamma_size); |
| 182 | gamma_step(b, gamma_size); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 183 | break; |
| 184 | } |
| 185 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 186 | res = drmModeCrtcSetGamma(fd, crtc_id, gamma_size, r, g, b); |
| 187 | if (res) |
| 188 | bs_debug_error("drmModeCrtcSetGamma(%d) failed: %s", crtc_id, strerror(errno)); |
| 189 | free(r); |
| 190 | free(g); |
| 191 | free(b); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 192 | return res; |
| 193 | } |
| 194 | |
| 195 | void help(void) |
| 196 | { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 197 | printf( |
| 198 | "\ |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 199 | gamma test\n\ |
| 200 | command line options:\ |
| 201 | \n\ |
| 202 | --help - this\n\ |
| 203 | --linear - set linear gamma table\n\ |
| 204 | --negative - set negative linear gamma table\n\ |
| 205 | --step - set step gamma table\n\ |
| 206 | --gamma=f - set pow(gamma) gamma table with gamma=f\n\ |
| 207 | --time=f - set test time\n\ |
| 208 | --crtcs=n - set mask of crtcs to test\n\ |
| 209 | --persist - do not reset gamma table at the end of the test\n\ |
| 210 | --internal - display tests on internal display\n\ |
| 211 | --external - display tests on external display\n\ |
| 212 | "); |
| 213 | } |
| 214 | |
| 215 | int main(int argc, char **argv) |
| 216 | { |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 217 | int internal = 1; |
| 218 | int persist = 0; |
| 219 | float time = 5.0; |
| 220 | float gamma = 2.2f; |
| 221 | float table = TABLE_LINEAR; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 222 | uint32_t crtcs = 0xFFFF; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 223 | |
| 224 | for (;;) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 225 | int c = getopt_long(argc, argv, "", command_options, NULL); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 226 | |
| 227 | if (c == -1) |
| 228 | break; |
| 229 | |
| 230 | switch (c) { |
| 231 | case FLAG_HELP: |
| 232 | help(); |
| 233 | return 0; |
| 234 | |
| 235 | case FLAG_INTERNAL: |
| 236 | internal = 1; |
| 237 | break; |
| 238 | |
| 239 | case FLAG_EXTERNAL: |
| 240 | internal = 0; |
| 241 | break; |
| 242 | |
| 243 | case FLAG_GAMMA: |
| 244 | gamma = strtof(optarg, NULL); |
| 245 | table = TABLE_POW; |
| 246 | break; |
| 247 | |
| 248 | case FLAG_LINEAR: |
| 249 | table = TABLE_LINEAR; |
| 250 | break; |
| 251 | |
| 252 | case FLAG_NEGATIVE: |
| 253 | table = TABLE_NEGATIVE; |
| 254 | break; |
| 255 | |
| 256 | case FLAG_STEP: |
| 257 | table = TABLE_STEP; |
| 258 | break; |
| 259 | |
| 260 | case FLAG_TIME: |
| 261 | time = strtof(optarg, NULL); |
| 262 | break; |
| 263 | |
| 264 | case FLAG_CRTCS: |
| 265 | crtcs = strtoul(optarg, NULL, 0); |
| 266 | break; |
| 267 | |
| 268 | case FLAG_PERSIST: |
| 269 | persist = 1; |
| 270 | break; |
| 271 | } |
| 272 | } |
| 273 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 274 | drmModeConnector *connector = NULL; |
| 275 | struct bs_drm_pipe pipe = { 0 }; |
| 276 | struct bs_drm_pipe_plumber *plumber = bs_drm_pipe_plumber_new(); |
| 277 | bs_drm_pipe_plumber_connector_ptr(plumber, &connector); |
| 278 | bs_drm_pipe_plumber_crtc_mask(plumber, crtcs); |
| 279 | if (!internal) |
| 280 | bs_drm_pipe_plumber_connector_ranks(plumber, bs_drm_connectors_external_rank); |
| 281 | if (!bs_drm_pipe_plumber_make(plumber, &pipe)) { |
| 282 | bs_debug_error("failed to make pipe"); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 283 | return 1; |
| 284 | } |
| 285 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 286 | int fd = pipe.fd; |
| 287 | bs_drm_pipe_plumber_fd(plumber, fd); |
| 288 | drmModeRes *resources = drmModeGetResources(fd); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 289 | if (!resources) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 290 | bs_debug_error("failed to get drm resources"); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 291 | return 1; |
| 292 | } |
| 293 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 294 | struct gbm_device *gbm = gbm_create_device(fd); |
| 295 | if (!gbm) { |
| 296 | bs_debug_error("failed to create gbm"); |
| 297 | return 1; |
| 298 | } |
| 299 | |
| 300 | for (int c = 0; c < resources->count_crtcs && (crtcs >> c); c++) { |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 301 | int ret; |
| 302 | drmModeCrtc *crtc; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 303 | uint32_t crtc_mask = 1u << c; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 304 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 305 | if (!(crtcs & crtc_mask)) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 306 | continue; |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 307 | |
| 308 | if (connector != NULL) { |
| 309 | drmModeFreeConnector(connector); |
| 310 | connector = NULL; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 311 | } |
| 312 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 313 | bs_drm_pipe_plumber_crtc_mask(plumber, crtc_mask); |
| 314 | if (!bs_drm_pipe_plumber_make(plumber, &pipe)) { |
| 315 | bs_debug_error("failed to make pipe with crtc mask: %x", crtc_mask); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 316 | return 1; |
| 317 | } |
| 318 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 319 | crtc = drmModeGetCrtc(fd, pipe.crtc_id); |
| 320 | if (!crtc) { |
| 321 | bs_debug_error("drmModeGetCrtc(%d) failed: %s\n", pipe.crtc_id, |
| 322 | strerror(errno)); |
| 323 | return 1; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 324 | } |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 325 | int gamma_size = crtc->gamma_size; |
| 326 | drmModeFreeCrtc(crtc); |
| 327 | |
| 328 | if (!gamma_size) { |
| 329 | bs_debug_error("CRTC %d has no gamma table", crtc->crtc_id); |
| 330 | continue; |
| 331 | } |
| 332 | |
| 333 | printf("CRTC:%d gamma size:%d\n", pipe.crtc_id, gamma_size); |
| 334 | |
| 335 | printf("Using CRTC:%u ENCODER:%u CONNECTOR:%u\n", pipe.crtc_id, pipe.encoder_id, |
| 336 | pipe.connector_id); |
| 337 | |
| 338 | drmModeModeInfoPtr mode = find_best_mode(connector->count_modes, connector->modes); |
| 339 | if (!mode) { |
| 340 | bs_debug_error("Could not find mode for CRTC %d", pipe.crtc_id); |
| 341 | continue; |
| 342 | } |
| 343 | |
| 344 | printf("Using mode %s\n", mode->name); |
| 345 | |
| 346 | printf("Creating buffer %ux%u\n", mode->hdisplay, mode->vdisplay); |
| 347 | struct gbm_bo *bo = |
Zach Reizner | a21d9eb | 2016-09-28 11:40:13 -0700 | [diff] [blame] | 348 | gbm_bo_create(gbm, mode->hdisplay, mode->vdisplay, GBM_FORMAT_XRGB8888, |
| 349 | GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 350 | if (!bo) { |
| 351 | bs_debug_error("failed to create buffer object"); |
| 352 | return 1; |
| 353 | } |
| 354 | |
| 355 | uint32_t fb_id = bs_drm_fb_create_gbm(bo); |
| 356 | if (!fb_id) { |
| 357 | bs_debug_error("failed to create frame buffer for buffer object"); |
| 358 | return 1; |
| 359 | } |
| 360 | |
| 361 | if (!draw_pattern(bo)) { |
| 362 | bs_debug_error("failed to draw pattern on buffer object"); |
| 363 | return 1; |
| 364 | } |
| 365 | |
| 366 | ret = drmModeSetCrtc(fd, pipe.crtc_id, fb_id, 0, 0, &pipe.connector_id, 1, mode); |
| 367 | if (ret < 0) { |
| 368 | bs_debug_error("Could not set mode on CRTC %d %s", pipe.crtc_id, |
| 369 | strerror(errno)); |
| 370 | return 1; |
| 371 | } |
| 372 | |
| 373 | ret = set_gamma(fd, pipe.crtc_id, gamma_size, table, gamma); |
| 374 | if (ret) |
| 375 | return ret; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 376 | |
| 377 | fsleep(time); |
| 378 | |
| 379 | if (!persist) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 380 | ret = set_gamma(fd, pipe.crtc_id, gamma_size, TABLE_LINEAR, 0.0f); |
| 381 | if (ret) |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 382 | return ret; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 383 | } |
| 384 | |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 385 | ret = drmModeSetCrtc(fd, pipe.crtc_id, 0, 0, 0, NULL, 0, NULL); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 386 | if (ret < 0) { |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 387 | bs_debug_error("Could disable CRTC %d %s\n", pipe.crtc_id, strerror(errno)); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 388 | } |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 389 | |
| 390 | drmModeRmFB(fd, fb_id); |
| 391 | gbm_bo_destroy(bo); |
| 392 | } |
| 393 | |
| 394 | if (connector != NULL) { |
| 395 | drmModeFreeConnector(connector); |
| 396 | connector = NULL; |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 397 | } |
| 398 | |
| 399 | drmModeFreeResources(resources); |
Zach Reizner | 3415d06 | 2016-03-30 11:14:29 -0700 | [diff] [blame] | 400 | bs_drm_pipe_plumber_destroy(&plumber); |
Dominik Behr | e472630 | 2015-04-27 20:18:26 -0700 | [diff] [blame] | 401 | |
| 402 | return 0; |
| 403 | } |