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 #pragma once
6 
7 #include <zircon/device/display-controller.h>
8 #include <zircon/types.h>
9 #include <lib/zx/channel.h>
10 
11 #include "display.h"
12 #include "fuchsia/hardware/display/c/fidl.h"
13 #include "image.h"
14 
15 typedef struct frame {
16     uint32_t width;
17     uint32_t height;
18     uint32_t x_pos;
19     uint32_t y_pos;
20 } frame_t;
21 
22 typedef struct layer {
23     uint64_t id;
24     bool active;
25 
26     bool done;
27 
28     frame_t src;
29     frame_t dest;
30 
31     image_import_t import_info[2];
32 } layer_t;
33 
34 // A layer whose output can appear on multiple displays.
35 class VirtualLayer {
36 public:
37     explicit VirtualLayer(Display* display);
38     explicit VirtualLayer(const fbl::Vector<Display>& displays);
39 
40     // Finish initializing the layer. All Set* methods should be called before this.
41     virtual bool Init(zx_handle_t channel) = 0;
42 
43     // Steps the local layout state to frame_num.
44     virtual void StepLayout(int32_t frame_num) = 0;
45 
46     // Waits for the display controller to be done with the previous version of this frame.
47     virtual bool WaitForReady() = 0;
48 
49     // Sets the current layout to the display contorller.
50     virtual void SendLayout(zx_handle_t channel) = 0;
51 
52     // Renders the current frame (and signals the fence if necessary).
53     virtual void Render(int32_t frame_num) = 0;
54 
55     // Gets the display controller layer ID for usage on the given display.
id(uint64_t display_id)56     uint64_t id(uint64_t display_id) const {
57         for (unsigned i = 0; i < displays_.size(); i++) {
58             if (displays_[i]->id() == display_id && layers_[i].active) {
59                 return layers_[i].id;
60             }
61         }
62         return INVALID_ID;
63     }
64 
65     // Gets the ID of the image on the given display.
66     virtual uint64_t image_id(uint64_t display_id) const = 0;
67 
set_frame_done(uint64_t display_id)68     void set_frame_done(uint64_t display_id) {
69         for (unsigned i = 0; i < displays_.size(); i++) {
70             if (displays_[i]->id() == display_id) {
71                 layers_[i].done = true;
72             }
73         }
74     }
75 
is_done()76     virtual bool is_done() const {
77         bool done = true;
78         for (unsigned i = 0; i < displays_.size(); i++) {
79             done &= !layers_[i].active || layers_[i].done;
80         }
81         return done;
82     }
83 
clear_done()84     void clear_done() {
85         for (unsigned i = 0; i < displays_.size(); i++) {
86             layers_[i].done = false;
87         }
88     }
89 
90 protected:
91     layer_t* CreateLayer(zx_handle_t dc_handle);
92     void SetLayerImages(zx_handle_t handle, bool alt_image);
93 
94     fbl::Vector<Display*> displays_;
95     fbl::Vector<layer_t> layers_;
96 
97     uint32_t width_;
98     uint32_t height_;
99 };
100 
101 class PrimaryLayer : public VirtualLayer {
102 public:
103     explicit PrimaryLayer(Display* display);
104     explicit PrimaryLayer(const fbl::Vector<Display>& displays);
105 
106     // Set* methods to configure the layer.
SetImageDimens(uint32_t width,uint32_t height)107     void SetImageDimens(uint32_t width, uint32_t height) {
108         image_width_ = width;
109         image_height_ = height;
110 
111         src_frame_.width = width;
112         src_frame_.height = height;
113         dest_frame_.width = width;
114         dest_frame_.height = height;
115     }
SetSrcFrame(uint32_t width,uint32_t height)116     void SetSrcFrame(uint32_t width, uint32_t height) {
117         src_frame_.width = width;
118         src_frame_.height = height;
119     }
SetDestFrame(uint32_t width,uint32_t height)120     void SetDestFrame(uint32_t width, uint32_t height) {
121         dest_frame_.width = width;
122         dest_frame_.height = height;
123     }
SetLayerFlipping(bool flip)124     void SetLayerFlipping(bool flip) { layer_flipping_ = flip; }
SetPanSrc(bool pan)125     void SetPanSrc(bool pan) { pan_src_ = pan; }
SetPanDest(bool pan)126     void SetPanDest(bool pan) { pan_dest_ = pan; }
SetLayerToggle(bool toggle)127     void SetLayerToggle(bool toggle) { layer_toggle_ = toggle; }
SetRotates(bool rotates)128     void SetRotates(bool rotates) { rotates_ = rotates; }
SetAlpha(bool enable,float val)129     void SetAlpha(bool enable, float val) {
130         alpha_enable_ = enable;
131         alpha_val_ = val;
132     }
SetScaling(bool enable)133     void SetScaling(bool enable) {
134         scaling_ = enable;
135     }
SetImageFormat(uint32_t image_format)136     void SetImageFormat(uint32_t image_format) { image_format_ = image_format; }
137 
138     bool Init(zx_handle_t channel) override;
139     void StepLayout(int32_t frame_num) override;
140     bool WaitForReady() override;
141     void SendLayout(zx_handle_t channel) override;
142     void Render(int32_t frame_num) override;
143 
image_id(uint64_t display_id)144     uint64_t image_id(uint64_t display_id) const override {
145         for (unsigned i = 0; i < displays_.size(); i++) {
146             if (displays_[i]->id() == display_id && layers_[i].active) {
147                 return layers_[i].import_info[alt_image_].id;
148             }
149         }
150         return INVALID_ID;
151     }
152 
153 private:
154     void SetLayerPositions(zx_handle_t handle);
155     bool Wait(uint32_t idx);
156     void InitImageDimens();
157 
158     uint32_t image_width_ = 0;
159     uint32_t image_height_ = 0;
160     uint32_t image_format_ = 0;
161     frame_t src_frame_ = {};
162     frame_t dest_frame_ = {};
163     uint8_t rotation_ = fuchsia_hardware_display_Transform_IDENTITY;
164     bool layer_flipping_ = false;
165     bool pan_src_ = false;
166     bool pan_dest_ = false;
167     bool layer_toggle_ = false;
168     bool rotates_ = false;
169     bool alpha_enable_ = false;
170     float alpha_val_ = 0.f;
171     bool scaling_ = false;
172 
173     bool alt_image_ = false;
174     Image* images_[2];
175 };
176 
177 class CursorLayer : public VirtualLayer {
178 public:
179     explicit CursorLayer(Display* display);
180     explicit CursorLayer(const fbl::Vector<Display>& displays);
181 
182     bool Init(zx_handle_t channel) override;
183     void StepLayout(int32_t frame_num) override;
184     void SendLayout(zx_handle_t channel) override;
185 
WaitForReady()186     bool WaitForReady() override { return true; }
Render(int32_t frame_num)187     void Render(int32_t frame_num) override {}
188 
image_id(uint64_t display_id)189     uint64_t image_id(uint64_t display_id) const override {
190         for (unsigned i = 0; i < displays_.size(); i++) {
191             if (displays_[i]->id() == display_id && layers_[i].active) {
192                 return layers_[i].import_info[0].id;
193             }
194         }
195         return INVALID_ID;
196     }
197 
198 
199 private:
200     uint32_t x_pos_ = 0;
201     uint32_t y_pos_ = 0;
202 
203     Image* image_;
204 };
205 
206 class ColorLayer : public VirtualLayer {
207 public:
208     explicit ColorLayer(Display* display);
209     explicit ColorLayer(const fbl::Vector<Display>& displays);
210 
211     bool Init(zx_handle_t channel) override;
212 
SendLayout(zx_handle_t channel)213     void SendLayout(zx_handle_t channel) override {};
StepLayout(int32_t frame_num)214     void StepLayout(int32_t frame_num) override {};
WaitForReady()215     bool WaitForReady() override { return true; }
Render(int32_t frame_num)216     void Render(int32_t frame_num) override {}
image_id(uint64_t display_id)217     uint64_t image_id(uint64_t display_id) const override { return INVALID_ID; }
is_done()218     virtual bool is_done() const override { return true; }
219 };
220