| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2010 The Android Open Source Project | 
| Saurabh Shah | 56f610d | 2012-08-07 15:27:06 -0700 | [diff] [blame] | 3 |  * Copyright (C) 2012, The Linux Foundation. All rights reserved. | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 4 |  * | 
 | 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 Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 23 | #include <EGL/egl.h> | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 24 |  | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 25 | #include <overlay.h> | 
 | 26 | #include <fb_priv.h> | 
| Naseer Ahmed | 96c4c95 | 2012-07-25 18:27:14 -0700 | [diff] [blame] | 27 | #include <mdp_version.h> | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 28 | #include "hwc_utils.h" | 
| Naseer Ahmed | f48aef6 | 2012-07-20 09:05:53 -0700 | [diff] [blame] | 29 | #include "hwc_video.h" | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 30 | #include "hwc_fbupdate.h" | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 31 | #include "hwc_mdpcomp.h" | 
| Saurabh Shah | 56f610d | 2012-08-07 15:27:06 -0700 | [diff] [blame] | 32 | #include "external.h" | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 33 |  | 
 | 34 | using namespace qhwc; | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 35 | #define VSYNC_DEBUG 0 | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 36 |  | 
 | 37 | static int hwc_device_open(const struct hw_module_t* module, | 
 | 38 |                            const char* name, | 
 | 39 |                            struct hw_device_t** device); | 
 | 40 |  | 
 | 41 | static struct hw_module_methods_t hwc_module_methods = { | 
 | 42 |     open: hwc_device_open | 
 | 43 | }; | 
 | 44 |  | 
 | 45 | hwc_module_t HAL_MODULE_INFO_SYM = { | 
 | 46 |     common: { | 
 | 47 |         tag: HARDWARE_MODULE_TAG, | 
 | 48 |         version_major: 2, | 
 | 49 |         version_minor: 0, | 
 | 50 |         id: HWC_HARDWARE_MODULE_ID, | 
 | 51 |         name: "Qualcomm Hardware Composer Module", | 
 | 52 |         author: "CodeAurora Forum", | 
 | 53 |         methods: &hwc_module_methods, | 
 | 54 |         dso: 0, | 
 | 55 |         reserved: {0}, | 
 | 56 |     } | 
 | 57 | }; | 
 | 58 |  | 
 | 59 | /* | 
 | 60 |  * Save callback functions registered to HWC | 
 | 61 |  */ | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 62 | static void hwc_registerProcs(struct hwc_composer_device_1* dev, | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 63 |                               hwc_procs_t const* procs) | 
 | 64 | { | 
| Iliyan Malchev | 0f9c397 | 2012-10-11 15:16:15 -0700 | [diff] [blame] | 65 |     ALOGI("%s", __FUNCTION__); | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 66 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
 | 67 |     if(!ctx) { | 
 | 68 |         ALOGE("%s: Invalid context", __FUNCTION__); | 
 | 69 |         return; | 
 | 70 |     } | 
| Jesse Hall | 3be78d9 | 2012-08-21 15:12:23 -0700 | [diff] [blame] | 71 |     ctx->proc = procs; | 
 | 72 |  | 
| Naseer Ahmed | ff4f025 | 2012-10-01 13:03:01 -0400 | [diff] [blame] | 73 |     // Now that we have the functions needed, kick off | 
 | 74 |     // the uevent & vsync threads | 
| Jesse Hall | 3be78d9 | 2012-08-21 15:12:23 -0700 | [diff] [blame] | 75 |     init_uevent_thread(ctx); | 
| Naseer Ahmed | ff4f025 | 2012-10-01 13:03:01 -0400 | [diff] [blame] | 76 |     init_vsync_thread(ctx); | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 77 | } | 
 | 78 |  | 
