1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "display.h"
6 #include <math.h>
7 #include <zircon/syscalls.h>
8 
Display(fuchsia_hardware_display_Info * info)9 Display::Display(fuchsia_hardware_display_Info* info) {
10     id_ = info->id;
11 
12     auto pixel_format = reinterpret_cast<int32_t*>(info->pixel_format.data);
13     for (unsigned i = 0; i < info->pixel_format.count; i++) {
14         pixel_formats_.push_back(pixel_format[i]);
15     }
16 
17     auto mode = reinterpret_cast<fuchsia_hardware_display_Mode*>(info->modes.data);
18     for (unsigned i = 0; i < info->modes.count; i++) {
19         modes_.push_back(mode[i]);
20     }
21 
22     auto cursors =
23         reinterpret_cast<fuchsia_hardware_display_CursorInfo*>(info->cursor_configs.data);
24     for (unsigned i = 0; i < info->cursor_configs.count; i++) {
25         cursors_.push_back(cursors[i]);
26     }
27 
28     manufacturer_name_ = fbl::String(info->manufacturer_name.data);
29     monitor_name_ = fbl::String(info->monitor_name.data);
30     monitor_serial_ = fbl::String(info->monitor_serial.data);
31 }
32 
Dump()33 void Display::Dump() {
34     printf("Display id = %ld\n", id_);
35     printf("\tManufacturer name = \"%s\"\n", manufacturer_name_.c_str());
36     printf("\tMonitor name = \"%s\"\n", monitor_name_.c_str());
37     printf("\tMonitor serial = \"%s\"\n", monitor_serial_.c_str());
38 
39     printf("\tSupported pixel formats:\n");
40     for (unsigned i = 0; i < pixel_formats_.size(); i++) {
41         printf("\t\t%d\t: %08x\n", i, pixel_formats_[i]);
42     }
43 
44     printf("\n\tSupported display modes:\n");
45     for (unsigned i = 0; i < modes_.size(); i++) {
46         printf("\t\t%d\t: %dx%d\t%d.%02d\n", i,
47                modes_[i].horizontal_resolution, modes_[i].vertical_resolution,
48                modes_[i].refresh_rate_e2 / 100, modes_[i].refresh_rate_e2 % 100);
49     }
50 
51     printf("\n\tSupported cursor modes:\n");
52     for (unsigned i = 0; i < cursors_.size(); i++) {
53         printf("\t\t%d\t: %dx%d\t%08x\n",
54                i, cursors_[i].width, cursors_[i].height, cursors_[i].pixel_format);
55     }
56     printf("\n");
57 }
58 
Init(zx_handle_t dc_handle)59 void Display::Init(zx_handle_t dc_handle) {
60     if (mode_idx_ != 0) {
61         fuchsia_hardware_display_ControllerSetDisplayModeRequest set_mode_msg;
62         set_mode_msg.hdr.ordinal = fuchsia_hardware_display_ControllerSetDisplayModeOrdinal;
63         set_mode_msg.display_id = id_;
64         set_mode_msg.mode = modes_[mode_idx_];
65         ZX_ASSERT(zx_channel_write(dc_handle, 0,
66                                    &set_mode_msg, sizeof(set_mode_msg), nullptr, 0) == ZX_OK);
67     }
68 
69     if (grayscale_) {
70         fuchsia_hardware_display_ControllerSetDisplayColorConversionRequest cc_msg;
71         cc_msg.hdr.ordinal = fuchsia_hardware_display_ControllerSetDisplayColorConversionOrdinal;
72         cc_msg.display_id = id_;
73         cc_msg.postoffsets[0] = nanf("post");
74         cc_msg.preoffsets[0] = nanf("pre");
75         float grayscale[9] = {
76             .2126f, .7152f, .0722f,
77             .2126f, .7152f, .0722f,
78             .2126f, .7152f, .0722f,
79         };
80         memcpy(cc_msg.coefficients, grayscale, sizeof(grayscale));
81         ZX_ASSERT(zx_channel_write(dc_handle, 0, &cc_msg, sizeof(cc_msg), NULL, 0) == ZX_OK);
82     }
83 }
84