summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew F. Davis2018-07-24 08:20:35 -0500
committerAlistair Strachan2018-08-31 13:00:04 -0500
commit8eaa2bfcd5a0abbd52051f14de0c0e200e98175b (patch)
tree624db8896f88f8680bb2e8a1e100497230716b65
parent86a022aa92b8f174df250113f4717737b9edfd25 (diff)
downloadhardware-ti-am57x-8eaa2bfcd5a0abbd52051f14de0c0e200e98175b.tar.gz
hardware-ti-am57x-8eaa2bfcd5a0abbd52051f14de0c0e200e98175b.tar.xz
hardware-ti-am57x-8eaa2bfcd5a0abbd52051f14de0c0e200e98175b.zip
libhwcomposer: Add initial support
Add basic HW Composer support that allows boot to UI. More functionality will be added incrementally. Test: Boot to UI with BeagleBoard X15 Change-Id: I9803cc892dfe85b8b9929229ba3b86f2bd9d36bc Signed-off-by: Andrew F. Davis <afd@ti.com>
-rw-r--r--libhwcomposer/Android.bp44
-rw-r--r--libhwcomposer/NOTICE203
-rw-r--r--libhwcomposer/display.cpp273
-rw-r--r--libhwcomposer/display.h126
-rw-r--r--libhwcomposer/drmfb.cpp100
-rw-r--r--libhwcomposer/drmfb.h35
-rw-r--r--libhwcomposer/format.cpp152
-rw-r--r--libhwcomposer/format.h63
-rw-r--r--libhwcomposer/hal_public.h245
-rw-r--r--libhwcomposer/hwc.cpp724
-rw-r--r--libhwcomposer/hwc_dev.h57
11 files changed, 2022 insertions, 0 deletions
diff --git a/libhwcomposer/Android.bp b/libhwcomposer/Android.bp
new file mode 100644
index 0000000..384e7e2
--- /dev/null
+++ b/libhwcomposer/Android.bp
@@ -0,0 +1,44 @@
1// Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15cc_library_shared {
16 name: "hwcomposer.am57x",
17
18 vendor: true,
19 relative_install_path: "hw",
20
21 srcs: [
22 "display.cpp",
23 "drmfb.cpp",
24 "format.cpp",
25 "hwc.cpp",
26 ],
27
28 cflags: [
29 "-DLOG_TAG=\"ti_hwc\"",
30 "-Wno-unused-parameter",
31 "-Wno-missing-field-initializers",
32 "-fexceptions",
33 ],
34
35 shared_libs: [
36 "liblog",
37 "libcutils",
38 "libutils",
39 "libhardware",
40 "libhardware_legacy",
41 "libdrm",
42 "libkmsxx",
43 ],
44}
diff --git a/libhwcomposer/NOTICE b/libhwcomposer/NOTICE
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/libhwcomposer/NOTICE
@@ -0,0 +1,203 @@
1
2 Apache License
3 Version 2.0, January 2004
4 http://www.apache.org/licenses/
5
6 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
8 1. Definitions.
9
10 "License" shall mean the terms and conditions for use, reproduction,
11 and distribution as defined by Sections 1 through 9 of this document.
12
13 "Licensor" shall mean the copyright owner or entity authorized by
14 the copyright owner that is granting the License.
15
16 "Legal Entity" shall mean the union of the acting entity and all
17 other entities that control, are controlled by, or are under common
18 control with that entity. For the purposes of this definition,
19 "control" means (i) the power, direct or indirect, to cause the
20 direction or management of such entity, whether by contract or
21 otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 outstanding shares, or (iii) beneficial ownership of such entity.
23
24 "You" (or "Your") shall mean an individual or Legal Entity
25 exercising permissions granted by this License.
26
27 "Source" form shall mean the preferred form for making modifications,
28 including but not limited to software source code, documentation
29 source, and configuration files.
30
31 "Object" form shall mean any form resulting from mechanical
32 transformation or translation of a Source form, including but
33 not limited to compiled object code, generated documentation,
34 and conversions to other media types.
35
36 "Work" shall mean the work of authorship, whether in Source or
37 Object form, made available under the License, as indicated by a
38 copyright notice that is included in or attached to the work
39 (an example is provided in the Appendix below).
40
41 "Derivative Works" shall mean any work, whether in Source or Object
42 form, that is based on (or derived from) the Work and for which the
43 editorial revisions, annotations, elaborations, or other modifications
44 represent, as a whole, an original work of authorship. For the purposes
45 of this License, Derivative Works shall not include works that remain
46 separable from, or merely link (or bind by name) to the interfaces of,
47 the Work and Derivative Works thereof.
48
49 "Contribution" shall mean any work of authorship, including
50 the original version of the Work and any modifications or additions
51 to that Work or Derivative Works thereof, that is intentionally
52 submitted to Licensor for inclusion in the Work by the copyright owner
53 or by an individual or Legal Entity authorized to submit on behalf of
54 the copyright owner. For the purposes of this definition, "submitted"
55 means any form of electronic, verbal, or written communication sent
56 to the Licensor or its representatives, including but not limited to
57 communication on electronic mailing lists, source code control systems,
58 and issue tracking systems that are managed by, or on behalf of, the
59 Licensor for the purpose of discussing and improving the Work, but
60 excluding communication that is conspicuously marked or otherwise
61 designated in writing by the copyright owner as "Not a Contribution."
62
63 "Contributor" shall mean Licensor and any individual or Legal Entity
64 on behalf of whom a Contribution has been received by Licensor and
65 subsequently incorporated within the Work.
66
67 2. Grant of Copyright License. Subject to the terms and conditions of
68 this License, each Contributor hereby grants to You a perpetual,
69 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 copyright license to reproduce, prepare Derivative Works of,
71 publicly display, publicly perform, sublicense, and distribute the
72 Work and such Derivative Works in Source or Object form.
73
74 3. Grant of Patent License. Subject to the terms and conditions of
75 this License, each Contributor hereby grants to You a perpetual,
76 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 (except as stated in this section) patent license to make, have made,
78 use, offer to sell, sell, import, and otherwise transfer the Work,
79 where such license applies only to those patent claims licensable
80 by such Contributor that are necessarily infringed by their
81 Contribution(s) alone or by combination of their Contribution(s)
82 with the Work to which such Contribution(s) was submitted. If You
83 institute patent litigation against any entity (including a
84 cross-claim or counterclaim in a lawsuit) alleging that the Work
85 or a Contribution incorporated within the Work constitutes direct
86 or contributory patent infringement, then any patent licenses
87 granted to You under this License for that Work shall terminate
88 as of the date such litigation is filed.
89
90 4. Redistribution. You may reproduce and distribute copies of the
91 Work or Derivative Works thereof in any medium, with or without
92 modifications, and in Source or Object form, provided that You
93 meet the following conditions:
94
95 (a) You must give any other recipients of the Work or
96 Derivative Works a copy of this License; and
97
98 (b) You must cause any modified files to carry prominent notices
99 stating that You changed the files; and
100
101 (c) You must retain, in the Source form of any Derivative Works
102 that You distribute, all copyright, patent, trademark, and
103 attribution notices from the Source form of the Work,
104 excluding those notices that do not pertain to any part of
105 the Derivative Works; and
106
107 (d) If the Work includes a "NOTICE" text file as part of its
108 distribution, then any Derivative Works that You distribute must
109 include a readable copy of the attribution notices contained
110 within such NOTICE file, excluding those notices that do not
111 pertain to any part of the Derivative Works, in at least one
112 of the following places: within a NOTICE text file distributed
113 as part of the Derivative Works; within the Source form or
114 documentation, if provided along with the Derivative Works; or,
115 within a display generated by the Derivative Works, if and
116 wherever such third-party notices normally appear. The contents
117 of the NOTICE file are for informational purposes only and
118 do not modify the License. You may add Your own attribution
119 notices within Derivative Works that You distribute, alongside
120 or as an addendum to the NOTICE text from the Work, provided
121 that such additional attribution notices cannot be construed
122 as modifying the License.
123
124 You may add Your own copyright statement to Your modifications and
125 may provide additional or different license terms and conditions
126 for use, reproduction, or distribution of Your modifications, or
127 for any such Derivative Works as a whole, provided Your use,
128 reproduction, and distribution of the Work otherwise complies with
129 the conditions stated in this License.
130
131 5. Submission of Contributions. Unless You explicitly state otherwise,
132 any Contribution intentionally submitted for inclusion in the Work
133 by You to the Licensor shall be under the terms and conditions of
134 this License, without any additional terms or conditions.
135 Notwithstanding the above, nothing herein shall supersede or modify
136 the terms of any separate license agreement you may have executed
137 with Licensor regarding such Contributions.
138
139 6. Trademarks. This License does not grant permission to use the trade
140 names, trademarks, service marks, or product names of the Licensor,
141 except as required for reasonable and customary use in describing the
142 origin of the Work and reproducing the content of the NOTICE file.
143
144 7. Disclaimer of Warranty. Unless required by applicable law or
145 agreed to in writing, Licensor provides the Work (and each
146 Contributor provides its Contributions) on an "AS IS" BASIS,
147 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 implied, including, without limitation, any warranties or conditions
149 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 PARTICULAR PURPOSE. You are solely responsible for determining the
151 appropriateness of using or redistributing the Work and assume any
152 risks associated with Your exercise of permissions under this License.
153
154 8. Limitation of Liability. In no event and under no legal theory,
155 whether in tort (including negligence), contract, or otherwise,
156 unless required by applicable law (such as deliberate and grossly
157 negligent acts) or agreed to in writing, shall any Contributor be
158 liable to You for damages, including any direct, indirect, special,
159 incidental, or consequential damages of any character arising as a
160 result of this License or out of the use or inability to use the
161 Work (including but not limited to damages for loss of goodwill,
162 work stoppage, computer failure or malfunction, or any and all
163 other commercial damages or losses), even if such Contributor
164 has been advised of the possibility of such damages.
165
166 9. Accepting Warranty or Additional Liability. While redistributing
167 the Work or Derivative Works thereof, You may choose to offer,
168 and charge a fee for, acceptance of support, warranty, indemnity,
169 or other liability obligations and/or rights consistent with this
170 License. However, in accepting such obligations, You may act only
171 on Your own behalf and on Your sole responsibility, not on behalf
172 of any other Contributor, and only if You agree to indemnify,
173 defend, and hold each Contributor harmless for any liability
174 incurred by, or claims asserted against, such Contributor by reason
175 of your accepting any such warranty or additional liability.
176
177 END OF TERMS AND CONDITIONS
178
179 APPENDIX: How to apply the Apache License to your work.
180
181 To apply the Apache License to your work, attach the following
182 boilerplate notice, with the fields enclosed by brackets "[]"
183 replaced with your own identifying information. (Don't include
184 the brackets!) The text should be enclosed in the appropriate
185 comment syntax for the file format. We also recommend that a
186 file or class name and description of purpose be included on the
187 same "printed page" as the copyright notice for easier
188 identification within third-party archives.
189
190 Copyright [yyyy] [name of copyright owner]
191
192 Licensed under the Apache License, Version 2.0 (the "License");
193 you may not use this file except in compliance with the License.
194 You may obtain a copy of the License at
195
196 http://www.apache.org/licenses/LICENSE-2.0
197
198 Unless required by applicable law or agreed to in writing, software
199 distributed under the License is distributed on an "AS IS" BASIS,
200 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 See the License for the specific language governing permissions and
202 limitations under the License.
203
diff --git a/libhwcomposer/display.cpp b/libhwcomposer/display.cpp
new file mode 100644
index 0000000..f881a84
--- /dev/null
+++ b/libhwcomposer/display.cpp
@@ -0,0 +1,273 @@
1/*
2 * Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <algorithm>
18
19#include <cstdint>
20
21#include <cutils/log.h>
22#include <cutils/properties.h>
23
24#include "display.h"
25#include "format.h"
26#include "hwc_dev.h"
27
28HWCDisplay::HWCDisplay(enum disp_role role) :
29 active_config(0),
30 role(role),
31 cb_procs(NULL),
32 is_dummy(false),
33 vsync_on(false),
34 blanked(true),
35 is_flip_pending(false)
36{
37}
38
39void HWCDisplay::setup_composition_pipes()
40{
41 std::unique_lock<std::mutex> lock(this->mutex);
42
43 KMSDisplay* kdisp = &this->disp_link;
44
45 int count = 0;
46 for (auto plane : kdisp->card->get_planes()) {
47 auto possible_crtcs = plane->get_possible_crtcs();
48 if (std::find(possible_crtcs.begin(), possible_crtcs.end(), kdisp->crtc) != possible_crtcs.end()) {
49 planeProps[count].plane = plane;
50 ALOGI("Overlay %d: plane_id: %d", count, planeProps[count].plane->id());
51 count++;
52 }
53 }
54}
55
56/* Page flip handler callback */
57void HWCDisplay::page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void* data)
58{
59 HWCDisplay* display = static_cast<HWCDisplay*>(data);
60
61 std::unique_lock<std::mutex> lock(display->mutex);
62
63 if (display->is_flip_pending == false) {
64 ALOGW("Spurious page flip?");
65 return;
66 }
67
68 /* release the old buffers */
69 for (auto current_fb_info : display->current_fb_infos)
70 delete current_fb_info;
71 display->current_fb_infos.clear();
72
73 /* pending are now current */
74 for (auto pending_fb_info : display->pending_fb_infos)
75 display->current_fb_infos.push_back(pending_fb_info);
76 display->pending_fb_infos.clear();
77
78 display->is_flip_pending = false;
79 lock.unlock();
80 display->cond_flip.notify_one();
81}
82
83static int vblank_kick(HWCDisplay* display)
84{
85 drmVBlank vblank;
86 memset(&vblank, 0, sizeof(vblank));
87 vblank.request.type = (drmVBlankSeqType)(DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT |
88 display->role == DISP_ROLE_SECONDARY ? DRM_VBLANK_SECONDARY : 0);
89 vblank.request.sequence = 1;
90 vblank.request.signal = (unsigned long)display;
91 int err = drmWaitVBlank(display->disp_link.card->fd(), &vblank);
92 if (err < 0) {
93 /* FIXME: error in drmWaitVBlank() use SW vsync instead? */
94 ALOGE("drmWaitVBlank error %d (%s)", err, strerror(errno));
95 return -1;
96 }
97
98 return 0;
99}
100
101/* Callback function that gets triggered on vsync */
102void HWCDisplay::vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void* data)
103{
104 HWCDisplay* display = static_cast<HWCDisplay*>(data);
105
106 std::unique_lock<std::mutex> lock(display->mutex);
107
108 if (display->vsync_on) {
109 int64_t ts = sec * (int64_t)1000000000 + usec * (int64_t)1000;
110
111// ALOGD("Sending VBLANK at %lld for display %d", ts, display->role);
112 display->cb_procs->vsync(display->cb_procs, display->role, ts);
113
114 vblank_kick(display);
115 }
116}
117
118int HWCDisplay::set_vsync_state(bool state)
119{
120 std::unique_lock<std::mutex> lock(this->mutex);
121
122 if (this->is_dummy)
123 return 0;
124
125 this->vsync_on = state;
126
127 if (this->vsync_on)
128 return vblank_kick(this);
129
130 return 0;
131}
132
133static void set_plane_properties(kms::AtomicReq& req, drm_plane_props_t* plane_props)
134{
135 kms::Plane* plane = plane_props->plane;
136
137 req.add(plane, "FB_ID", plane_props->fb_info->fb_id);
138
139 req.add(plane, "IN_FENCE_FD", plane_props->layer->acquireFenceFd);
140
141 req.add(plane, {
142 { "CRTC_ID", plane_props->crtc_id },
143 { "SRC_X", (plane_props->src_x) << 16 },
144 { "SRC_Y", (plane_props->src_y) << 16 },
145 { "SRC_W", (plane_props->src_w) << 16 },
146 { "SRC_H", (plane_props->src_h) << 16 },
147 { "CRTC_X", plane_props->crtc_x },
148 { "CRTC_Y", plane_props->crtc_y },
149 { "CRTC_W", plane_props->crtc_w },
150 { "CRTC_H", plane_props->crtc_h },
151 });
152
153 /* optional props */
154 req.add(plane, {
155 { "zorder", plane_props->zorder },
156 { "pre_mult_alpha", plane_props->pre_mult_alpha },
157 });
158}
159
160int HWCDisplay::update_display(drm_plane_props_t* planeProp)
161{
162 std::unique_lock<std::mutex> lock(this->mutex);
163
164 this->cond_flip.wait(lock, [this]{return !this->is_flip_pending;});
165
166 buffer_handle_t handle = planeProp->layer->handle;
167 if (!handle) {
168 ALOGW("Got empty handle, nothing to display");
169 return 0;
170 }
171
172 KMSDisplay* kdisp = &this->disp_link;
173
174 planeProp->fb_info = new DRMFramebuffer(kdisp->card->fd(), handle, false);
175 this->pending_fb_infos.push_back(planeProp->fb_info);
176
177 planeProp->crtc_id = kdisp->crtc->id();
178
179 // Atomic display update
180 kms::AtomicReq req(*kdisp->card);
181 set_plane_properties(req, planeProp);
182 int ret = req.commit(this, true);
183 if (ret) {
184 ALOGE("cannot do atomic commit/page flip: %d (%s)", ret, strerror(errno));
185 for (auto pending_fb_info : this->pending_fb_infos)
186 delete pending_fb_info;
187 this->pending_fb_infos.clear();
188 return ret;
189 }
190
191// ALOGD("Scheduled page flip on display %d", this->role);
192 this->is_flip_pending = true;
193
194 return 0;
195}
196
197void HWCDisplay::blank(int blank)
198{
199 std::unique_lock<std::mutex> lock(this->mutex);
200
201 if (this->is_dummy)
202 return;
203
204 KMSDisplay* kdisp = &this->disp_link;
205
206 ALOGI("Linking connector %d to crtc %d", kdisp->con->id(), kdisp->crtc->id());
207
208 int ret = kdisp->crtc->set_mode(kdisp->con, kdisp->mode);
209 if (ret) {
210 ALOGE("Failed to set crtc mode (%s)", strerror(-ret));
211 return;
212 }
213
214 // FIXME: This should actually blank the screen
215 this->blanked = blank;
216}
217
218int HWCDisplay::get_display_configs(uint32_t* configs, size_t* numConfigs)
219{
220 if (!configs || !numConfigs)
221 return -EINVAL;
222
223 if (*numConfigs == 0)
224 return 0;
225
226 std::unique_lock<std::mutex> lock(this->mutex);
227
228 size_t num = this->configs.size();
229 if (num > *numConfigs)
230 num = *numConfigs;
231
232 for (size_t i = 0; i < num; i++)
233 configs[i] = i;
234
235 *numConfigs = num;
236
237 return 0;
238}
239
240int HWCDisplay::get_display_attributes(uint32_t cfg, const uint32_t* attributes, int32_t* values)
241{
242 if (!attributes || !values)
243 return 0;
244
245 std::unique_lock<std::mutex> lock(this->mutex);
246
247 if (cfg >= this->configs.size())
248 return -EINVAL;
249
250 display_config_t* config = &this->configs[cfg];
251
252 for (size_t i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
253 switch (attributes[i]) {
254 case HWC_DISPLAY_VSYNC_PERIOD:
255 values[i] = 1000000000 / config->fps;
256 break;
257 case HWC_DISPLAY_WIDTH:
258 values[i] = config->xres;
259 break;
260 case HWC_DISPLAY_HEIGHT:
261 values[i] = config->yres;
262 break;
263 case HWC_DISPLAY_DPI_X:
264 values[i] = 1000 * config->xdpi;
265 break;
266 case HWC_DISPLAY_DPI_Y:
267 values[i] = 1000 * config->ydpi;
268 break;
269 }
270 }
271
272 return 0;
273}
diff --git a/libhwcomposer/display.h b/libhwcomposer/display.h
new file mode 100644
index 0000000..5df923f
--- /dev/null
+++ b/libhwcomposer/display.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <condition_variable>
20#include <mutex>
21
22#include <cstdbool>
23#include <cstdint>
24
25#include <hardware/hwcomposer.h>
26#include <kms++/kms++.h>
27
28#include <xf86drm.h>
29#include <xf86drmMode.h>
30
31#include "drmfb.h"
32
33#define MAX_DISPLAYS 4
34#define DSS_AVAILABLE_PIPES 4
35
36typedef struct display_config {
37 unsigned int xres;
38 unsigned int yres;
39 unsigned int fps;
40 unsigned int xdpi;
41 unsigned int ydpi;
42} display_config_t;
43
44enum disp_role {
45 DISP_ROLE_PRIMARY = 0,
46 DISP_ROLE_SECONDARY,
47};
48
49typedef struct drm_plane_props {
50 hwc_layer_1_t* layer;
51
52 kms::Plane* plane;
53 uint64_t crtc_id;
54
55 uint64_t crtc_x;
56 uint64_t crtc_y;
57 uint64_t crtc_w;
58 uint64_t crtc_h;
59 uint64_t src_x;
60 uint64_t src_y;
61 uint64_t src_w;
62 uint64_t src_h;
63
64 uint64_t rotation;
65 uint64_t zorder;
66 uint64_t pre_mult_alpha;
67
68 DRMFramebuffer* fb_info;
69} drm_plane_props_t;
70
71class KMSDisplay {
72public:
73 KMSDisplay() :
74 card(NULL),
75 con(NULL),
76 crtc(NULL),
77 mode() {}
78
79 kms::Card* card;
80 kms::Connector* con;
81 kms::Crtc* crtc;
82 kms::Videomode mode;
83};
84
85class HWCDisplay
86{
87public:
88 HWCDisplay(enum disp_role role);
89 ~HWCDisplay(){};
90
91 void setup_composition_pipes();
92
93 int update_display(drm_plane_props_t* planeProp);
94
95 std::vector<display_config_t> configs;
96 uint32_t active_config;
97
98 enum disp_role role;
99
100 drm_plane_props_t planeProps[DSS_AVAILABLE_PIPES];
101
102 KMSDisplay disp_link;
103
104 const hwc_procs_t* cb_procs;
105
106 bool is_dummy;
107
108 int set_vsync_state(bool state);
109 void blank(int blank);
110 int get_display_configs(uint32_t* configs, size_t* numConfigs);
111 int get_display_attributes(uint32_t cfg, const uint32_t* attributes, int32_t* values);
112
113 static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void* data);
114 static void vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void* data);
115
116private:
117 std::vector<DRMFramebuffer*> pending_fb_infos;
118 std::vector<DRMFramebuffer*> current_fb_infos;
119
120 bool vsync_on;
121 bool blanked;
122
123 std::mutex mutex;
124 std::condition_variable cond_flip;
125 volatile bool is_flip_pending;
126};
diff --git a/libhwcomposer/drmfb.cpp b/libhwcomposer/drmfb.cpp
new file mode 100644
index 0000000..04c41dd
--- /dev/null
+++ b/libhwcomposer/drmfb.cpp
@@ -0,0 +1,100 @@
1/*
2 * Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <cutils/log.h>
18#include <drm/drm_fourcc.h>
19#include <hardware/hwcomposer.h>
20
21#include <xf86drm.h>
22#include <xf86drmMode.h>
23
24#include "drmfb.h"
25#include "format.h"
26#include "hal_public.h"
27
28DRMFramebuffer::DRMFramebuffer(int drm_fd, buffer_handle_t handle, bool is_overlay) :
29 bo(), pitches(), offsets()
30{
31 if (!handle)
32 return;
33
34 uint32_t gem_handle;
35 IMG_native_handle_t* img_hnd = (IMG_native_handle_t*)handle;
36 int ret = drmPrimeFDToHandle(drm_fd, img_hnd->fd[0], &gem_handle);
37 if (ret) {
38 ALOGE("Failed to get DRM buffer object from handle");
39 return;
40 }
41
42 this->width = img_hnd->iWidth;
43 this->height = img_hnd->iHeight;
44 this->format = convert_hal_to_drm_format(img_hnd->iFormat, true);
45 this->bo[0] = gem_handle;
46 this->pitches[0] = ALIGN(img_hnd->iWidth, HW_ALIGN) * get_format_bpp(img_hnd->iFormat) >> 3;
47 this->offsets[0] = 0;
48 this->drm_fd = drm_fd;
49
50 if (is_overlay) {
51 switch (this->format) {
52 case DRM_FORMAT_NV12:
53 this->bo[1] = gem_handle;
54
55 this->pitches[0] = ALIGN(img_hnd->iWidth, HW_ALIGN);
56 this->pitches[1] = this->pitches[0];
57
58 this->offsets[1] = this->pitches[0] * img_hnd->iHeight;
59 break;
60 case DRM_FORMAT_ARGB8888:
61 case DRM_FORMAT_XRGB8888:
62 case DRM_FORMAT_RGB565:
63 break;
64 default:
65 ALOGE("Bad format for overlay");
66 return;
67 }
68 }
69
70 ret = drmModeAddFB2(drm_fd, this->width, this->height,
71 this->format, this->bo,
72 this->pitches, this->offsets,
73 &this->fb_id, 0);
74 if (ret) {
75 ALOGE("Could not create DRM frame buffer %d", ret);
76 return;
77 }
78}
79
80DRMFramebuffer::~DRMFramebuffer()
81{
82 if (this->fb_id) {
83 if (drmModeRmFB(this->drm_fd, this->fb_id))
84 ALOGE("Failed to remove DRM frame buffer");
85 }
86
87 for (size_t i = 0; i < 4; i++) {
88 if (this->bo[i]) {
89 struct drm_gem_close close_args = {
90 close_args.handle = this->bo[i],
91 close_args.pad = 0,
92 };
93 int ret = drmIoctl(this->drm_fd, DRM_IOCTL_GEM_CLOSE, &close_args);
94 if (ret) {
95 ALOGE("Failed to close GEM handle");
96 return;
97 }
98 }
99 }
100}
diff --git a/libhwcomposer/drmfb.h b/libhwcomposer/drmfb.h
new file mode 100644
index 0000000..1efff0d
--- /dev/null
+++ b/libhwcomposer/drmfb.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <cstdint>
20
21class DRMFramebuffer
22{
23 public:
24 DRMFramebuffer(int drm_fd, buffer_handle_t handle, bool is_overlay);
25 ~DRMFramebuffer();
26
27 uint32_t width;
28 uint32_t height;
29 uint32_t format;
30 uint32_t bo[4];
31 uint32_t pitches[4];
32 uint32_t offsets[4];
33 uint32_t fb_id;
34 int drm_fd;
35};
diff --git a/libhwcomposer/format.cpp b/libhwcomposer/format.cpp
new file mode 100644
index 0000000..7f39203
--- /dev/null
+++ b/libhwcomposer/format.cpp
@@ -0,0 +1,152 @@
1/*
2 * Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <cstdint>
18
19#include <cutils/log.h>
20
21#include <linux/types.h>
22
23#include "format.h"
24#include "hal_public.h"
25
26bool is_valid_format(uint32_t format)
27{
28 switch (format) {
29 case HAL_PIXEL_FORMAT_RGBA_8888:
30 case HAL_PIXEL_FORMAT_BGRA_8888:
31 return true;
32
33 case HAL_PIXEL_FORMAT_RGB_565:
34 return true;
35
36 case HAL_PIXEL_FORMAT_NV12:
37 return true;
38
39 case HAL_PIXEL_FORMAT_RGBX_8888:
40 case HAL_PIXEL_FORMAT_BGRX_8888:
41 return true;
42
43 case HAL_PIXEL_FORMAT_TI_NV12:
44 case HAL_PIXEL_FORMAT_TI_NV12_1D:
45 /* legacy formats not supported anymore */
46 return false;
47
48 default:
49 return false;
50 }
51}
52
53bool is_rgb_format(uint32_t format)
54{
55 switch (format) {
56 case HAL_PIXEL_FORMAT_BGRA_8888:
57 case HAL_PIXEL_FORMAT_BGRX_8888:
58 case HAL_PIXEL_FORMAT_RGB_565:
59 return true;
60 default:
61 return false;
62 }
63}
64
65bool is_bgr_format(uint32_t format)
66{
67 switch (format) {
68 case HAL_PIXEL_FORMAT_RGBX_8888:
69 case HAL_PIXEL_FORMAT_RGBA_8888:
70 return true;
71 default:
72 return false;
73 }
74}
75
76bool is_nv12_format(uint32_t format)
77{
78 switch (format) {
79 case HAL_PIXEL_FORMAT_TI_NV12:
80 case HAL_PIXEL_FORMAT_TI_NV12_1D:
81 case HAL_PIXEL_FORMAT_NV12:
82 return true;
83 default:
84 return false;
85 }
86}
87
88bool is_opaque_format(uint32_t format)
89{
90 switch (format) {
91 case HAL_PIXEL_FORMAT_RGB_565:
92 case HAL_PIXEL_FORMAT_RGBX_8888:
93 case HAL_PIXEL_FORMAT_BGRX_8888:
94 return true;
95 default:
96 return false;
97 }
98}
99
100uint32_t get_format_bpp(uint32_t format)
101{
102 switch (format) {
103 case HAL_PIXEL_FORMAT_BGRA_8888:
104 case HAL_PIXEL_FORMAT_BGRX_8888:
105 case HAL_PIXEL_FORMAT_RGBX_8888:
106 case HAL_PIXEL_FORMAT_RGBA_8888:
107 return 32;
108 case HAL_PIXEL_FORMAT_RGB_565:
109 return 16;
110 case HAL_PIXEL_FORMAT_TI_NV12:
111 case HAL_PIXEL_FORMAT_TI_NV12_1D:
112 case HAL_PIXEL_FORMAT_NV12:
113 return 8;
114 default:
115 return 0;
116 }
117}
118
119uint32_t convert_hal_to_drm_format(uint32_t hal_format, bool blended)
120{
121 uint32_t dss_format = HAL_PIXEL_FORMAT_RGBA_8888;
122
123 /* convert color format */
124 switch (hal_format) {
125 case HAL_PIXEL_FORMAT_RGBA_8888:
126 case HAL_PIXEL_FORMAT_BGRA_8888:
127 dss_format = DRM_FORMAT_ARGB8888;
128 if (blended)
129 break;
130
131 case HAL_PIXEL_FORMAT_RGBX_8888:
132 case HAL_PIXEL_FORMAT_BGRX_8888:
133 dss_format = DRM_FORMAT_XRGB8888;
134 break;
135
136 case HAL_PIXEL_FORMAT_RGB_565:
137 dss_format = DRM_FORMAT_RGB565;
138 break;
139
140 case HAL_PIXEL_FORMAT_TI_NV12:
141 case HAL_PIXEL_FORMAT_TI_NV12_1D:
142 case HAL_PIXEL_FORMAT_NV12:
143 dss_format = DRM_FORMAT_NV12;
144 break;
145
146 default:
147 /* Should have been filtered out */
148 ALOGV("Unsupported pixel format");
149 }
150
151 return dss_format;
152}
diff --git a/libhwcomposer/format.h b/libhwcomposer/format.h
new file mode 100644
index 0000000..731c53a
--- /dev/null
+++ b/libhwcomposer/format.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include <string>
20
21#include <cstdint>
22
23#include <drm/drm_fourcc.h>
24#include <linux/types.h>
25
26#include "hal_public.h"
27
28static inline std::string HAL_FMT(uint32_t format)
29{
30 switch (format) {
31 case HAL_PIXEL_FORMAT_TI_NV12: return "NV12";
32 case HAL_PIXEL_FORMAT_TI_NV12_1D: return "NV12";
33 case HAL_PIXEL_FORMAT_YV12: return "YV12";
34 case HAL_PIXEL_FORMAT_BGRX_8888: return "xRGB32";
35 case HAL_PIXEL_FORMAT_RGBX_8888: return "xBGR32";
36 case HAL_PIXEL_FORMAT_BGRA_8888: return "ARGB32";
37 case HAL_PIXEL_FORMAT_RGBA_8888: return "ABGR32";
38 case HAL_PIXEL_FORMAT_RGB_565: return "RGB565";
39 default: return "??";
40 }
41}
42
43static inline std::string DRM_FMT(uint32_t format)
44{
45 switch (format) {
46 case DRM_FORMAT_NV12: return "NV12";
47 case DRM_FORMAT_XRGB8888: return "xRGB32";
48 case DRM_FORMAT_ARGB8888: return "ARGB32";
49 case DRM_FORMAT_RGB565: return "RGB565";
50 default: return "??";
51 }
52}
53
54bool is_valid_format(uint32_t format);
55bool is_rgb_format(uint32_t format);
56bool is_bgr_format(uint32_t format);
57bool is_nv12_format(uint32_t format);
58bool is_opaque_format(uint32_t format);
59uint32_t get_format_bpp(uint32_t format);
60uint32_t convert_hal_to_dss_format(uint32_t format, bool blended);
61uint32_t convert_hal_to_drm_format(uint32_t hal_format, bool blended);
62uint32_t convert_hal_to_ocd_format(uint32_t hal_format);
63uint32_t get_stride_from_format(uint32_t format, uint32_t width);
diff --git a/libhwcomposer/hal_public.h b/libhwcomposer/hal_public.h
new file mode 100644
index 0000000..5ca9bd2
--- /dev/null
+++ b/libhwcomposer/hal_public.h
@@ -0,0 +1,245 @@
1/* Copyright (c) Imagination Technologies Ltd.
2 *
3 * The contents of this file are subject to the MIT license as set out below.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef HAL_PUBLIC_H
25#define HAL_PUBLIC_H
26
27/* Authors of third party hardware composer (HWC) modules will need to include
28 * this header to access functionality in the gralloc and framebuffer HALs.
29 */
30
31#include <hardware/gralloc.h>
32#include <hardware/memtrack.h>
33
34#define ALIGN(x,a) (((x) + (a) - 1L) & ~((a) - 1L))
35#define HW_ALIGN 16
36
37/* This can be tuned down as appropriate for the SOC.
38 *
39 * IMG formats are usually a single sub-alloc.
40 * Some OEM video formats are two sub-allocs (Y, UV planes).
41 * Future OEM video formats might be three sub-allocs (Y, U, V planes).
42 */
43#define MAX_SUB_ALLOCS 3
44
45/* Format is not YCbCr (e.g. a RGB format) - bIsYUVFormat should be false */
46#define YUV_CHROMA_ORDER_NONE 0
47/* Cb follows Y */
48#define YUV_CHROMA_ORDER_CBCR_UV 1
49/* Cr follows Y */
50#define YUV_CHROMA_ORDER_CRCB_VU 2
51
52typedef struct
53{
54 native_handle_t base;
55
56 /* These fields can be sent cross process. They are also valid
57 * to duplicate within the same process.
58 *
59 * A table is stored within psPrivateData on gralloc_module_t (this
60 * is obviously per-process) which maps stamps to a mapped
61 * PVRSRV_CLIENT_MEM_INFO in that process. Each map entry has a lock
62 * count associated with it, satisfying the requirements of the
63 * Android API. This also prevents us from leaking maps/allocations.
64 *
65 * This table has entries inserted either by alloc()
66 * (alloc_device_t) or map() (gralloc_module_t). Entries are removed
67 * by free() (alloc_device_t) and unmap() (gralloc_module_t).
68 *
69 * As a special case for framebuffer_device_t, framebuffer_open()
70 * will add and framebuffer_close() will remove from this table.
71 */
72
73#define IMG_NATIVE_HANDLE_NUMFDS MAX_SUB_ALLOCS
74 /* The `fd' field is used to "export" a meminfo to another process.
75 * Therefore, it is allocated by alloc_device_t, and consumed by
76 * gralloc_module_t. The framebuffer_device_t does not need a handle,
77 * and the special value IMG_FRAMEBUFFER_FD is used instead.
78 */
79 int fd[MAX_SUB_ALLOCS];
80
81#define IMG_NATIVE_HANDLE_NUMINTS \
82 ((sizeof(unsigned long long) / sizeof(int)) + 5 + MAX_SUB_ALLOCS + 1 + MAX_SUB_ALLOCS + MAX_SUB_ALLOCS)
83 /* A KERNEL unique identifier for any exported kernel meminfo. Each
84 * exported kernel meminfo will have a unique stamp, but note that in
85 * userspace, several meminfos across multiple processes could have
86 * the same stamp. As the native_handle can be dup(2)'d, there could be
87 * multiple handles with the same stamp but different file descriptors.
88 */
89 unsigned long long ui64Stamp;
90
91 /* This is used for buffer usage validation when locking a buffer,
92 * and also in WSEGL (for the composition bypass feature).
93 */
94 int usage;
95
96 /* In order to do efficient cache flushes we need the buffer dimensions
97 * and format. These are available on the ANativeWindowBuffer,
98 * but the platform doesn't pass them down to the graphics HAL.
99 */
100 int iWidth;
101 int iHeight;
102 int iFormat;
103 unsigned int uiBpp;
104
105 /* The ion allocation path doesn't allow for the allocation size and
106 * mapping flags to be communicated cross-process automatically.
107 * Cache these here so we can map buffers in client processes.
108 */
109 unsigned int uiAllocSize[MAX_SUB_ALLOCS];
110 unsigned int uiFlags;
111 /* For multi-planar allocations, there will be multiple hstrides */
112 int aiStride[MAX_SUB_ALLOCS];
113
114 /* For multi-planar allocations, there will be multiple vstrides */
115 int aiVStride[MAX_SUB_ALLOCS];
116
117}
118__attribute__((aligned(sizeof(int)),packed)) IMG_native_handle_t;
119
120typedef struct
121{
122 int l, t, w, h;
123}
124IMG_write_lock_rect_t;
125
126typedef int (*IMG_buffer_format_compute_params_pfn)(
127 unsigned int uiPlane, int *piWidth, int *piHeight,
128 int *piStride, int *piVStride, unsigned long *pulPlaneOffset);
129
130typedef struct IMG_buffer_format_public_t
131{
132 /* Buffer formats are returned as a linked list */
133 struct IMG_buffer_format_public_t *psNext;
134
135 /* HAL_PIXEL_FORMAT_... enumerant */
136 int iHalPixelFormat;
137
138 /* WSEGL_PIXELFORMAT_... enumerant */
139 int iWSEGLPixelFormat;
140
141 /* Friendly name for format */
142 const char *const szName;
143
144 /* Bits (not bytes) per pixel */
145 unsigned int uiBpp;
146
147 /* Supported HW usage bits. If this is GRALLOC_USAGE_HW_MASK, all usages
148 * are supported. Used for HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED.
149 */
150 int iSupportedUsage;
151
152 /* YUV output format */
153 int bIsYUVFormat;
154
155 /* YCBCR_ORDERING_* defined the order of the Cb/Cr values */
156 int eYUVChromaOrder;
157
158 /* Utility function for adjusting YUV per-plane parameters */
159 IMG_buffer_format_compute_params_pfn pfnComputeParams;
160}
161IMG_buffer_format_public_t;
162
163typedef struct
164{
165 /* Base memtrack record, copied to caller */
166 struct memtrack_record base;
167
168 /* Record type, for filtering cached records */
169 enum memtrack_type eType;
170
171 /* Process ID, for filtering cached records */
172 pid_t pid;
173}
174IMG_memtrack_record_public_t;
175
176typedef struct IMG_gralloc_module_public_t
177{
178 gralloc_module_t base;
179
180 /* This function is deprecated and might be NULL. Do not use it. */
181 int (*GetPhyAddrs)(gralloc_module_t const* module,
182 buffer_handle_t handle, void **ppvPhyAddr);
183
184 /* Obtain HAL's registered format list */
185 const IMG_buffer_format_public_t *(*GetBufferFormats)(void);
186
187 int (*GetImplementationFormat) (struct IMG_gralloc_module_public_t const *psGrallocModule, int usage);
188
189 int (*GetMemTrackRecords)(struct IMG_gralloc_module_public_t const *module,
190 IMG_memtrack_record_public_t **ppsRecords,
191 size_t *puNumRecords);
192
193 /* Custom-blit components in lieu of overlay hardware */
194 int (*Blit)(struct IMG_gralloc_module_public_t const *module,
195 buffer_handle_t src,
196 void *dest[MAX_SUB_ALLOCS], int format);
197
198 int (*Blit2)(struct IMG_gralloc_module_public_t const *module,
199 buffer_handle_t src, buffer_handle_t dest,
200 int w, int h, int x, int y);
201
202 int (*Blit3)(struct IMG_gralloc_module_public_t const *module,
203 unsigned long long ui64SrcStamp, int iSrcWidth,
204 int iSrcHeight, int iSrcFormat, int eSrcRotation,
205 buffer_handle_t dest, int eDestRotation);
206}
207IMG_gralloc_module_public_t;
208
209/**
210 * pixel format definitions
211 */
212
213enum {
214 /*
215 * 0x100 = 0x1FF
216 *
217 * This range is reserved for pixel formats that are specific to the HAL
218 * implementation. Implementations can use any value in this range to
219 * communicate video pixel formats between their HAL modules. These
220 * formats must not have an alpha channel. Additionally, an EGLimage
221 * created from a gralloc buffer of one of these formats must be
222 * supported for use with the GL_OES_EGL_image_external OpenGL ES
223 * extension.
224 */
225
226 /*
227 * These are vendor specific pixel format, by (informal) convention
228 * IMGTec formats start from the top of the range, TI formats start from
229 * the bottom
230 */
231 HAL_PIXEL_FORMAT_TI_NV12 = 0x100,
232 HAL_PIXEL_FORMAT_TI_UNUSED = 0x101,
233 HAL_PIXEL_FORMAT_TI_NV12_1D = 0x102,
234 HAL_PIXEL_FORMAT_TI_Y8 = 0x103,
235 HAL_PIXEL_FORMAT_TI_Y16 = 0x104,
236 HAL_PIXEL_FORMAT_TI_UYVY = 0x105,
237 HAL_PIXEL_FORMAT_BGRX_8888 = 0x1FF,
238
239 /* generic format missing from Android list, not specific to vendor
240 * implementation
241 */
242 HAL_PIXEL_FORMAT_NV12 = 0x3231564E, // FourCC for NV12
243};
244
245#endif /* HAL_PUBLIC_H */
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
new file mode 100644
index 0000000..b04c548
--- /dev/null
+++ b/libhwcomposer/hwc.cpp
@@ -0,0 +1,724 @@
1/*
2 * Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <sstream>
18
19#include <cutils/trace.h>
20#include <fcntl.h>
21#include <poll.h>
22#include <sys/ioctl.h>
23#include <sys/resource.h>
24
25#include <cutils/log.h>
26#include <cutils/properties.h>
27#define HWC_REMOVE_DEPRECATED_VERSIONS 1
28#include <hardware/hardware.h>
29#include <hardware/hwcomposer.h>
30#include <hardware_legacy/uevent.h>
31
32#include <kms++/kms++.h>
33
34#include "display.h"
35#include "format.h"
36#include "hwc_dev.h"
37
38#define LCD_DISPLAY_DEFAULT_HRES 1920
39#define LCD_DISPLAY_DEFAULT_VRES 1080
40#define LCD_DISPLAY_DEFAULT_FPS 60
41
42#define LCD_DISPLAY_DEFAULT_DPI 120
43#define HDMI_DISPLAY_DEFAULT_DPI 75
44
45#define HWC_PRIORITY_LOW_DISPLAY (19)
46
47#ifndef ARRAY_SIZE
48#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
49#endif
50
51#define WIDTH(rect) ((rect).right - (rect).left)
52#define HEIGHT(rect) ((rect).bottom - (rect).top)
53
54static bool is_valid_display(omap_hwc_device_t* hwc_dev, int disp)
55{
56 if (disp < 0 || disp >= MAX_DISPLAYS || !hwc_dev->displays[disp])
57 return false;
58
59 return true;
60}
61
62struct drm_connector_type {
63 int type;
64 char name[64];
65};
66
67#define CONNECTOR_TYPE_STR(type) { DRM_MODE_CONNECTOR_ ## type, #type }
68
69static const struct drm_connector_type connector_type_list[] = {
70 CONNECTOR_TYPE_STR(Unknown),
71 CONNECTOR_TYPE_STR(VGA),
72 CONNECTOR_TYPE_STR(DVII),
73 CONNECTOR_TYPE_STR(DVID),
74 CONNECTOR_TYPE_STR(DVIA),
75 CONNECTOR_TYPE_STR(Composite),
76 CONNECTOR_TYPE_STR(SVIDEO),
77 CONNECTOR_TYPE_STR(LVDS),
78 CONNECTOR_TYPE_STR(Component),
79 CONNECTOR_TYPE_STR(9PinDIN),
80 CONNECTOR_TYPE_STR(DisplayPort),
81 CONNECTOR_TYPE_STR(HDMIA),
82 CONNECTOR_TYPE_STR(HDMIB),
83 CONNECTOR_TYPE_STR(TV),
84 CONNECTOR_TYPE_STR(eDP),
85 CONNECTOR_TYPE_STR(VIRTUAL),
86 CONNECTOR_TYPE_STR(DSI),
87 CONNECTOR_TYPE_STR(DPI),
88};
89
90/* The connectors for primary and external displays can be controlled
91 * by the below system properties
92 * - ro.hwc.primary.conn
93 * - ro.hwc.external.conn
94 * If these are not set (default), `DRM_CONNECTOR_TYPE_Unknown` will be
95 * considered as primary display connector, and `DRM_CONNECTOR_TYPE_HDMIA`
96 * will be considered as secondary display.
97 *
98 * The values are <string> constants, with acceptable values being as defined
99 * by the DRM interface `DRM_CONNECTOR_TYPE_<string>`.
100 *
101 * If nothing is set, external is `HDMIA` connector.
102 */
103static int display_get_connector_type(int disp)
104{
105 char prop_val[PROPERTY_VALUE_MAX];
106
107 if (disp == HWC_DISPLAY_PRIMARY)
108 property_get("ro.hwc.primary.conn", prop_val, "");
109 else
110 property_get("ro.hwc.external.conn", prop_val, "HDMIA");
111
112 for (size_t i = 0; i < ARRAY_SIZE(connector_type_list); i++) {
113 if (!strncasecmp(prop_val, connector_type_list[i].name, 64))
114 return connector_type_list[i].type;
115 }
116
117 return -1;
118}
119
120static void get_connectors(omap_hwc_device_t* hwc_dev)
121{
122 int primary_connector_type = display_get_connector_type(HWC_DISPLAY_PRIMARY);
123 int external_connector_type = display_get_connector_type(HWC_DISPLAY_EXTERNAL);
124
125 // Find primary connector
126 for (auto connector : hwc_dev->card->get_connectors()) {
127 if (primary_connector_type != -1) {
128 if (connector->connector_type() == (uint32_t)primary_connector_type) {
129 hwc_dev->primaryConector = connector;
130 break;
131 }
132 } else {
133 /* If connector type is not specified use the first
134 * connector that is not our HWC_DISPLAY_EXTERNAL connector
135 */
136 if (connector->connector_type() != (uint32_t)external_connector_type) {
137 hwc_dev->primaryConector = connector;
138 break;
139 }
140 }
141 }
142
143 // Find external connector
144 for (auto connector : hwc_dev->card->get_connectors()) {
145 if (connector->connector_type() == (uint32_t)external_connector_type) {
146 hwc_dev->externalConector = connector;
147 break;
148 }
149 }
150}
151
152static int init_primary_display(omap_hwc_device_t* hwc_dev)
153{
154 if (hwc_dev->displays[HWC_DISPLAY_PRIMARY]) {
155 ALOGE("Display %d is already connected", HWC_DISPLAY_PRIMARY);
156 return -EBUSY;
157 }
158
159 kms::Connector* connector = hwc_dev->primaryConector;
160
161 HWCDisplay* display = new HWCDisplay(DISP_ROLE_PRIMARY);
162 hwc_dev->displays[HWC_DISPLAY_PRIMARY] = display;
163
164 if (!connector) {
165 ALOGW("No connector found for primary display");
166 ALOGW("Using dummy primary display");
167
168 display->is_dummy = true;
169
170 display_config_t config;
171 config.xres = LCD_DISPLAY_DEFAULT_HRES;
172 config.yres = LCD_DISPLAY_DEFAULT_VRES;
173 config.fps = LCD_DISPLAY_DEFAULT_FPS;
174 config.xdpi = LCD_DISPLAY_DEFAULT_DPI;
175 config.ydpi = LCD_DISPLAY_DEFAULT_DPI;
176 display->configs.push_back(config);
177
178 return 0;
179 }
180
181 /* Always use default mode for now */
182 kms::Videomode mode = connector->get_default_mode();
183
184 display_config_t config;
185 config.xres = mode.hdisplay;
186 config.yres = mode.vdisplay;
187 config.fps = mode.vrefresh;
188 config.xdpi = LCD_DISPLAY_DEFAULT_DPI;
189 config.ydpi = LCD_DISPLAY_DEFAULT_DPI;
190 display->configs.push_back(config);
191
192 display->disp_link.card = hwc_dev->card;
193 display->disp_link.con = connector;
194 display->disp_link.crtc = connector->get_current_crtc();
195 // FIXME: user resource manager
196 if (!display->disp_link.crtc)
197 display->disp_link.crtc = connector->get_possible_crtcs()[0];
198 display->disp_link.mode = mode;
199
200 display->setup_composition_pipes();
201
202 return 0;
203}
204
205static int add_external_hdmi_display(omap_hwc_device_t* hwc_dev)
206{
207 if (hwc_dev->displays[HWC_DISPLAY_EXTERNAL]) {
208 ALOGE("Display %d is already connected", HWC_DISPLAY_EXTERNAL);
209 return 0;
210 }
211
212 kms::Connector* connector = hwc_dev->externalConector;
213
214 if (!connector) {
215 ALOGE("No connector for external display");
216 return -1;
217 }
218
219 /* wait until EDID read finishes */
220 do {
221 connector->refresh();
222 } while (connector->get_modes().size() == 0);
223
224 // FIXME: Allow selecting other modes until HWC 1.4 support is added
225 kms::Videomode mode = connector->get_default_mode();
226
227 HWCDisplay* display = new HWCDisplay(DISP_ROLE_SECONDARY);
228 hwc_dev->displays[HWC_DISPLAY_EXTERNAL] = display;
229
230 display_config_t config;
231 config.xres = mode.hdisplay;
232 config.yres = mode.vdisplay;
233 config.fps = mode.vrefresh;
234 config.xdpi = HDMI_DISPLAY_DEFAULT_DPI;
235 config.ydpi = HDMI_DISPLAY_DEFAULT_DPI;
236 display->configs.push_back(config);
237
238 display->disp_link.card = hwc_dev->card;
239 display->disp_link.con = connector;
240 display->disp_link.crtc = connector->get_current_crtc();
241 // FIXME: user resource manager
242 if (!display->disp_link.crtc)
243 display->disp_link.crtc = connector->get_possible_crtcs()[0];
244 display->disp_link.mode = mode;
245
246 display->setup_composition_pipes();
247
248 return 0;
249}
250
251static void remove_external_hdmi_display(omap_hwc_device_t* hwc_dev)
252{
253 HWCDisplay* display = hwc_dev->displays[HWC_DISPLAY_EXTERNAL];
254 if (!display) {
255 ALOGW("Failed to remove non-existent display %d", HWC_DISPLAY_EXTERNAL);
256 return;
257 }
258
259 delete hwc_dev->displays[HWC_DISPLAY_EXTERNAL];
260 hwc_dev->displays[HWC_DISPLAY_EXTERNAL] = NULL;
261}
262
263static void handle_hotplug(omap_hwc_device_t* hwc_dev, bool state)
264{
265 if (state) {
266 int err = add_external_hdmi_display(hwc_dev);
267 if (err) {
268 remove_external_hdmi_display(hwc_dev);
269 return;
270 }
271 ALOGI("Added external display");
272 } else {
273 remove_external_hdmi_display(hwc_dev);
274 ALOGI("Removed external display");
275 }
276}
277
278static int find_hdmi_connector_status(omap_hwc_device_t* hwc_dev)
279{
280 auto connector = hwc_dev->externalConector;
281 if (!connector)
282 return false;
283
284 bool old_state = connector->connected();
285 connector->refresh();
286 bool cur_state = connector->connected();
287
288 if (cur_state != old_state)
289 ALOGI("%s event for connector %u\n",
290 cur_state == DRM_MODE_CONNECTED ? "Plug" : "Unplug",
291 connector->id());
292
293 return cur_state == DRM_MODE_CONNECTED;
294}
295
296static bool check_hotplug_status(omap_hwc_device_t* hwc_dev, bool old_state)
297{
298 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
299
300 bool state = find_hdmi_connector_status(hwc_dev);
301 if (state != old_state)
302 handle_hotplug(hwc_dev, state);
303
304 lock.unlock();
305
306 if (hwc_dev->cb_procs) {
307 if (hwc_dev->cb_procs->hotplug)
308 hwc_dev->cb_procs->hotplug(hwc_dev->cb_procs, HWC_DISPLAY_EXTERNAL, state);
309 if (hwc_dev->cb_procs->invalidate)
310 hwc_dev->cb_procs->invalidate(hwc_dev->cb_procs);
311 }
312
313 return state;
314}
315
316static void hwc_hdmi_thread(void* data)
317{
318 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)data;
319
320 setpriority(PRIO_PROCESS, 0, HWC_PRIORITY_LOW_DISPLAY);
321
322 uevent_init();
323
324 struct pollfd pfds[1] = {
325 {
326 pfds[0].fd = uevent_get_fd(),
327 pfds[0].events = POLLIN,
328 pfds[0].revents = 0,
329 }
330 };
331
332 const char* hdmi_uevent_path = "change@/devices/platform/omapdrm.0/drm/card0";
333 static char uevent_desc[4096];
334 memset(uevent_desc, 0, sizeof(uevent_desc));
335
336 /* Check outside of uevent loop in-case already plugged in */
337 bool state = check_hotplug_status(hwc_dev, false);
338
339 while (true) {
340 int err = poll(pfds, ARRAY_SIZE(pfds), -1);
341 if (err < 0) {
342 ALOGE("received hdmi_thread poll() error event %d", err);
343 break;
344 }
345
346 if (pfds[0].revents & POLLIN) {
347 /* keep last 2 zeroes to ensure double 0 termination */
348 uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2);
349 if (strlen(hdmi_uevent_path) <= 0 || strcmp(uevent_desc, hdmi_uevent_path))
350 continue; /* event not for us */
351
352 state = check_hotplug_status(hwc_dev, state);
353 }
354 }
355
356 ALOGE("HDMI polling thread exiting\n");
357}
358
359/*
360 * DRM event polling thread
361 * We poll for DRM events in this thread. DRM events can be vblank and/or
362 * page-flip events both occurring on Vsync.
363 */
364static void hwc_drm_event_thread(void* data)
365{
366 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)data;
367
368 setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
369
370 struct pollfd pfds = {
371 pfds.fd = hwc_dev->card->fd(),
372 pfds.events = POLLIN,
373 pfds.revents = 0,
374 };
375
376 drmEventContext evctx = {
377 evctx.version = 2,
378 evctx.vblank_handler = HWCDisplay::vblank_handler,
379 evctx.page_flip_handler = HWCDisplay::page_flip_handler,
380 };
381
382 while (true) {
383 int ret = poll(&pfds, 1, 60000);
384 if (ret < 0) {
385 ALOGE("Event poll error %d", errno);
386 break;
387 } else if (ret == 0) {
388 ALOGI("Event poll timeout");
389 continue;
390 }
391 if (pfds.revents & POLLIN)
392 drmHandleEvent(pfds.fd, &evctx);
393 }
394
395 ALOGE("DRM event polling thread exiting\n");
396}
397
398static void adjust_drm_plane_to_layer(hwc_layer_1_t* layer, int zorder, drm_plane_props_t* plane)
399{
400 if (!layer || !plane) {
401 ALOGE("Bad layer or plane");
402 return;
403 }
404
405 /* display position */
406 plane->crtc_x = layer->displayFrame.left;
407 plane->crtc_y = layer->displayFrame.top;
408 plane->crtc_w = WIDTH(layer->displayFrame);
409 plane->crtc_h = HEIGHT(layer->displayFrame);
410
411 /* crop */
412 plane->src_x = layer->sourceCrop.left;
413 plane->src_y = layer->sourceCrop.top;
414 plane->src_w = WIDTH(layer->sourceCrop);
415 plane->src_h = HEIGHT(layer->sourceCrop);
416
417 plane->zorder = zorder;
418 plane->layer = layer;
419
420 if (layer->blending == HWC_BLENDING_PREMULT)
421 plane->pre_mult_alpha = 1;
422 else
423 plane->pre_mult_alpha = 0;
424}
425
426static int hwc_prepare_for_display(omap_hwc_device_t* hwc_dev, int disp, hwc_display_contents_1_t* content)
427{
428 if (!is_valid_display(hwc_dev, disp))
429 return -ENODEV;
430
431 HWCDisplay* display = hwc_dev->displays[disp];
432
433 if (display->is_dummy) {
434 for (size_t i = 0; i < content->numHwLayers - 1; i++) {
435 hwc_layer_1_t* layer = &content->hwLayers[i];
436 layer->compositionType = HWC_OVERLAY;
437 }
438 return 0;
439 }
440
441 /* Set the FB_TARGET layer */
442 adjust_drm_plane_to_layer(&content->hwLayers[content->numHwLayers - 1], 0, &display->planeProps[disp]);
443
444 return 0;
445}
446
447static int hwc_prepare(struct hwc_composer_device_1* dev, size_t numDisplays, hwc_display_contents_1_t** displays)
448{
449 atrace_begin(ATRACE_TAG_HAL, "am57xx_hwc_prepare");
450 if (!numDisplays || !displays)
451 return 0;
452
453 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)dev;
454 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
455
456 int err = 0;
457
458 for (size_t i = 0; i < numDisplays; i++) {
459 hwc_display_contents_1_t* contents = displays[i];
460
461 if (!contents)
462 continue;
463
464 if (contents->numHwLayers == 0) {
465 ALOGW("Prepare given no content for display %d", i);
466 continue;
467 }
468
469 int disp_err = hwc_prepare_for_display(hwc_dev, i, contents);
470 if (!err && disp_err)
471 err = disp_err;
472 }
473
474 atrace_end(ATRACE_TAG_HAL);
475 return err;
476}
477
478static int hwc_set_for_display(omap_hwc_device_t* hwc_dev, int disp, hwc_display_contents_1_t* content)
479{
480 if (!is_valid_display(hwc_dev, disp))
481 return -ENODEV;
482
483 HWCDisplay* display = hwc_dev->displays[disp];
484 drm_plane_props_t* planeProp = &display->planeProps[disp];
485
486 int err = 0;
487
488 /*
489 * clear release and retire fence fd's here in case we do
490 * not set them in update_display()
491 */
492 for (size_t i = 0; i < content->numHwLayers; i++) {
493 hwc_layer_1_t* layer = &content->hwLayers[i];
494 layer->releaseFenceFd = -1;
495 }
496 content->retireFenceFd = -1;
497
498 if (!display->is_dummy) {
499 err = display->update_display(planeProp);
500 if (err)
501 ALOGE("Failed to update display %d\n", disp);
502 }
503
504 /* clear any remaining acquire fences */
505 for (size_t i = 0; i < content->numHwLayers; i++) {
506 hwc_layer_1_t* layer = &content->hwLayers[i];
507 if (layer->acquireFenceFd >= 0) {
508 close(layer->acquireFenceFd);
509 layer->acquireFenceFd = -1;
510 }
511 }
512
513 return err;
514}
515
516static int hwc_set(struct hwc_composer_device_1* dev, size_t numDisplays, hwc_display_contents_1_t** displays)
517{
518 atrace_begin(ATRACE_TAG_HAL, "am57xx_hwc_set");
519 if (!numDisplays || !displays)
520 return 0;
521
522 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)dev;
523 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
524
525 int err = 0;
526
527 for (size_t i = 0; i < numDisplays; i++) {
528 hwc_display_contents_1_t* contents = displays[i];
529
530 if (!contents)
531 continue;
532
533 if (contents->numHwLayers == 0) {
534 ALOGE("Set given no content for display %d", i);
535 continue;
536 }
537
538 int disp_err = hwc_set_for_display(hwc_dev, i, contents);
539 if (!err && disp_err)
540 err = disp_err;
541 }
542
543 atrace_end(ATRACE_TAG_HAL);
544 return err;
545}
546
547static int hwc_eventControl(struct hwc_composer_device_1* dev, int disp, int event, int enabled)
548{
549 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)dev;
550 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
551
552 if (!is_valid_display(hwc_dev, disp))
553 return -EINVAL;
554
555 switch (event) {
556 case HWC_EVENT_VSYNC:
557 // FIXME: This is a hack
558 hwc_dev->displays[disp]->cb_procs = hwc_dev->cb_procs;
559
560 ALOGD("%s vsync for display %d", enabled ? "Enabling" : "Disabling", disp);
561 return hwc_dev->displays[disp]->set_vsync_state(enabled);
562
563 default:
564 return -EINVAL;
565 }
566
567 return 0;
568}
569
570static int hwc_blank(struct hwc_composer_device_1* dev, int disp, int blank)
571{
572 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)dev;
573 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
574
575 ALOGD("%s display %d", blank ? "Blanking" : "Unblanking", disp);
576
577 if (!is_valid_display(hwc_dev, disp))
578 return -EINVAL;
579
580 hwc_dev->displays[disp]->blank(blank);
581
582 return 0;
583}
584
585static int hwc_query(struct hwc_composer_device_1* dev, int what, int* value)
586{
587 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)dev;
588 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
589
590 switch (what) {
591 case HWC_BACKGROUND_LAYER_SUPPORTED:
592 // we don't support the background layer yet
593 value[0] = 0;
594 break;
595 case HWC_VSYNC_PERIOD:
596 ALOGW("Query for deprecated vsync value, returning 60Hz");
597 *value = 1000 * 1000 * 1000 / 60;
598 break;
599 case HWC_DISPLAY_TYPES_SUPPORTED:
600 *value = HWC_DISPLAY_PRIMARY_BIT | HWC_DISPLAY_EXTERNAL_BIT;
601 break;
602 default:
603 // unsupported query
604 return -EINVAL;
605 }
606
607 return 0;
608}
609
610static void hwc_registerProcs(struct hwc_composer_device_1* dev, hwc_procs_t const* procs)
611{
612 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)dev;
613 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
614
615 hwc_dev->cb_procs = (typeof(hwc_dev->cb_procs))procs;
616
617 /* now that cb_procs->hotplug is valid */
618 try {
619 hwc_dev->hdmi_thread = new std::thread(hwc_hdmi_thread, hwc_dev);
620 } catch (...) {
621 ALOGE("Failed to create HDMI listening thread (%s)", strerror(errno));
622 }
623}
624
625static int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, uint32_t* configs, size_t* numConfigs)
626{
627 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)dev;
628 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
629
630 if (!is_valid_display(hwc_dev, disp))
631 return -EINVAL;
632
633 HWCDisplay* display = hwc_dev->displays[disp];
634
635 return display->get_display_configs(configs, numConfigs);
636}
637
638static int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, uint32_t config, const uint32_t* attributes, int32_t* values)
639{
640 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)dev;
641 std::unique_lock<std::mutex> lock(hwc_dev->mutex);
642
643 if (!is_valid_display(hwc_dev, disp))
644 return -EINVAL;
645
646 HWCDisplay* display = hwc_dev->displays[disp];
647
648 return display->get_display_attributes(config, attributes, values);
649}
650
651static int hwc_device_close(hw_device_t* device)
652{
653 omap_hwc_device_t* hwc_dev = (omap_hwc_device_t*)device;
654
655 if (hwc_dev) {
656 if (hwc_dev->event_thread)
657 delete hwc_dev->event_thread;
658
659 for (size_t i = 0; i < MAX_DISPLAYS; i++)
660 delete hwc_dev->displays[i];
661
662 delete hwc_dev;
663 }
664
665 return 0;
666}
667
668static int hwc_device_open(const hw_module_t* module, const char* name, hw_device_t** device)
669{
670 if (strcmp(name, HWC_HARDWARE_COMPOSER))
671 return -EINVAL;
672
673 omap_hwc_device_t* hwc_dev = new omap_hwc_device_t;
674 memset(hwc_dev, 0, sizeof(*hwc_dev));
675
676 /* Open DRM device */
677 hwc_dev->card = new kms::Card();
678
679 /* Find primary and external connectors */
680 get_connectors(hwc_dev);
681
682 int ret = init_primary_display(hwc_dev);
683 if (ret) {
684 ALOGE("Could not initialize primary display");
685 return -1;
686 }
687
688 hwc_dev->event_thread = new std::thread(hwc_drm_event_thread, hwc_dev);
689
690 hwc_dev->device.common.tag = HARDWARE_DEVICE_TAG;
691 hwc_dev->device.common.version = HWC_DEVICE_API_VERSION_1_1;
692 hwc_dev->device.common.module = (hw_module_t*)module;
693 hwc_dev->device.common.close = hwc_device_close;
694 hwc_dev->device.prepare = hwc_prepare;
695 hwc_dev->device.set = hwc_set;
696 hwc_dev->device.eventControl = hwc_eventControl;
697 hwc_dev->device.blank = hwc_blank;
698 hwc_dev->device.query = hwc_query;
699 hwc_dev->device.registerProcs = hwc_registerProcs;
700 hwc_dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
701 hwc_dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
702
703 *device = &hwc_dev->device.common;
704
705 return 0;
706}
707
708static struct hw_module_methods_t module_methods = {
709 .open = hwc_device_open,
710};
711
712omap_hwc_module_t HAL_MODULE_INFO_SYM = {
713 .base = {
714 .common = {
715 .tag = HARDWARE_MODULE_TAG,
716 .module_api_version = HWC_MODULE_API_VERSION_0_1,
717 .hal_api_version = HARDWARE_HAL_API_VERSION,
718 .id = HWC_HARDWARE_MODULE_ID,
719 .name = "AM57xx Hardware Composer HAL",
720 .author = "Texas Instruments",
721 .methods = &module_methods,
722 },
723 },
724};
diff --git a/libhwcomposer/hwc_dev.h b/libhwcomposer/hwc_dev.h
new file mode 100644
index 0000000..03d413b
--- /dev/null
+++ b/libhwcomposer/hwc_dev.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef HWC_DEV_H
18#define HWC_DEV_H
19
20#include <mutex>
21#include <thread>
22
23#include <cstdbool>
24#include <cstdint>
25
26#include <hardware/hwcomposer.h>
27#include <kms++/kms++.h>
28
29#include "display.h"
30
31typedef struct omap_hwc_module {
32 hwc_module_t base;
33
34} omap_hwc_module_t;
35
36typedef struct omap_hwc_device {
37 /* static data */
38 hwc_composer_device_1_t device;
39
40 std::mutex mutex;
41
42 std::thread* hdmi_thread;
43 std::thread* event_thread;
44
45 kms::Card* card;
46
47 HWCDisplay* displays[MAX_DISPLAYS];
48
49 kms::Connector* primaryConector;
50 kms::Connector* externalConector;
51
52 drmEventContext evctx;
53
54 const hwc_procs_t* cb_procs;
55} omap_hwc_device_t;
56
57#endif /* HWC_DEV_H */