| Saurabh Shah | 649cda6 | 2012-09-16 16:05:58 -0700 | [diff] [blame] | 79 | //Helper | 
| Naseer Ahmed | b1c7632 | 2012-10-17 00:32:50 -0400 | [diff] [blame] | 80 | static void reset(hwc_context_t *ctx, int numDisplays, | 
 | 81 |                   hwc_display_contents_1_t** displays) { | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 82 |     memset(ctx->listStats, 0, sizeof(ctx->listStats)); | 
| Saurabh Shah | 1a8cda0 | 2012-10-12 17:00:39 -0700 | [diff] [blame] | 83 |     for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){ | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 84 |         ctx->listStats[i].yuvIndex = -1; | 
| Naseer Ahmed | b1c7632 | 2012-10-17 00:32:50 -0400 | [diff] [blame] | 85 |         hwc_display_contents_1_t *list = displays[i]; | 
 | 86 |         // XXX:SurfaceFlinger no longer guarantees that this | 
 | 87 |         // value is reset on every prepare. However, for the layer | 
 | 88 |         // cache we need to reset it. | 
 | 89 |         // We can probably rethink that later on | 
 | 90 |         if (LIKELY(list && list->numHwLayers > 1)) { | 
 | 91 |             for(uint32_t j = 0; j < list->numHwLayers; j++) { | 
 | 92 |                 if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET) | 
 | 93 |                     list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; | 
 | 94 |             } | 
 | 95 |         } | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 96 |     } | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 97 |     VideoOverlay::reset(); | 
 | 98 |     FBUpdate::reset(); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 99 | } | 
 | 100 |  | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 101 | //clear prev layer prop flags and realloc for current frame | 
 | 102 | static void reset_layer_prop(hwc_context_t* ctx, int dpy) { | 
 | 103 |     int layer_count = ctx->listStats[dpy].numAppLayers; | 
 | 104 |  | 
 | 105 |     if(ctx->layerProp[dpy]) { | 
 | 106 |        delete[] ctx->layerProp[dpy]; | 
 | 107 |        ctx->layerProp[dpy] = NULL; | 
 | 108 |     } | 
 | 109 |  | 
 | 110 |     if(layer_count) { | 
 | 111 |        ctx->layerProp[dpy] = new LayerProp[layer_count]; | 
 | 112 |     } | 
 | 113 | } | 
 | 114 |  | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 115 | static int hwc_prepare_primary(hwc_composer_device_1 *dev, | 
 | 116 |         hwc_display_contents_1_t *list) { | 
 | 117 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
| Saurabh Shah | 1a8cda0 | 2012-10-12 17:00:39 -0700 | [diff] [blame] | 118 |  | 
 | 119 |     if (LIKELY(list && list->numHwLayers > 1) && | 
 | 120 |         ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { | 
 | 121 |  | 
| Saurabh Shah | 86623d7 | 2012-09-25 19:39:17 -0700 | [diff] [blame] | 122 |         uint32_t last = list->numHwLayers - 1; | 
| Saurabh Shah | 1a8cda0 | 2012-10-12 17:00:39 -0700 | [diff] [blame] | 123 |         hwc_layer_1_t *fbLayer = &list->hwLayers[last]; | 
 | 124 |         if(fbLayer->handle) { | 
 | 125 |             setListStats(ctx, list, HWC_DISPLAY_PRIMARY); | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 126 |             reset_layer_prop(ctx, HWC_DISPLAY_PRIMARY); | 
 | 127 |             if(!MDPComp::configure(ctx, list)) { | 
 | 128 |                 VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY); | 
 | 129 |                 FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_PRIMARY); | 
| Naseer Ahmed | 76e313c | 2012-12-01 18:12:59 -0500 | [diff] [blame] | 130 |                 ctx->mLayerCache->updateLayerCache(list); | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 131 |             } | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 132 |         } | 
 | 133 |     } | 
 | 134 |     return 0; | 
 | 135 | } | 
 | 136 |  | 
 | 137 | static int hwc_prepare_external(hwc_composer_device_1 *dev, | 
 | 138 |         hwc_display_contents_1_t *list) { | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 139 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 140 |  | 
| Saurabh Shah | ae823e7 | 2012-10-05 00:08:11 -0400 | [diff] [blame] | 141 |     if (LIKELY(list && list->numHwLayers > 1) && | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 142 |         ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive && | 
 | 143 |         ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) { | 
 | 144 |  | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 145 |         uint32_t last = list->numHwLayers - 1; | 
| Saurabh Shah | 1a8cda0 | 2012-10-12 17:00:39 -0700 | [diff] [blame] | 146 |         hwc_layer_1_t *fbLayer = &list->hwLayers[last]; | 
 | 147 |         if(fbLayer->handle) { | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 148 |             setListStats(ctx, list, HWC_DISPLAY_EXTERNAL); | 
 | 149 |             reset_layer_prop(ctx, HWC_DISPLAY_EXTERNAL); | 
 | 150 |  | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 151 |             VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL); | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 152 |             FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL); | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 153 |         } | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 154 |     } | 
 | 155 |     return 0; | 
