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 <common/utils/HwcTrace.h> 17 #include <common/base/Drm.h> 18 #include <Hwcomposer.h> 19 #include <DisplayPlane.h> 20 #include <IDisplayDevice.h> 21 #include <common/base/HwcLayerList.h> 22 #include <ips/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 ELOGTRACE("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 ELOGTRACE("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 */, 66 hwc_display_contents_1_t ** /* displays */) 67 { 68 RETURN_FALSE_IF_NOT_INIT(); 69 mCount = 0; 70 return true; 71 } 72 73 bool TngDisplayContext::commitContents(hwc_display_contents_1_t *display, HwcLayerList *layerList) 74 { 75 bool ret; 76 77 RETURN_FALSE_IF_NOT_INIT(); 78 79 if (!display || !layerList) { 80 ELOGTRACE("invalid parameters"); 81 return false; 82 } 83 84 IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers; 85 86 for (size_t i = 0; i < display->numHwLayers; i++) { 87 if (mCount >= MAXIMUM_LAYER_NUMBER) { 88 ELOGTRACE("layer count exceeds the limit"); 89 return false; 90 } 91 92 // check layer parameters 93 if (!display->hwLayers[i].handle) { 94 continue; 95 } 96 97 DisplayPlane* plane = layerList->getPlane(i); 98 if (!plane) { 99 continue; 100 } 101 102 ret = plane->flip(NULL); 103 if (ret == false) { 104 VLOGTRACE("failed to flip plane %d", i); 105 continue; 106 } 107 108 IMG_hwc_layer_t *imgLayer = &imgLayerList[mCount++]; 109 // update IMG layer 110 imgLayer->psLayer = &display->hwLayers[i]; 111 imgLayer->custom = (uint32_t)plane->getContext(); 112 struct intel_dc_plane_ctx *ctx = 113 (struct intel_dc_plane_ctx *)imgLayer->custom; 114 // update z order 115 Hwcomposer& hwc = Hwcomposer::getInstance(); 116 DisplayPlaneManager *pm = hwc.getPlaneManager(); 117 void *config = pm->getZOrderConfig(); 118 if (config) { 119 memcpy(&ctx->zorder, config, sizeof(ctx->zorder)); 120 } else { 121 memset(&ctx->zorder, 0, sizeof(ctx->zorder)); 122 } 123 124 VLOGTRACE("count %d, handle %#x, trans %#x, blending %#x" 125 " sourceCrop %f,%f - %fx%f, dst %d,%d - %dx%d, custom %#x", 126 mCount, 127 (uint32_t)imgLayer->psLayer->handle, 128 imgLayer->psLayer->transform, 129 imgLayer->psLayer->blending, 130 imgLayer->psLayer->sourceCropf.left, 131 imgLayer->psLayer->sourceCropf.top, 132 imgLayer->psLayer->sourceCropf.right - imgLayer->psLayer->sourceCropf.left, 133 imgLayer->psLayer->sourceCropf.bottom - imgLayer->psLayer->sourceCropf.top, 134 imgLayer->psLayer->displayFrame.left, 135 imgLayer->psLayer->displayFrame.top, 136 imgLayer->psLayer->displayFrame.right - imgLayer->psLayer->displayFrame.left, 137 imgLayer->psLayer->displayFrame.bottom - imgLayer->psLayer->displayFrame.top, 138 imgLayer->custom); 139 } 140 141 layerList->postFlip(); 142 return true; 143 } 144 145 bool TngDisplayContext::commitEnd(size_t numDisplays, hwc_display_contents_1_t **displays) 146 { 147 int releaseFenceFd = -1; 148 149 VLOGTRACE("count = %d", mCount); 150 151 if (mIMGDisplayDevice && mCount) { 152 int err = mIMGDisplayDevice->post(mIMGDisplayDevice, 153 mImgLayers, 154 mCount, 155 &releaseFenceFd); 156 if (err) { 157 ELOGTRACE("post failed, err = %d", err); 158 return false; 159 } 160 } 161 162 // close acquire fence 163 for (size_t i = 0; i < numDisplays; i++) { 164 // Wait and close HWC_OVERLAY typed layer's acquire fence 165 hwc_display_contents_1_t* display = displays[i]; 166 if (!display) { 167 continue; 168 } 169 170 for (size_t j = 0; j < display->numHwLayers-1; j++) { 171 hwc_layer_1_t& layer = display->hwLayers[j]; 172 if (layer.compositionType == HWC_OVERLAY) { 173 if (layer.acquireFenceFd != -1) { 174 // sync_wait(layer.acquireFenceFd, 16ms); 175 close(layer.acquireFenceFd); 176 layer.acquireFenceFd = -1; 177 } 178 } 179 } 180 181 // Wait and close framebuffer target layer's acquire fence 182 hwc_layer_1_t& fbt = display->hwLayers[display->numHwLayers-1]; 183 if (fbt.acquireFenceFd != -1) { 184 // sync_wait(fbt.acquireFencdFd, 16ms); 185 close(fbt.acquireFenceFd); 186 fbt.acquireFenceFd = -1; 187 } 188 189 // Wait and close outbuf's acquire fence 190 if (display->outbufAcquireFenceFd != -1) { 191 // sync_wait(display->outbufAcquireFenceFd, 16ms); 192 close(display->outbufAcquireFenceFd); 193 display->outbufAcquireFenceFd = -1; 194 } 195 } 196 197 // update release fence and retire fence 198 if (mCount > 0) { 199 // For physical displays, dup the releaseFenceFd only for 200 // HWC layers which successfully flipped to display planes 201 IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers; 202 203 for (size_t i = 0; i < mCount; i++) { 204 IMG_hwc_layer_t *imgLayer = &imgLayerList[i]; 205 imgLayer->psLayer->releaseFenceFd = 206 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1; 207 } 208 } 209 210 for (size_t i = 0; i < numDisplays; i++) { 211 if (!displays[i]) { 212 continue; 213 } 214 215 // log for layer fence status 216 for (size_t j = 0; j < displays[i]->numHwLayers; j++) { 217 VLOGTRACE("handle %#x, acquiredFD %d, releaseFD %d", 218 (uint32_t)displays[i]->hwLayers[j].handle, 219 displays[i]->hwLayers[j].acquireFenceFd, 220 displays[i]->hwLayers[j].releaseFenceFd); 221 } 222 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 displays[i]->retireFenceFd = 230 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1; 231 } 232 } 233 234 // close original release fence fd 235 if (releaseFenceFd != -1) { 236 close(releaseFenceFd); 237 } 238 return true; 239 } 240 241 bool TngDisplayContext::compositionComplete() 242 { 243 return true; 244 } 245 246 bool TngDisplayContext::setCursorPosition(int disp, int x, int y) 247 { 248 DLOGTRACE("setCursorPosition"); 249 struct intel_dc_cursor_ctx ctx; 250 memset(&ctx, 0, sizeof(ctx)); 251 ctx.pipe = disp; 252 if (x < 0) { 253 ctx.pos |= 1 << 15; 254 x = -x; 255 } 256 if (y < 0) { 257 ctx.pos |= 1 << 31; 258 y = -y; 259 } 260 ctx.pos |= (y & 0xfff) << 16 | (x & 0xfff); 261 Drm *drm = Hwcomposer::getInstance().getDrm(); 262 return drm->writeIoctl(DRM_PSB_UPDATE_CURSOR_POS, &ctx, sizeof(ctx)); 263 } 264 265 266 void TngDisplayContext::deinitialize() 267 { 268 mIMGDisplayDevice = 0; 269 270 mCount = 0; 271 mInitialized = false; 272 } 273 274 275 } // namespace intel 276 } // namespace android 277