blob: 9baf1a75682345903d52f655e55331e47f1a023b [file] [log] [blame]
Dominik Behre4726302015-04-27 20:18:26 -07001/*
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 Reizner3415d062016-03-30 11:14:29 -07007#include "bs_drm.h"
8
Dominik Behre4726302015-04-27 20:18:26 -07009#include <getopt.h>
10#include <math.h>
Dominik Behre4726302015-04-27 20:18:26 -070011
Zach Reizner3415d062016-03-30 11:14:29 -070012#define TABLE_LINEAR 0
13#define TABLE_NEGATIVE 1
14#define TABLE_POW 2
15#define TABLE_STEP 3
Miguel Casasa5d9ff22020-03-12 17:23:34 -040016// TABLE_PIECEWISE_HDR mimics Chrome's PIECEWISE_HDR gfx::ColorSpace::TranferID,
17// basically an sRGB up to a given elbow or joint, and linear after.
18#define TABLE_PIECEWISE_HDR 4
Dominik Behre4726302015-04-27 20:18:26 -070019
Zach Reizner3415d062016-03-30 11:14:29 -070020#define FLAG_INTERNAL 'i'
21#define FLAG_EXTERNAL 'e'
22#define FLAG_GAMMA 'g'
23#define FLAG_LINEAR 'l'
24#define FLAG_NEGATIVE 'n'
25#define FLAG_TIME 't'
26#define FLAG_CRTCS 'c'
27#define FLAG_PERSIST 'p'
28#define FLAG_STEP 's'
Miguel Casasa5d9ff22020-03-12 17:23:34 -040029#define FLAG_HDR 'x'
Zach Reizner3415d062016-03-30 11:14:29 -070030#define FLAG_HELP 'h'
Dominik Behre4726302015-04-27 20:18:26 -070031
Zach Reizner3415d062016-03-30 11:14:29 -070032static struct option command_options[] = { { "internal", no_argument, NULL, FLAG_INTERNAL },
33 { "external", no_argument, NULL, FLAG_EXTERNAL },
34 { "gamma", required_argument, NULL, FLAG_GAMMA },
35 { "linear", no_argument, NULL, FLAG_LINEAR },
36 { "negative", no_argument, NULL, FLAG_NEGATIVE },
37 { "time", required_argument, NULL, FLAG_TIME },
38 { "crtcs", required_argument, NULL, FLAG_CRTCS },
39 { "persist", no_argument, NULL, FLAG_PERSIST },
40 { "step", no_argument, NULL, FLAG_STEP },
Miguel Casasa5d9ff22020-03-12 17:23:34 -040041 { "hdr", required_argument, NULL, FLAG_HDR },
Zach Reizner3415d062016-03-30 11:14:29 -070042 { "help", no_argument, NULL, FLAG_HELP },
43 { NULL, 0, NULL, 0 } };
Dominik Behre4726302015-04-27 20:18:26 -070044
Zach Reizner3415d062016-03-30 11:14:29 -070045static void gamma_linear(uint16_t *table, int size)
Dominik Behre4726302015-04-27 20:18:26 -070046{
47 int i;
48 for (i = 0; i < size; i++) {
49 float v = (float)(i) / (float)(size - 1);
50 v *= 65535.0f;
51 table[i] = (uint16_t)v;
52 }
53}
54
Zach Reizner3415d062016-03-30 11:14:29 -070055static void gamma_inv(uint16_t *table, int size)
Dominik Behre4726302015-04-27 20:18:26 -070056{
57 int i;
58 for (i = 0; i < size; i++) {
59 float v = (float)(size - 1 - i) / (float)(size - 1);
60 v *= 65535.0f;
61 table[i] = (uint16_t)v;
62 }
63}
64
Zach Reizner3415d062016-03-30 11:14:29 -070065static void gamma_pow(uint16_t *table, int size, float p)
Dominik Behre4726302015-04-27 20:18:26 -070066{
67 int i;
68 for (i = 0; i < size; i++) {
69 float v = (float)(i) / (float)(size - 1);
70 v = pow(v, p);
71 v *= 65535.0f;
72 table[i] = (uint16_t)v;
73 }
74}
75
Zach Reizner3415d062016-03-30 11:14:29 -070076static void gamma_step(uint16_t *table, int size)
Dominik Behre4726302015-04-27 20:18:26 -070077{
78 int i;
79 for (i = 0; i < size; i++) {
80 table[i] = (i < size / 2) ? 0 : 65535;
81 }
82}
83
Miguel Casasa5d9ff22020-03-12 17:23:34 -040084static void gamma_piecewise_linear(uint16_t *table, int size, float joint)
85{
86 const float gamma = 1 / 2.2f;
87 // |joint_i| is the index in [0, size) where sRGB and linear curves meet.
88 const size_t joint_i = joint * size;
89 // |joint_v| is the gamma output value where sRGB and linear curves meet.
90 const float joint_v = pow(joint, gamma);
91 // |slope| is the slope of the linear part.
92 const float slope = (1 - joint_v) / (1 - joint);
93 int i;
94 for (i = 0; i < size; i++) {
95 float v = (float)(i) / (float)(size - 1);
96
97 if (i < joint_i)
98 v = pow(v, gamma);
99 else
100 v = joint_v + slope * (v - joint);
101
102 v *= 65535.0f;
103 table[i] = (uint16_t)v;
104 }
105}
106
107static const char* gamma_name(int gamma_table_id)
108{
109 const char *table_names[] = { "TABLE_LINEAR", "TABLE_NEGATIVE", "TABLE_POW", "TABLE_STEP",
110 "TABLE_PIECEWISE_HDR" };
111 const size_t max_gamma_table_id = sizeof(table_names)/sizeof(table_names[0]);
112 if (gamma_table_id >= max_gamma_table_id)
113 return NULL;
114 return table_names[gamma_table_id];
115}
116
Zach Reizner3415d062016-03-30 11:14:29 -0700117static void fsleep(double secs)
Dominik Behre4726302015-04-27 20:18:26 -0700118{
119 usleep((useconds_t)(1000000.0f * secs));
120}
121
Zach Reizner3415d062016-03-30 11:14:29 -0700122static drmModeModeInfoPtr find_best_mode(int mode_count, drmModeModeInfoPtr modes)
Dominik Behre4726302015-04-27 20:18:26 -0700123{
Zach Reizner3415d062016-03-30 11:14:29 -0700124 assert(mode_count >= 0);
125 if (mode_count == 0)
126 return NULL;
127
128 assert(modes);
129
130 for (int m = 0; m < mode_count; m++)
131 if (modes[m].type & DRM_MODE_TYPE_PREFERRED)
132 return &modes[m];
133
134 return &modes[0];
Dominik Behre4726302015-04-27 20:18:26 -0700135}
136
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400137static bool draw_pattern(struct bs_mapper *mapper, struct gbm_bo *bo, int gbm_format)
Dominik Behre4726302015-04-27 20:18:26 -0700138{
Satyajit Sahub7e47dd2018-05-07 12:35:50 +0530139 uint32_t stride;
Zach Reizner3415d062016-03-30 11:14:29 -0700140 const uint32_t height = gbm_bo_get_height(bo);
Zach Reizner3415d062016-03-30 11:14:29 -0700141 const uint32_t stripw = gbm_bo_get_width(bo) / 256;
142 const uint32_t striph = height / 4;
143
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400144 if (gbm_format != GBM_FORMAT_XRGB8888 && gbm_format != GBM_FORMAT_XRGB2101010)
145 return false;
146
Dongseong Hwang9093afe2017-03-20 19:16:28 -0700147 void *map_data;
Satyajit Sahub7e47dd2018-05-07 12:35:50 +0530148 uint8_t *bo_ptr = bs_mapper_map(mapper, bo, 0, &map_data, &stride);
Dongseong Hwang9093afe2017-03-20 19:16:28 -0700149 if (bo_ptr == MAP_FAILED) {
Zach Reizner3415d062016-03-30 11:14:29 -0700150 bs_debug_error("failed to mmap buffer while drawing pattern");
151 return false;
Dominik Behre4726302015-04-27 20:18:26 -0700152 }
Satyajit Sahub7e47dd2018-05-07 12:35:50 +0530153 const uint32_t bo_size = stride * height;
Dominik Behre4726302015-04-27 20:18:26 -0700154
Zach Reizner3415d062016-03-30 11:14:29 -0700155 bool success = true;
Dominik Behre4726302015-04-27 20:18:26 -0700156
Zach Reizner3415d062016-03-30 11:14:29 -0700157 memset(bo_ptr, 0, bo_size);
158 for (uint32_t s = 0; s < 4; s++) {
159 uint8_t r = 0, g = 0, b = 0;
160 switch (s) {
161 case 0:
162 r = g = b = 1;
163 break;
164 case 1:
165 r = 1;
166 break;
167 case 2:
168 g = 1;
169 break;
170 case 3:
171 b = 1;
172 break;
173 default:
174 assert("invalid strip" && false);
175 success = false;
176 goto out;
177 }
178 for (uint32_t y = s * striph; y < (s + 1) * striph; y++) {
179 uint8_t *row_ptr = &bo_ptr[y * stride];
180 for (uint32_t i = 0; i < 256; i++) {
181 for (uint32_t x = i * stripw; x < (i + 1) * stripw; x++) {
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400182 if (gbm_format == GBM_FORMAT_XRGB8888) {
183 row_ptr[x * 4 + 0] = b * i;
184 row_ptr[x * 4 + 1] = g * i;
185 row_ptr[x * 4 + 2] = r * i;
186 row_ptr[x * 4 + 3] = 0;
187 } else {
188 *(uint32_t *)(&row_ptr[x * 4]) =
189 (((r * i) << 2) | ((r * i) >> 6)) << 20 |
190 (((g * i) << 2) | ((g * i) >> 6)) << 10 |
191 (((b * i) << 2) | ((b * i) >> 6));
192 }
Dominik Behre4726302015-04-27 20:18:26 -0700193 }
194 }
195 }
Dominik Behre4726302015-04-27 20:18:26 -0700196 }
197
Zach Reizner3415d062016-03-30 11:14:29 -0700198out:
Dongseong Hwang9093afe2017-03-20 19:16:28 -0700199 bs_mapper_unmap(mapper, bo, map_data);
Zach Reizner3415d062016-03-30 11:14:29 -0700200 return success;
Dominik Behre4726302015-04-27 20:18:26 -0700201}
202
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400203// |parameter| is passed to the appropriate |gamma_table| generation function.
204static int set_gamma(int fd, uint32_t crtc_id, int gamma_size, int gamma_table, float parameter)
Dominik Behre4726302015-04-27 20:18:26 -0700205{
206 int res;
207 uint16_t *r, *g, *b;
Zach Reizner3415d062016-03-30 11:14:29 -0700208 r = calloc(gamma_size, sizeof(*r));
209 g = calloc(gamma_size, sizeof(*g));
210 b = calloc(gamma_size, sizeof(*b));
Dominik Behre4726302015-04-27 20:18:26 -0700211
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400212 printf("Setting gamma table index %d (%s)\n", gamma_table, gamma_name(gamma_table));
Dominik Behre4726302015-04-27 20:18:26 -0700213 switch (gamma_table) {
214 case TABLE_LINEAR:
Zach Reizner3415d062016-03-30 11:14:29 -0700215 gamma_linear(r, gamma_size);
216 gamma_linear(g, gamma_size);
217 gamma_linear(b, gamma_size);
Dominik Behre4726302015-04-27 20:18:26 -0700218 break;
219 case TABLE_NEGATIVE:
Zach Reizner3415d062016-03-30 11:14:29 -0700220 gamma_inv(r, gamma_size);
221 gamma_inv(g, gamma_size);
222 gamma_inv(b, gamma_size);
Dominik Behre4726302015-04-27 20:18:26 -0700223 break;
224 case TABLE_POW:
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400225 gamma_pow(r, gamma_size, parameter);
226 gamma_pow(g, gamma_size, parameter);
227 gamma_pow(b, gamma_size, parameter);
Dominik Behre4726302015-04-27 20:18:26 -0700228 break;
229 case TABLE_STEP:
Zach Reizner3415d062016-03-30 11:14:29 -0700230 gamma_step(r, gamma_size);
231 gamma_step(g, gamma_size);
232 gamma_step(b, gamma_size);
Dominik Behre4726302015-04-27 20:18:26 -0700233 break;
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400234 case TABLE_PIECEWISE_HDR:
235 gamma_piecewise_linear(r, gamma_size, parameter);
236 gamma_piecewise_linear(g, gamma_size, parameter);
237 gamma_piecewise_linear(b, gamma_size, parameter);
238 break;
Dominik Behre4726302015-04-27 20:18:26 -0700239 }
240
Zach Reizner3415d062016-03-30 11:14:29 -0700241 res = drmModeCrtcSetGamma(fd, crtc_id, gamma_size, r, g, b);
242 if (res)
243 bs_debug_error("drmModeCrtcSetGamma(%d) failed: %s", crtc_id, strerror(errno));
244 free(r);
245 free(g);
246 free(b);
Dominik Behre4726302015-04-27 20:18:26 -0700247 return res;
248}
249
250void help(void)
251{
Zach Reizner3415d062016-03-30 11:14:29 -0700252 printf(
253 "\
Dominik Behre4726302015-04-27 20:18:26 -0700254gamma test\n\
255command line options:\
256\n\
257--help - this\n\
258--linear - set linear gamma table\n\
259--negative - set negative linear gamma table\n\
260--step - set step gamma table\n\
261--gamma=f - set pow(gamma) gamma table with gamma=f\n\
262--time=f - set test time\n\
263--crtcs=n - set mask of crtcs to test\n\
264--persist - do not reset gamma table at the end of the test\n\
265--internal - display tests on internal display\n\
266--external - display tests on external display\n\
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400267--hdr=x - sets piecewise HDR gamma table with SDR-HDR joint at x (usually 0.5)\n\
Dominik Behre4726302015-04-27 20:18:26 -0700268");
269}
270
271int main(int argc, char **argv)
272{
Dominik Behre4726302015-04-27 20:18:26 -0700273 int internal = 1;
274 int persist = 0;
275 float time = 5.0;
276 float gamma = 2.2f;
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400277 float srgb_joint = 0.0f;
278 int table = TABLE_LINEAR;
Zach Reizner3415d062016-03-30 11:14:29 -0700279 uint32_t crtcs = 0xFFFF;
Dominik Behre4726302015-04-27 20:18:26 -0700280
281 for (;;) {
Zach Reizner3415d062016-03-30 11:14:29 -0700282 int c = getopt_long(argc, argv, "", command_options, NULL);
Dominik Behre4726302015-04-27 20:18:26 -0700283
284 if (c == -1)
285 break;
286
287 switch (c) {
288 case FLAG_HELP:
289 help();
290 return 0;
291
292 case FLAG_INTERNAL:
293 internal = 1;
294 break;
295
296 case FLAG_EXTERNAL:
297 internal = 0;
298 break;
299
300 case FLAG_GAMMA:
301 gamma = strtof(optarg, NULL);
302 table = TABLE_POW;
303 break;
304
305 case FLAG_LINEAR:
306 table = TABLE_LINEAR;
307 break;
308
309 case FLAG_NEGATIVE:
310 table = TABLE_NEGATIVE;
311 break;
312
313 case FLAG_STEP:
314 table = TABLE_STEP;
315 break;
316
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400317 case FLAG_HDR:
318 srgb_joint = strtof(optarg, NULL);
319 table = TABLE_PIECEWISE_HDR;
320 break;
321
Dominik Behre4726302015-04-27 20:18:26 -0700322 case FLAG_TIME:
323 time = strtof(optarg, NULL);
324 break;
325
326 case FLAG_CRTCS:
327 crtcs = strtoul(optarg, NULL, 0);
328 break;
329
330 case FLAG_PERSIST:
331 persist = 1;
332 break;
333 }
334 }
335
Zach Reizner3415d062016-03-30 11:14:29 -0700336 drmModeConnector *connector = NULL;
337 struct bs_drm_pipe pipe = { 0 };
338 struct bs_drm_pipe_plumber *plumber = bs_drm_pipe_plumber_new();
339 bs_drm_pipe_plumber_connector_ptr(plumber, &connector);
340 bs_drm_pipe_plumber_crtc_mask(plumber, crtcs);
341 if (!internal)
342 bs_drm_pipe_plumber_connector_ranks(plumber, bs_drm_connectors_external_rank);
343 if (!bs_drm_pipe_plumber_make(plumber, &pipe)) {
344 bs_debug_error("failed to make pipe");
Dominik Behre4726302015-04-27 20:18:26 -0700345 return 1;
346 }
347
Zach Reizner3415d062016-03-30 11:14:29 -0700348 int fd = pipe.fd;
349 bs_drm_pipe_plumber_fd(plumber, fd);
350 drmModeRes *resources = drmModeGetResources(fd);
Dominik Behre4726302015-04-27 20:18:26 -0700351 if (!resources) {
Zach Reizner3415d062016-03-30 11:14:29 -0700352 bs_debug_error("failed to get drm resources");
Dominik Behre4726302015-04-27 20:18:26 -0700353 return 1;
354 }
355
Zach Reizner3415d062016-03-30 11:14:29 -0700356 struct gbm_device *gbm = gbm_create_device(fd);
357 if (!gbm) {
358 bs_debug_error("failed to create gbm");
359 return 1;
360 }
361
Shirish S99c916e2017-07-07 15:57:57 +0530362 struct bs_mapper *mapper = bs_mapper_gem_new();
Dongseong Hwang9093afe2017-03-20 19:16:28 -0700363 if (mapper == NULL) {
364 bs_debug_error("failed to create mapper object");
365 return 1;
366 }
367
Gurchetan Singh5dd7b702017-02-24 17:56:33 -0800368 uint32_t num_success = 0;
Zach Reizner3415d062016-03-30 11:14:29 -0700369 for (int c = 0; c < resources->count_crtcs && (crtcs >> c); c++) {
Dominik Behre4726302015-04-27 20:18:26 -0700370 int ret;
371 drmModeCrtc *crtc;
Zach Reizner3415d062016-03-30 11:14:29 -0700372 uint32_t crtc_mask = 1u << c;
Dominik Behre4726302015-04-27 20:18:26 -0700373
Zach Reizner3415d062016-03-30 11:14:29 -0700374 if (!(crtcs & crtc_mask))
Dominik Behre4726302015-04-27 20:18:26 -0700375 continue;
Zach Reizner3415d062016-03-30 11:14:29 -0700376
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400377 if (c > 0)
378 printf("\n");
379
Zach Reizner3415d062016-03-30 11:14:29 -0700380 if (connector != NULL) {
381 drmModeFreeConnector(connector);
382 connector = NULL;
Dominik Behre4726302015-04-27 20:18:26 -0700383 }
384
Zach Reizner3415d062016-03-30 11:14:29 -0700385 bs_drm_pipe_plumber_crtc_mask(plumber, crtc_mask);
386 if (!bs_drm_pipe_plumber_make(plumber, &pipe)) {
Gurchetan Singh5dd7b702017-02-24 17:56:33 -0800387 printf("unable to make pipe with crtc mask: %x\n", crtc_mask);
388 continue;
Dominik Behre4726302015-04-27 20:18:26 -0700389 }
390
Zach Reizner3415d062016-03-30 11:14:29 -0700391 crtc = drmModeGetCrtc(fd, pipe.crtc_id);
392 if (!crtc) {
393 bs_debug_error("drmModeGetCrtc(%d) failed: %s\n", pipe.crtc_id,
394 strerror(errno));
395 return 1;
Dominik Behre4726302015-04-27 20:18:26 -0700396 }
Zach Reizner3415d062016-03-30 11:14:29 -0700397 int gamma_size = crtc->gamma_size;
398 drmModeFreeCrtc(crtc);
399
400 if (!gamma_size) {
401 bs_debug_error("CRTC %d has no gamma table", crtc->crtc_id);
402 continue;
403 }
404
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400405 printf("CRTC:%d gamma table size:%d\n", pipe.crtc_id, gamma_size);
Zach Reizner3415d062016-03-30 11:14:29 -0700406
407 printf("Using CRTC:%u ENCODER:%u CONNECTOR:%u\n", pipe.crtc_id, pipe.encoder_id,
408 pipe.connector_id);
409
410 drmModeModeInfoPtr mode = find_best_mode(connector->count_modes, connector->modes);
411 if (!mode) {
412 bs_debug_error("Could not find mode for CRTC %d", pipe.crtc_id);
413 continue;
414 }
415
416 printf("Using mode %s\n", mode->name);
417
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400418 const bool is_hdr = table == TABLE_PIECEWISE_HDR;
419 const int gbm_format = is_hdr ? GBM_FORMAT_XRGB2101010 : GBM_FORMAT_XRGB8888;
420
421 printf("Creating buffer %ux%u (%s)\n", mode->hdisplay, mode->vdisplay,
422 (is_hdr ? "XR30" : "XR24"));
423 struct gbm_bo *bo = gbm_bo_create(gbm, mode->hdisplay, mode->vdisplay, gbm_format,
424 GBM_BO_USE_SCANOUT | GBM_BO_USE_SW_WRITE_RARELY);
Zach Reizner3415d062016-03-30 11:14:29 -0700425 if (!bo) {
426 bs_debug_error("failed to create buffer object");
427 return 1;
428 }
429
430 uint32_t fb_id = bs_drm_fb_create_gbm(bo);
431 if (!fb_id) {
432 bs_debug_error("failed to create frame buffer for buffer object");
433 return 1;
434 }
435
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400436 if (!draw_pattern(mapper, bo, gbm_format)) {
Zach Reizner3415d062016-03-30 11:14:29 -0700437 bs_debug_error("failed to draw pattern on buffer object");
438 return 1;
439 }
440
441 ret = drmModeSetCrtc(fd, pipe.crtc_id, fb_id, 0, 0, &pipe.connector_id, 1, mode);
442 if (ret < 0) {
443 bs_debug_error("Could not set mode on CRTC %d %s", pipe.crtc_id,
444 strerror(errno));
445 return 1;
446 }
447
Miguel Casasa5d9ff22020-03-12 17:23:34 -0400448 ret = set_gamma(fd, pipe.crtc_id, gamma_size, table, is_hdr ? srgb_joint : gamma);
Zach Reizner3415d062016-03-30 11:14:29 -0700449 if (ret)
450 return ret;
Dominik Behre4726302015-04-27 20:18:26 -0700451
452 fsleep(time);
453
454 if (!persist) {
Zach Reizner3415d062016-03-30 11:14:29 -0700455 ret = set_gamma(fd, pipe.crtc_id, gamma_size, TABLE_LINEAR, 0.0f);
456 if (ret)
Dominik Behre4726302015-04-27 20:18:26 -0700457 return ret;
Dominik Behre4726302015-04-27 20:18:26 -0700458 }
459
Zach Reizner3415d062016-03-30 11:14:29 -0700460 ret = drmModeSetCrtc(fd, pipe.crtc_id, 0, 0, 0, NULL, 0, NULL);
Dominik Behre4726302015-04-27 20:18:26 -0700461 if (ret < 0) {
Zach Reizner3415d062016-03-30 11:14:29 -0700462 bs_debug_error("Could disable CRTC %d %s\n", pipe.crtc_id, strerror(errno));
Gurchetan Singh5dd7b702017-02-24 17:56:33 -0800463 return 1;
Dominik Behre4726302015-04-27 20:18:26 -0700464 }
Zach Reizner3415d062016-03-30 11:14:29 -0700465
466 drmModeRmFB(fd, fb_id);
467 gbm_bo_destroy(bo);
Gurchetan Singh5dd7b702017-02-24 17:56:33 -0800468 num_success++;
Zach Reizner3415d062016-03-30 11:14:29 -0700469 }
Dongseong Hwang9093afe2017-03-20 19:16:28 -0700470 bs_mapper_destroy(mapper);
Zach Reizner3415d062016-03-30 11:14:29 -0700471
472 if (connector != NULL) {
473 drmModeFreeConnector(connector);
474 connector = NULL;
Dominik Behre4726302015-04-27 20:18:26 -0700475 }
476
477 drmModeFreeResources(resources);
Zach Reizner3415d062016-03-30 11:14:29 -0700478 bs_drm_pipe_plumber_destroy(&plumber);
Dominik Behre4726302015-04-27 20:18:26 -0700479
Gurchetan Singh5dd7b702017-02-24 17:56:33 -0800480 if (!num_success) {
481 bs_debug_error("unable to set gamma table on any CRTC");
482 return 1;
483 }
484
Dominik Behre4726302015-04-27 20:18:26 -0700485 return 0;
486}