| Saurabh Shah | 649cda6 | 2012-09-16 16:05:58 -0700 | [diff] [blame] | 156 | } | 
 | 157 |  | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 158 | static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, | 
 | 159 |                        hwc_display_contents_1_t** displays) | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 160 | { | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 161 |     int ret = 0; | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 162 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 163 |     Locker::Autolock _l(ctx->mBlankLock); | 
| Naseer Ahmed | b1c7632 | 2012-10-17 00:32:50 -0400 | [diff] [blame] | 164 |     reset(ctx, numDisplays, displays); | 
| Saurabh Shah | 56f610d | 2012-08-07 15:27:06 -0700 | [diff] [blame] | 165 |  | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 166 |     ctx->mOverlay->configBegin(); | 
| Saurabh Shah | 56f610d | 2012-08-07 15:27:06 -0700 | [diff] [blame] | 167 |  | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 168 |     for (int32_t i = numDisplays - 1; i >= 0; i--) { | 
 | 169 |         hwc_display_contents_1_t *list = displays[i]; | 
 | 170 |         switch(i) { | 
 | 171 |             case HWC_DISPLAY_PRIMARY: | 
 | 172 |                 ret = hwc_prepare_primary(dev, list); | 
 | 173 |                 break; | 
 | 174 |             case HWC_DISPLAY_EXTERNAL: | 
 | 175 |  | 
 | 176 |                 ret = hwc_prepare_external(dev, list); | 
 | 177 |                 break; | 
 | 178 |             default: | 
 | 179 |                 ret = -EINVAL; | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 180 |         } | 
 | 181 |     } | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 182 |     ctx->mOverlay->configDone(); | 
 | 183 |  | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 184 |     return ret; | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 185 | } | 
 | 186 |  | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 187 | static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 188 |                              int event, int enabled) | 
 | 189 | { | 
 | 190 |     int ret = 0; | 
| Naseer Ahmed | ff4f025 | 2012-10-01 13:03:01 -0400 | [diff] [blame] | 191 |  | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 192 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
 | 193 |     private_module_t* m = reinterpret_cast<private_module_t*>( | 
 | 194 |                 ctx->mFbDev->common.module); | 
| Iliyan Malchev | eac8965 | 2012-10-04 10:38:28 -0700 | [diff] [blame] | 195 |     pthread_mutex_lock(&ctx->vstate.lock); | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 196 |     switch(event) { | 
 | 197 |         case HWC_EVENT_VSYNC: | 
| Omprakash Dhyade | 1ef881c | 2012-10-03 02:26:55 -0700 | [diff] [blame] | 198 |             if (ctx->vstate.enable == enabled) | 
 | 199 |                 break; | 
| Iliyan Malchev | eac8965 | 2012-10-04 10:38:28 -0700 | [diff] [blame] | 200 |             ctx->vstate.enable = !!enabled; | 
| Naseer Ahmed | c7faa70 | 2012-10-04 15:10:30 -0400 | [diff] [blame] | 201 |             pthread_cond_signal(&ctx->vstate.cond); | 
| Iliyan Malchev | eac8965 | 2012-10-04 10:38:28 -0700 | [diff] [blame] | 202 |             ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s", | 
 | 203 |                       (enabled)?"ENABLED":"DISABLED"); | 
 | 204 |             break; | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 205 |         default: | 
 | 206 |             ret = -EINVAL; | 
 | 207 |     } | 
