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
9Display::Display(fuchsia_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_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 = reinterpret_cast<fuchsia_display_CursorInfo*>(info->cursor_configs.data);
23    for (unsigned i = 0; i < info->cursor_configs.count; i++) {
24        cursors_.push_back(cursors[i]);
25    }
26}
27
28void Display::Dump() {
29    printf("Display id = %ld\n", id_);
30
31    printf("\tSupported pixel formats:\n");
32    for (unsigned i = 0; i < pixel_formats_.size(); i++) {
33        printf("\t\t%d\t: %08x\n", i, pixel_formats_[i]);
34    }
35
36    printf("\n\tSupported display modes:\n");
37    for (unsigned i = 0; i < modes_.size(); i++) {
38        printf("\t\t%d\t: %dx%d\t%d.%02d\n", i,
39               modes_[i].horizontal_resolution, modes_[i].vertical_resolution,
40               modes_[i].refresh_rate_e2 / 100, modes_[i].refresh_rate_e2 % 100);
41    }
42
43    printf("\n\tSupported cursor modes:\n");
44    for (unsigned i = 0; i < cursors_.size(); i++) {
45        printf("\t\t%d\t: %dx%d\t%08x\n",
46               i, cursors_[i].width, cursors_[i].height, cursors_[i].pixel_format);
47    }
48    printf("\n");
49}
50
51void Display::Init(zx_handle_t dc_handle) {
52    if (mode_idx_ != 0) {
53        fuchsia_display_ControllerSetDisplayModeRequest set_mode_msg;
54        set_mode_msg.hdr.ordinal = fuchsia_display_ControllerSetDisplayModeOrdinal;
55        set_mode_msg.display_id = id_;
56        set_mode_msg.mode = modes_[mode_idx_];
57        ZX_ASSERT(zx_channel_write(dc_handle, 0,
58                                   &set_mode_msg, sizeof(set_mode_msg), nullptr, 0) == ZX_OK);
59    }
60
61    if (grayscale_) {
62        fuchsia_display_ControllerSetDisplayColorConversionRequest cc_msg;
63        cc_msg.hdr.ordinal = fuchsia_display_ControllerSetDisplayColorConversionOrdinal;
64        cc_msg.display_id = id_;
65        cc_msg.postoffsets[0] = nanf("post");
66        cc_msg.preoffsets[0] = nanf("pre");
67        float grayscale[9] = {
68            .2126f, .7152f, .0722f,
69            .2126f, .7152f, .0722f,
70            .2126f, .7152f, .0722f,
71        };
72        memcpy(cc_msg.coefficients, grayscale, sizeof(grayscale));
73        ZX_ASSERT(zx_channel_write(dc_handle, 0, &cc_msg, sizeof(cc_msg), NULL, 0) == ZX_OK);
74    }
75}
76