1 /* 2 // Copyright(c)2014 IntelCorporation 3 // 4 // LicensedundertheApacheLicense,Version2.0(the"License"); 5 // youmaynotusethisfileexceptincompliancewiththeLicense. 6 // YoumayobtainacopyoftheLicenseat 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software 11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS, 12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. 13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand 14 // limitationsundertheLicense. 15 */ 16 #include <HwcTrace.h> 17 #include <Hwcomposer.h> 18 #include <Drm.h> 19 #include <DisplayPlane.h> 20 #include <IDisplayDevice.h> 21 #include <HwcLayerList.h> 22 #include <tangier/TngDisplayContext.h> 23 24 25 namespace android { 26 namespace intel { 27 28 TngDisplayContext::TngDisplayContext() 29 : mIMGDisplayDevice(0), 30 mInitialized(false), 31 mCount(0) 32 { 33 CTRACE(); 34 } 35 36 TngDisplayContext::~TngDisplayContext() 37 { 38 WARN_IF_NOT_DEINIT(); 39 } 40 41 bool TngDisplayContext::initialize() 42 { 43 CTRACE(); 44 45 // open frame buffer device 46 hw_module_t const* module; 47 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); 48 if (err) { 49 ETRACE("failed to load gralloc module, error = %d", err); 50 return false; 51 } 52 53 // init IMG display device 54 mIMGDisplayDevice = (((IMG_gralloc_module_public_t *)module)->getDisplayDevice((IMG_gralloc_module_public_t *)module)); 55 if (!mIMGDisplayDevice) { 56 ETRACE("failed to get display device"); 57 return false; 58 } 59 60 mCount = 0; 61 mInitialized = true; 62 return true; 63 } 64 65 bool TngDisplayContext::commitBegin(size_t numDisplays, hwc_display_contents_1_t **displays) 66 { 67 RETURN_FALSE_IF_NOT_INIT(); 68 mCount = 0; 69 return true; 70 } 71 72 bool TngDisplayContext::commitContents(hwc_display_contents_1_t *display, HwcLayerList *layerList) 73 { 74 bool ret; 75 76 RETURN_FALSE_IF_NOT_INIT(); 77 78 if (!display || !layerList) { 79 ETRACE("invalid parameters"); 80 return false; 81 } 82 83 IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers; 84 85 for (size_t i = 0; i < display->numHwLayers; i++) { 86 if (mCount >= MAXIMUM_LAYER_NUMBER) { 87 ETRACE("layer count exceeds the limit"); 88 return false; 89 } 90 91 // check layer parameters 92 if (!display->hwLayers[i].handle) { 93 continue; 94 } 95 96 DisplayPlane* plane = layerList->getPlane(i); 97 if (!plane) { 98 continue; 99 } 100 101 ret = plane->flip(NULL); 102 if (ret == false) { 103 VTRACE("failed to flip plane %d", i); 104 continue; 105 } 106 107 IMG_hwc_layer_t *imgLayer = &imgLayerList[mCount++]; 108 // update IMG layer 109 imgLayer->psLayer = &display->hwLayers[i]; 110 imgLayer->custom = (unsigned long)plane->getContext(); 111 struct intel_dc_plane_ctx *ctx = 112 (struct intel_dc_plane_ctx *)imgLayer->custom; 113 // update z order 114 Hwcomposer& hwc = Hwcomposer::getInstance(); 115 DisplayPlaneManager *pm = hwc.getPlaneManager(); 116 void *config = pm->getZOrderConfig(); 117 if (config) { 118 memcpy(&ctx->zorder, config, sizeof(ctx->zorder)); 119 } else { 120 memset(&ctx->zorder, 0, sizeof(ctx->zorder)); 121 } 122 123 VTRACE("count %p, handle %#x, trans %#x, blending %#x" 124 " sourceCrop %f,%f - %fx%f, dst %d,%d - %dx%d, custom %#x", 125 mCount, 126 imgLayer->psLayer->handle, 127 imgLayer->psLayer->transform, 128 imgLayer->psLayer->blending, 129 imgLayer->psLayer->sourceCropf.left, 130 imgLayer->psLayer->sourceCropf.top, 131 imgLayer->psLayer->sourceCropf.right - imgLayer->psLayer->sourceCropf.left, 132 imgLayer->psLayer->sourceCropf.bottom - imgLayer->psLayer->sourceCropf.top, 133 imgLayer->psLayer->displayFrame.left, 134 imgLayer->psLayer->displayFrame.top, 135 imgLayer->psLayer->displayFrame.right - imgLayer->psLayer->displayFrame.left, 136 imgLayer->psLayer->displayFrame.bottom - imgLayer->psLayer->displayFrame.top, 137 imgLayer->custom); 138 } 139 140 layerList->postFlip(); 141 return true; 142 } 143 144 bool TngDisplayContext::commitEnd(size_t numDisplays, hwc_display_contents_1_t **displays) 145 { 146 int releaseFenceFd = -1; 147 148 VTRACE("count = %d", mCount); 149 150 if (mIMGDisplayDevice && mCount) { 151 int err = mIMGDisplayDevice->post(mIMGDisplayDevice, 152 mImgLayers, 153 mCount, 154 &releaseFenceFd); 155 if (err) { 156 ETRACE("post failed, err = %d", err); 157 return false; 158 } 159 } 160 161 // close acquire fence 162 for (size_t i = 0; i < numDisplays; i++) { 163 // Wait and close HWC_OVERLAY typed layer's acquire fence 164 hwc_display_contents_1_t* display = displays[i]; 165 if (!display) { 166 continue; 167 } 168 169 for (size_t j = 0; j < display->numHwLayers-1; j++) { 170 hwc_layer_1_t& layer = display->hwLayers[j]; 171 if (layer.compositionType == HWC_OVERLAY) { 172 if (layer.acquireFenceFd != -1) { 173 // sync_wait(layer.acquireFenceFd, 16ms); 174 close(layer.acquireFenceFd); 175 layer.acquireFenceFd = -1; 176 } 177 } 178 } 179 180 // Wait and close framebuffer target layer's acquire fence 181 hwc_layer_1_t& fbt = display->hwLayers[display->numHwLayers-1]; 182 if (fbt.acquireFenceFd != -1) { 183 // sync_wait(fbt.acquireFencdFd, 16ms); 184 close(fbt.acquireFenceFd); 185 fbt.acquireFenceFd = -1; 186 } 187 188 // Wait and close outbuf's acquire fence 189 if (display->outbufAcquireFenceFd != -1) { 190 // sync_wait(display->outbufAcquireFenceFd, 16ms); 191 close(display->outbufAcquireFenceFd); 192 display->outbufAcquireFenceFd = -1; 193 } 194 } 195 196 // update release fence and retire fence 197 if (mCount > 0) { 198 // For physical displays, dup the releaseFenceFd only for 199 // HWC layers which successfully flipped to display planes 200 IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers; 201 202 for (unsigned int i = 0; i < mCount; i++) { 203 IMG_hwc_layer_t *imgLayer = &imgLayerList[i]; 204 imgLayer->psLayer->releaseFenceFd = 205 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1; 206 } 207 } 208 209 for (size_t i = 0; i < numDisplays; i++) { 210 if (!displays[i]) { 211 continue; 212 } 213 214 // log for layer fence status 215 for (size_t j = 0; j < displays[i]->numHwLayers; j++) { 216 VTRACE("handle %#p, acquiredFD %d, releaseFD %d", 217 displays[i]->hwLayers[j].handle, 218 displays[i]->hwLayers[j].acquireFenceFd, 219 displays[i]->hwLayers[j].releaseFenceFd); 220 } 221 222 #ifdef INTEL_WIDI_MERRIFIELD 223 // retireFence is used for SurfaceFlinger to do DispSync; 224 // dup releaseFenceFd for physical displays and ignore virtual 225 // display; we don't distinguish between release and retire, and all 226 // physical displays are using a single releaseFence; for virtual 227 // display, fencing is handled by the VirtualDisplay class 228 if (i < IDisplayDevice::DEVICE_VIRTUAL) { 229 #endif 230 displays[i]->retireFenceFd = 231 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1; 232 #ifdef INTEL_WIDI_MERRIFIELD 233 } 234 #endif 235 } 236 237 // close original release fence fd 238 if (releaseFenceFd != -1) { 239 close(releaseFenceFd); 240 } 241 return true; 242 } 243 244 bool TngDisplayContext::compositionComplete() 245 { 246 return true; 247 } 248 249 bool TngDisplayContext::setCursorPosition(int disp, int x, int y) 250 { 251 DTRACE("setCursorPosition"); 252 struct intel_dc_cursor_ctx ctx; 253 memset(&ctx, 0, sizeof(ctx)); 254 ctx.pipe = disp; 255 if (x < 0) { 256 ctx.pos |= 1 << 15; 257 x = -x; 258 } 259 if (y < 0) { 260 ctx.pos |= 1 << 31; 261 y = -y; 262 } 263 ctx.pos |= (y & 0xfff) << 16 | (x & 0xfff); 264 Drm *drm = Hwcomposer::getInstance().getDrm(); 265 return drm->writeIoctl(DRM_PSB_UPDATE_CURSOR_POS, &ctx, sizeof(ctx)); 266 } 267 268 void TngDisplayContext::deinitialize() 269 { 270 mIMGDisplayDevice = 0; 271 272 mCount = 0; 273 mInitialized = false; 274 } 275 276 277 } // namespace intel 278 } // namespace android 279