| Iliyan Malchev | eac8965 | 2012-10-04 10:38:28 -0700 | [diff] [blame] | 208 |     pthread_mutex_unlock(&ctx->vstate.lock); | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 209 |     return ret; | 
 | 210 | } | 
 | 211 |  | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 212 | static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank) | 
 | 213 | { | 
| Naseer Ahmed | 934790c | 2012-08-16 18:11:09 -0700 | [diff] [blame] | 214 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
 | 215 |     private_module_t* m = reinterpret_cast<private_module_t*>( | 
 | 216 |         ctx->mFbDev->common.module); | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 217 |     Locker::Autolock _l(ctx->mBlankLock); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 218 |     int ret = 0; | 
 | 219 |     ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank); | 
 | 220 |     switch(dpy) { | 
 | 221 |         case HWC_DISPLAY_PRIMARY: | 
 | 222 |             if(blank) { | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 223 |                 ctx->mOverlay->configBegin(); | 
 | 224 |                 ctx->mOverlay->configDone(); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 225 |                 ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN); | 
 | 226 |             } else { | 
 | 227 |                 ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK); | 
 | 228 |             } | 
 | 229 |             break; | 
 | 230 |         case HWC_DISPLAY_EXTERNAL: | 
 | 231 |             if(blank) { | 
 | 232 |                 //TODO actual | 
 | 233 |             } else { | 
 | 234 |             } | 
 | 235 |             break; | 
 | 236 |         default: | 
 | 237 |             return -EINVAL; | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 238 |     } | 
| Arun Kumar K.R | f6f49a1 | 2012-11-27 11:46:50 -0800 | [diff] [blame^] | 239 |     // Enable HPD here, as during bootup unblank is called | 
 | 240 |     // when SF is completely initialized | 
 | 241 |     ctx->mExtDisplay->setHPD(1); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 242 |  | 
 | 243 |     if(ret < 0) { | 
 | 244 |         ALOGE("%s: failed. Dpy=%d, blank=%d : %s", | 
 | 245 |                 __FUNCTION__, dpy, blank, strerror(errno)); | 
 | 246 |         return ret; | 
 | 247 |     } | 
 | 248 |     ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank); | 
 | 249 |     ctx->dpyAttr[dpy].isActive = !blank; | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 250 |     return 0; | 
 | 251 | } | 
 | 252 |  | 
 | 253 | static int hwc_query(struct hwc_composer_device_1* dev, | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 254 |                      int param, int* value) | 
 | 255 | { | 
 | 256 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
 | 257 |     private_module_t* m = reinterpret_cast<private_module_t*>( | 
 | 258 |         ctx->mFbDev->common.module); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 259 |     int supported = HWC_DISPLAY_PRIMARY_BIT; | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 260 |  | 
 | 261 |     switch (param) { | 
 | 262 |     case HWC_BACKGROUND_LAYER_SUPPORTED: | 
 | 263 |         // Not supported for now | 
 | 264 |         value[0] = 0; | 
 | 265 |         break; | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 266 |     case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1 | 
| Saurabh Shah | 2e2798c | 2012-08-30 14:47:10 -0700 | [diff] [blame] | 267 |         value[0] = m->fps; | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 268 |         ALOGI("fps: %d", value[0]); | 
 | 269 |         break; | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 270 |     case HWC_DISPLAY_TYPES_SUPPORTED: | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 271 |         if(ctx->mMDP.hasOverlay) | 
 | 272 |             supported |= HWC_DISPLAY_EXTERNAL_BIT; | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 273 |         value[0] = supported; | 
 | 274 |         break; | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 275 |     default: | 
 | 276 |         return -EINVAL; | 
 | 277 |     } | 
 | 278 |     return 0; | 
 | 279 |  | 
 | 280 | } | 
 | 281 |  | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 282 | static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 283 |     int ret = 0; | 
 | 284 |  | 
