blob: f331f84289f0fa53e5a0e648fd2c6c0b31827d5f [file] [log] [blame]
Naseer Ahmed29a26812012-06-14 00:56:20 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
Saurabh Shah56f610d2012-08-07 15:27:06 -07003 * Copyright (C) 2012, The Linux Foundation. All rights reserved.
Naseer Ahmed29a26812012-06-14 00:56:20 -07004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <fcntl.h>
19#include <errno.h>
20
21#include <cutils/log.h>
22#include <cutils/atomic.h>
Naseer Ahmed72cf9762012-07-21 12:17:13 -070023#include <EGL/egl.h>
Naseer Ahmed29a26812012-06-14 00:56:20 -070024
Naseer Ahmed72cf9762012-07-21 12:17:13 -070025#include <overlay.h>
26#include <fb_priv.h>
Naseer Ahmed96c4c952012-07-25 18:27:14 -070027#include <mdp_version.h>
Naseer Ahmed29a26812012-06-14 00:56:20 -070028#include "hwc_utils.h"
Naseer Ahmedf48aef62012-07-20 09:05:53 -070029#include "hwc_video.h"
Naseer Ahmed758bfc52012-11-28 17:02:08 -050030#include "hwc_fbupdate.h"
Saurabh Shah56f610d2012-08-07 15:27:06 -070031#include "external.h"
Naseer Ahmed29a26812012-06-14 00:56:20 -070032
33using namespace qhwc;
Naseer Ahmed758bfc52012-11-28 17:02:08 -050034#define VSYNC_DEBUG 0
Naseer Ahmed29a26812012-06-14 00:56:20 -070035
36static int hwc_device_open(const struct hw_module_t* module,
37 const char* name,
38 struct hw_device_t** device);
39
40static struct hw_module_methods_t hwc_module_methods = {
41 open: hwc_device_open
42};
43
44hwc_module_t HAL_MODULE_INFO_SYM = {
45 common: {
46 tag: HARDWARE_MODULE_TAG,
47 version_major: 2,
48 version_minor: 0,
49 id: HWC_HARDWARE_MODULE_ID,
50 name: "Qualcomm Hardware Composer Module",
51 author: "CodeAurora Forum",
52 methods: &hwc_module_methods,
53 dso: 0,
54 reserved: {0},
55 }
56};
57
58/*
59 * Save callback functions registered to HWC
60 */
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070061static void hwc_registerProcs(struct hwc_composer_device_1* dev,
Naseer Ahmed29a26812012-06-14 00:56:20 -070062 hwc_procs_t const* procs)
63{
Iliyan Malchev0f9c3972012-10-11 15:16:15 -070064 ALOGI("%s", __FUNCTION__);
Naseer Ahmed29a26812012-06-14 00:56:20 -070065 hwc_context_t* ctx = (hwc_context_t*)(dev);
66 if(!ctx) {
67 ALOGE("%s: Invalid context", __FUNCTION__);
68 return;
69 }
Jesse Hall3be78d92012-08-21 15:12:23 -070070 ctx->proc = procs;
71
Naseer Ahmedff4f0252012-10-01 13:03:01 -040072 // Now that we have the functions needed, kick off
73 // the uevent & vsync threads
Jesse Hall3be78d92012-08-21 15:12:23 -070074 init_uevent_thread(ctx);
Naseer Ahmedff4f0252012-10-01 13:03:01 -040075 init_vsync_thread(ctx);
Naseer Ahmed29a26812012-06-14 00:56:20 -070076}
77
Saurabh Shah649cda62012-09-16 16:05:58 -070078//Helper
Naseer Ahmedb1c76322012-10-17 00:32:50 -040079static void reset(hwc_context_t *ctx, int numDisplays,
80 hwc_display_contents_1_t** displays) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -070081 memset(ctx->listStats, 0, sizeof(ctx->listStats));
Saurabh Shah1a8cda02012-10-12 17:00:39 -070082 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){
Saurabh Shah3e858eb2012-09-17 16:53:21 -070083 ctx->listStats[i].yuvIndex = -1;
Naseer Ahmedb1c76322012-10-17 00:32:50 -040084 hwc_display_contents_1_t *list = displays[i];
85 // XXX:SurfaceFlinger no longer guarantees that this
86 // value is reset on every prepare. However, for the layer
87 // cache we need to reset it.
88 // We can probably rethink that later on
89 if (LIKELY(list && list->numHwLayers > 1)) {
90 for(uint32_t j = 0; j < list->numHwLayers; j++) {
91 if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
92 list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
93 }
94 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -070095 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -050096 VideoOverlay::reset();
97 FBUpdate::reset();
Saurabh Shah3e858eb2012-09-17 16:53:21 -070098}
99
100static int hwc_prepare_primary(hwc_composer_device_1 *dev,
101 hwc_display_contents_1_t *list) {
102 hwc_context_t* ctx = (hwc_context_t*)(dev);
Saurabh Shah1a8cda02012-10-12 17:00:39 -0700103
104 if (LIKELY(list && list->numHwLayers > 1) &&
105 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
106
Saurabh Shah86623d72012-09-25 19:39:17 -0700107 uint32_t last = list->numHwLayers - 1;
Saurabh Shah1a8cda02012-10-12 17:00:39 -0700108 hwc_layer_1_t *fbLayer = &list->hwLayers[last];
109 if(fbLayer->handle) {
110 setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
Naseer Ahmedb1c76322012-10-17 00:32:50 -0400111 ctx->mLayerCache->updateLayerCache(list);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500112 VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY);
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700113 }
114 }
115 return 0;
116}
117
118static int hwc_prepare_external(hwc_composer_device_1 *dev,
119 hwc_display_contents_1_t *list) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700120 hwc_context_t* ctx = (hwc_context_t*)(dev);
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700121
Saurabh Shahae823e72012-10-05 00:08:11 -0400122 if (LIKELY(list && list->numHwLayers > 1) &&
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700123 ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
124 ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
125
126 setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
127
128 uint32_t last = list->numHwLayers - 1;
Saurabh Shah1a8cda02012-10-12 17:00:39 -0700129 hwc_layer_1_t *fbLayer = &list->hwLayers[last];
130 if(fbLayer->handle) {
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500131 FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL);
132 VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL);
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700133 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700134 }
135 return 0;
Saurabh Shah649cda62012-09-16 16:05:58 -0700136}
137
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700138static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
139 hwc_display_contents_1_t** displays)
Naseer Ahmed29a26812012-06-14 00:56:20 -0700140{
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700141 int ret = 0;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700142 hwc_context_t* ctx = (hwc_context_t*)(dev);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500143 Locker::Autolock _l(ctx->mBlankLock);
Naseer Ahmedb1c76322012-10-17 00:32:50 -0400144 reset(ctx, numDisplays, displays);
Saurabh Shah56f610d2012-08-07 15:27:06 -0700145
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500146 ctx->mOverlay->configBegin();
Saurabh Shah56f610d2012-08-07 15:27:06 -0700147
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500148 //If securing of h/w in progress skip comp using overlay.
149 //TODO remove from here when sending FB via overlay
150 if(ctx->mSecuring == false) {
151 for (uint32_t i = 0; i < numDisplays; i++) {
152 hwc_display_contents_1_t *list = displays[i];
153 switch(i) {
154 case HWC_DISPLAY_PRIMARY:
155 ret = hwc_prepare_primary(dev, list);
156 break;
157 case HWC_DISPLAY_EXTERNAL:
158 ret = hwc_prepare_external(dev, list);
159 break;
160 default:
161 ret = -EINVAL;
162 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700163 }
164 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500165
166 ctx->mOverlay->configDone();
167
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700168 return ret;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700169}
170
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700171static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700172 int event, int enabled)
173{
174 int ret = 0;
Naseer Ahmedff4f0252012-10-01 13:03:01 -0400175
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700176 hwc_context_t* ctx = (hwc_context_t*)(dev);
177 private_module_t* m = reinterpret_cast<private_module_t*>(
178 ctx->mFbDev->common.module);
Iliyan Malcheveac89652012-10-04 10:38:28 -0700179 pthread_mutex_lock(&ctx->vstate.lock);
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700180 switch(event) {
181 case HWC_EVENT_VSYNC:
Omprakash Dhyade1ef881c2012-10-03 02:26:55 -0700182 if (ctx->vstate.enable == enabled)
183 break;
Iliyan Malcheveac89652012-10-04 10:38:28 -0700184 ctx->vstate.enable = !!enabled;
Naseer Ahmedc7faa702012-10-04 15:10:30 -0400185 pthread_cond_signal(&ctx->vstate.cond);
Iliyan Malcheveac89652012-10-04 10:38:28 -0700186 ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
187 (enabled)?"ENABLED":"DISABLED");
188 break;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700189 default:
190 ret = -EINVAL;
191 }
Iliyan Malcheveac89652012-10-04 10:38:28 -0700192 pthread_mutex_unlock(&ctx->vstate.lock);
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700193 return ret;
194}
195
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700196static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
197{
Naseer Ahmed934790c2012-08-16 18:11:09 -0700198 hwc_context_t* ctx = (hwc_context_t*)(dev);
199 private_module_t* m = reinterpret_cast<private_module_t*>(
200 ctx->mFbDev->common.module);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500201 Locker::Autolock _l(ctx->mBlankLock);
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700202 int ret = 0;
203 ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
204 switch(dpy) {
205 case HWC_DISPLAY_PRIMARY:
206 if(blank) {
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500207 ctx->mOverlay->configBegin();
208 ctx->mOverlay->configDone();
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700209 ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
210 } else {
211 ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
212 }
213 break;
214 case HWC_DISPLAY_EXTERNAL:
215 if(blank) {
216 //TODO actual
217 } else {
218 }
219 break;
220 default:
221 return -EINVAL;
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700222 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700223
224 if(ret < 0) {
225 ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
226 __FUNCTION__, dpy, blank, strerror(errno));
227 return ret;
228 }
229 ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
230 ctx->dpyAttr[dpy].isActive = !blank;
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700231 return 0;
232}
233
234static int hwc_query(struct hwc_composer_device_1* dev,
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700235 int param, int* value)
236{
237 hwc_context_t* ctx = (hwc_context_t*)(dev);
238 private_module_t* m = reinterpret_cast<private_module_t*>(
239 ctx->mFbDev->common.module);
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700240 int supported = HWC_DISPLAY_PRIMARY_BIT;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700241
242 switch (param) {
243 case HWC_BACKGROUND_LAYER_SUPPORTED:
244 // Not supported for now
245 value[0] = 0;
246 break;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700247 case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
Saurabh Shah2e2798c2012-08-30 14:47:10 -0700248 value[0] = m->fps;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700249 ALOGI("fps: %d", value[0]);
250 break;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700251 case HWC_DISPLAY_TYPES_SUPPORTED:
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700252 if(ctx->mMDP.hasOverlay)
253 supported |= HWC_DISPLAY_EXTERNAL_BIT;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700254 value[0] = supported;
255 break;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700256 default:
257 return -EINVAL;
258 }
259 return 0;
260
261}
262
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700263static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
Saurabh Shaheaf67912012-10-10 17:33:14 -0700264 int ret = 0;
265
Saurabh Shahae823e72012-10-05 00:08:11 -0400266 if (LIKELY(list && list->numHwLayers > 1) &&
267 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700268 uint32_t last = list->numHwLayers - 1;
269 hwc_layer_1_t *fbLayer = &list->hwLayers[last];
270
Saurabh Shah8c8bfd22012-09-26 21:09:40 -0700271 hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY);
272
Saurabh Shaheaf67912012-10-10 17:33:14 -0700273 if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) {
274 ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
275 ret = -1;
276 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700277 //TODO We dont check for SKIP flag on this layer because we need PAN
278 //always. Last layer is always FB
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700279 if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET) {
Saurabh Shaheaf67912012-10-10 17:33:14 -0700280 if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
281 ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
282 return -1;
283 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700284 }
285 }
Saurabh Shaheaf67912012-10-10 17:33:14 -0700286 return ret;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700287}
288
289static int hwc_set_external(hwc_context_t *ctx,
290 hwc_display_contents_1_t* list) {
Saurabh Shaheaf67912012-10-10 17:33:14 -0700291 int ret = 0;
Kinjal Bhavsarf83d4482012-10-10 15:56:21 -0700292 Locker::Autolock _l(ctx->mExtSetLock);
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700293
Saurabh Shahae823e72012-10-05 00:08:11 -0400294 if (LIKELY(list && list->numHwLayers > 1) &&
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700295 ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
296 ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700297 uint32_t last = list->numHwLayers - 1;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700298 hwc_layer_1_t *fbLayer = &list->hwLayers[last];
299
300 hwc_sync(ctx, list, HWC_DISPLAY_EXTERNAL);
301
Saurabh Shaheaf67912012-10-10 17:33:14 -0700302 if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_EXTERNAL)) {
303 ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
304 ret = -1;
305 }
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700306
307 private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
Saurabh Shah150806a2012-10-09 15:38:23 -0700308 if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
309 !(fbLayer->flags & HWC_SKIP_LAYER) && hnd) {
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500310 if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_EXTERNAL)) {
311 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
Saurabh Shaheaf67912012-10-10 17:33:14 -0700312 ret = -1;
313 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700314 }
Saurabh Shaheaf67912012-10-10 17:33:14 -0700315 if (!ctx->mExtDisplay->post()) {
316 ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__);
317 return -1;
318 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700319 }
Saurabh Shaheaf67912012-10-10 17:33:14 -0700320 return ret;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700321}
322
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700323static int hwc_set(hwc_composer_device_1 *dev,
324 size_t numDisplays,
325 hwc_display_contents_1_t** displays)
Naseer Ahmed29a26812012-06-14 00:56:20 -0700326{
327 int ret = 0;
328 hwc_context_t* ctx = (hwc_context_t*)(dev);
Naseer Ahmed32ff2252012-09-29 01:41:21 -0400329 Locker::Autolock _l(ctx->mBlankLock);
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700330
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700331 for (uint32_t i = 0; i < numDisplays; i++) {
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700332 hwc_display_contents_1_t* list = displays[i];
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700333 switch(i) {
334 case HWC_DISPLAY_PRIMARY:
335 ret = hwc_set_primary(ctx, list);
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700336 break;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700337 case HWC_DISPLAY_EXTERNAL:
338 ret = hwc_set_external(ctx, list);
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700339 break;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700340 default:
341 ret = -EINVAL;
Naseer Ahmed5b6708a2012-08-02 13:46:08 -0700342 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700343 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700344 return ret;
345}
346
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700347int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
348 uint32_t* configs, size_t* numConfigs) {
349 int ret = 0;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700350 hwc_context_t* ctx = (hwc_context_t*)(dev);
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700351 //in 1.1 there is no way to choose a config, report as config id # 0
352 //This config is passed to getDisplayAttributes. Ignore for now.
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700353 switch(disp) {
354 case HWC_DISPLAY_PRIMARY:
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700355 if(*numConfigs > 0) {
356 configs[0] = 0;
357 *numConfigs = 1;
358 }
359 ret = 0; //NO_ERROR
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700360 break;
361 case HWC_DISPLAY_EXTERNAL:
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700362 ret = -1; //Not connected
363 if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
364 ret = 0; //NO_ERROR
365 if(*numConfigs > 0) {
366 configs[0] = 0;
367 *numConfigs = 1;
368 }
369 }
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700370 break;
371 }
372 return ret;
373}
374
375int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
376 uint32_t config, const uint32_t* attributes, int32_t* values) {
377
378 hwc_context_t* ctx = (hwc_context_t*)(dev);
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700379 //If hotpluggable displays are inactive return error
380 if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
381 return -1;
382 }
383
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700384 //From HWComposer
385 static const uint32_t DISPLAY_ATTRIBUTES[] = {
386 HWC_DISPLAY_VSYNC_PERIOD,
387 HWC_DISPLAY_WIDTH,
388 HWC_DISPLAY_HEIGHT,
389 HWC_DISPLAY_DPI_X,
390 HWC_DISPLAY_DPI_Y,
391 HWC_DISPLAY_NO_ATTRIBUTE,
392 };
393
394 const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
395 sizeof(DISPLAY_ATTRIBUTES)[0]);
396
397 for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
398 switch (attributes[i]) {
399 case HWC_DISPLAY_VSYNC_PERIOD:
400 values[i] = ctx->dpyAttr[disp].vsync_period;
401 break;
402 case HWC_DISPLAY_WIDTH:
403 values[i] = ctx->dpyAttr[disp].xres;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700404 ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
405 ctx->dpyAttr[disp].xres);
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700406 break;
407 case HWC_DISPLAY_HEIGHT:
408 values[i] = ctx->dpyAttr[disp].yres;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700409 ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
410 ctx->dpyAttr[disp].yres);
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700411 break;
412 case HWC_DISPLAY_DPI_X:
Naseer Ahmed7b80d9c2012-09-26 20:14:38 -0400413 values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700414 break;
415 case HWC_DISPLAY_DPI_Y:
Naseer Ahmed7b80d9c2012-09-26 20:14:38 -0400416 values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700417 break;
418 default:
419 ALOGE("Unknown display attribute %d",
420 attributes[i]);
421 return -EINVAL;
422 }
423 }
424 return 0;
425}
426
Naseer Ahmed29a26812012-06-14 00:56:20 -0700427static int hwc_device_close(struct hw_device_t *dev)
428{
429 if(!dev) {
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700430 ALOGE("%s: NULL device pointer", __FUNCTION__);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700431 return -1;
432 }
433 closeContext((hwc_context_t*)dev);
434 free(dev);
435
436 return 0;
437}
438
439static int hwc_device_open(const struct hw_module_t* module, const char* name,
440 struct hw_device_t** device)
441{
442 int status = -EINVAL;
443
444 if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
445 struct hwc_context_t *dev;
446 dev = (hwc_context_t*)malloc(sizeof(*dev));
447 memset(dev, 0, sizeof(*dev));
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700448
449 //Initialize hwc context
Naseer Ahmed29a26812012-06-14 00:56:20 -0700450 initContext(dev);
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700451
452 //Setup HWC methods
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700453 dev->device.common.tag = HARDWARE_DEVICE_TAG;
454 dev->device.common.version = HWC_DEVICE_API_VERSION_1_1;
455 dev->device.common.module = const_cast<hw_module_t*>(module);
456 dev->device.common.close = hwc_device_close;
457 dev->device.prepare = hwc_prepare;
458 dev->device.set = hwc_set;
459 dev->device.eventControl = hwc_eventControl;
460 dev->device.blank = hwc_blank;
461 dev->device.query = hwc_query;
462 dev->device.registerProcs = hwc_registerProcs;
463 dev->device.dump = NULL;
464 dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
465 dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
466 *device = &dev->device.common;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700467 status = 0;
468 }
469 return status;
470}