| Saurabh Shah | ae823e7 | 2012-10-05 00:08:11 -0400 | [diff] [blame] | 285 |     if (LIKELY(list && list->numHwLayers > 1) && | 
 | 286 |         ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 287 |         uint32_t last = list->numHwLayers - 1; | 
 | 288 |         hwc_layer_1_t *fbLayer = &list->hwLayers[last]; | 
 | 289 |  | 
| Saurabh Shah | 8c8bfd2 | 2012-09-26 21:09:40 -0700 | [diff] [blame] | 290 |         hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY); | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 291 |         if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) { | 
 | 292 |             ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__); | 
 | 293 |             ret = -1; | 
 | 294 |         } | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 295 |         if (!MDPComp::draw(ctx, list)) { | 
 | 296 |             ALOGE("%s: MDPComp::draw fail!", __FUNCTION__); | 
 | 297 |             ret = -1; | 
 | 298 |         } | 
 | 299 |  | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 300 |         //TODO We dont check for SKIP flag on this layer because we need PAN | 
 | 301 |         //always. Last layer is always FB | 
| Naseer Ahmed | 54821fe | 2012-11-28 18:44:38 -0500 | [diff] [blame] | 302 |         private_handle_t *hnd = (private_handle_t *)fbLayer->handle; | 
 | 303 |         if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) { | 
 | 304 |             if(!(fbLayer->flags & HWC_SKIP_LAYER)) { | 
 | 305 |                 if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_PRIMARY)) { | 
 | 306 |                     ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); | 
 | 307 |                     ret = -1; | 
 | 308 |                 } | 
 | 309 |             } | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 310 |             if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) { | 
 | 311 |                 ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__); | 
 | 312 |                 return -1; | 
 | 313 |             } | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 314 |         } | 
 | 315 |     } | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 316 |     return ret; | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 317 | } | 
 | 318 |  | 
 | 319 | static int hwc_set_external(hwc_context_t *ctx, | 
 | 320 |         hwc_display_contents_1_t* list) { | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 321 |     int ret = 0; | 
| Kinjal Bhavsar | f83d448 | 2012-10-10 15:56:21 -0700 | [diff] [blame] | 322 |     Locker::Autolock _l(ctx->mExtSetLock); | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 323 |  | 
| Saurabh Shah | ae823e7 | 2012-10-05 00:08:11 -0400 | [diff] [blame] | 324 |     if (LIKELY(list && list->numHwLayers > 1) && | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 325 |         ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive && | 
 | 326 |         ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) { | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 327 |         uint32_t last = list->numHwLayers - 1; | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 328 |         hwc_layer_1_t *fbLayer = &list->hwLayers[last]; | 
 | 329 |  | 
 | 330 |         hwc_sync(ctx, list, HWC_DISPLAY_EXTERNAL); | 
 | 331 |  | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 332 |         if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_EXTERNAL)) { | 
 | 333 |             ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__); | 
 | 334 |             ret = -1; | 
 | 335 |         } | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 336 |  | 
 | 337 |         private_handle_t *hnd = (private_handle_t *)fbLayer->handle; | 
| Saurabh Shah | 150806a | 2012-10-09 15:38:23 -0700 | [diff] [blame] | 338 |         if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && | 
 | 339 |                 !(fbLayer->flags & HWC_SKIP_LAYER) && hnd) { | 
| Naseer Ahmed | 758bfc5 | 2012-11-28 17:02:08 -0500 | [diff] [blame] | 340 |             if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_EXTERNAL)) { | 
 | 341 |                 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 342 |                 ret = -1; | 
 | 343 |             } | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 344 |         } | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 345 |         if (!ctx->mExtDisplay->post()) { | 
 | 346 |             ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__); | 
 | 347 |             return -1; | 
 | 348 |         } | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 349 |     } | 
| Saurabh Shah | eaf6791 | 2012-10-10 17:33:14 -0700 | [diff] [blame] | 350 |     return ret; | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 351 | } | 
 | 352 |  | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 353 | static int hwc_set(hwc_composer_device_1 *dev, | 
 | 354 |                    size_t numDisplays, | 
 | 355 |                    hwc_display_contents_1_t** displays) | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 356 | { | 
 | 357 |     int ret = 0; | 
 | 358 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
| Naseer Ahmed | 32ff225 | 2012-09-29 01:41:21 -0400 | [diff] [blame] | 359 |     Locker::Autolock _l(ctx->mBlankLock); | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 360 |  | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 361 |     for (uint32_t i = 0; i < numDisplays; i++) { | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 362 |         hwc_display_contents_1_t* list = displays[i]; | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 363 |         switch(i) { | 
 | 364 |             case HWC_DISPLAY_PRIMARY: | 
 | 365 |                 ret = hwc_set_primary(ctx, list); | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 366 |                 break; | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 367 |             case HWC_DISPLAY_EXTERNAL: | 
 | 368 |                 ret = hwc_set_external(ctx, list); | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 369 |                 break; | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 370 |             default: | 
 | 371 |                 ret = -EINVAL; | 
| Naseer Ahmed | 5b6708a | 2012-08-02 13:46:08 -0700 | [diff] [blame] | 372 |         } | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 373 |     } | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 374 |     return ret; | 
 | 375 | } | 
 | 376 |  | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 377 | int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, | 
 | 378 |         uint32_t* configs, size_t* numConfigs) { | 
 | 379 |     int ret = 0; | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 380 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 381 |     //in 1.1 there is no way to choose a config, report as config id # 0 | 
 | 382 |     //This config is passed to getDisplayAttributes. Ignore for now. | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 383 |     switch(disp) { | 
 | 384 |         case HWC_DISPLAY_PRIMARY: | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 385 |             if(*numConfigs > 0) { | 
 | 386 |                 configs[0] = 0; | 
 | 387 |                 *numConfigs = 1; | 
 | 388 |             } | 
 | 389 |             ret = 0; //NO_ERROR | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 390 |             break; | 
 | 391 |         case HWC_DISPLAY_EXTERNAL: | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 392 |             ret = -1; //Not connected | 
 | 393 |             if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) { | 
 | 394 |                 ret = 0; //NO_ERROR | 
 | 395 |                 if(*numConfigs > 0) { | 
 | 396 |                     configs[0] = 0; | 
 | 397 |                     *numConfigs = 1; | 
 | 398 |                 } | 
 | 399 |             } | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 400 |             break; | 
 | 401 |     } | 
 | 402 |     return ret; | 
 | 403 | } | 
 | 404 |  | 
 | 405 | int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, | 
 | 406 |         uint32_t config, const uint32_t* attributes, int32_t* values) { | 
 | 407 |  | 
 | 408 |     hwc_context_t* ctx = (hwc_context_t*)(dev); | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 409 |     //If hotpluggable displays are inactive return error | 
 | 410 |     if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) { | 
 | 411 |         return -1; | 
 | 412 |     } | 
 | 413 |  | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 414 |     //From HWComposer | 
 | 415 |     static const uint32_t DISPLAY_ATTRIBUTES[] = { | 
 | 416 |         HWC_DISPLAY_VSYNC_PERIOD, | 
 | 417 |         HWC_DISPLAY_WIDTH, | 
 | 418 |         HWC_DISPLAY_HEIGHT, | 
 | 419 |         HWC_DISPLAY_DPI_X, | 
 | 420 |         HWC_DISPLAY_DPI_Y, | 
 | 421 |         HWC_DISPLAY_NO_ATTRIBUTE, | 
 | 422 |     }; | 
 | 423 |  | 
 | 424 |     const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) / | 
 | 425 |             sizeof(DISPLAY_ATTRIBUTES)[0]); | 
 | 426 |  | 
 | 427 |     for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { | 
 | 428 |         switch (attributes[i]) { | 
 | 429 |         case HWC_DISPLAY_VSYNC_PERIOD: | 
 | 430 |             values[i] = ctx->dpyAttr[disp].vsync_period; | 
 | 431 |             break; | 
 | 432 |         case HWC_DISPLAY_WIDTH: | 
 | 433 |             values[i] = ctx->dpyAttr[disp].xres; | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 434 |             ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp, | 
 | 435 |                     ctx->dpyAttr[disp].xres); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 436 |             break; | 
 | 437 |         case HWC_DISPLAY_HEIGHT: | 
 | 438 |             values[i] = ctx->dpyAttr[disp].yres; | 
| Saurabh Shah | c4d034f | 2012-09-27 15:55:15 -0700 | [diff] [blame] | 439 |             ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp, | 
 | 440 |                     ctx->dpyAttr[disp].yres); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 441 |             break; | 
 | 442 |         case HWC_DISPLAY_DPI_X: | 
| Naseer Ahmed | 7b80d9c | 2012-09-26 20:14:38 -0400 | [diff] [blame] | 443 |             values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 444 |             break; | 
 | 445 |         case HWC_DISPLAY_DPI_Y: | 
| Naseer Ahmed | 7b80d9c | 2012-09-26 20:14:38 -0400 | [diff] [blame] | 446 |             values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0); | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 447 |             break; | 
 | 448 |         default: | 
 | 449 |             ALOGE("Unknown display attribute %d", | 
 | 450 |                     attributes[i]); | 
 | 451 |             return -EINVAL; | 
 | 452 |         } | 
 | 453 |     } | 
 | 454 |     return 0; | 
 | 455 | } | 
 | 456 |  | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 457 | static int hwc_device_close(struct hw_device_t *dev) | 
 | 458 | { | 
 | 459 |     if(!dev) { | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 460 |         ALOGE("%s: NULL device pointer", __FUNCTION__); | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 461 |         return -1; | 
 | 462 |     } | 
 | 463 |     closeContext((hwc_context_t*)dev); | 
 | 464 |     free(dev); | 
 | 465 |  | 
 | 466 |     return 0; | 
 | 467 | } | 
 | 468 |  | 
 | 469 | static int hwc_device_open(const struct hw_module_t* module, const char* name, | 
 | 470 |                            struct hw_device_t** device) | 
 | 471 | { | 
 | 472 |     int status = -EINVAL; | 
 | 473 |  | 
 | 474 |     if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { | 
 | 475 |         struct hwc_context_t *dev; | 
 | 476 |         dev = (hwc_context_t*)malloc(sizeof(*dev)); | 
 | 477 |         memset(dev, 0, sizeof(*dev)); | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 478 |  | 
 | 479 |         //Initialize hwc context | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 480 |         initContext(dev); | 
| Naseer Ahmed | 72cf976 | 2012-07-21 12:17:13 -0700 | [diff] [blame] | 481 |  | 
 | 482 |         //Setup HWC methods | 
| Saurabh Shah | 3e858eb | 2012-09-17 16:53:21 -0700 | [diff] [blame] | 483 |         dev->device.common.tag          = HARDWARE_DEVICE_TAG; | 
 | 484 |         dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1; | 
 | 485 |         dev->device.common.module       = const_cast<hw_module_t*>(module); | 
 | 486 |         dev->device.common.close        = hwc_device_close; | 
 | 487 |         dev->device.prepare             = hwc_prepare; | 
 | 488 |         dev->device.set                 = hwc_set; | 
 | 489 |         dev->device.eventControl        = hwc_eventControl; | 
 | 490 |         dev->device.blank               = hwc_blank; | 
 | 491 |         dev->device.query               = hwc_query; | 
 | 492 |         dev->device.registerProcs       = hwc_registerProcs; | 
 | 493 |         dev->device.dump                = NULL; | 
 | 494 |         dev->device.getDisplayConfigs   = hwc_getDisplayConfigs; | 
 | 495 |         dev->device.getDisplayAttributes = hwc_getDisplayAttributes; | 
 | 496 |         *device = &dev->device.common; | 
| Naseer Ahmed | 29a2681 | 2012-06-14 00:56:20 -0700 | [diff] [blame] | 497 |         status = 0; | 
 | 498 |     } | 
 | 499 |     return status; | 
 | 500 | } |