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 namespace android { 25 namespace intel { 26 27 TngDisplayContext::TngDisplayContext() 28 : mIMGDisplayDevice(0), 29 mInitialized(false), 30 mCount(0) 31 { 32 CTRACE(); 33 } 34 35 TngDisplayContext::~TngDisplayContext() 36 { 37 WARN_IF_NOT_DEINIT(); 38 } 39 40 bool TngDisplayContext::initialize() 41 { 42 CTRACE(); 43 44 // open frame buffer device 45 gralloc_module_t const* module; 46 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (hw_module_t const**)&module); 47 if (err) { 48 ELOGTRACE("failed to load gralloc module, error = %d", err); 49 return false; 50 } 51 52 // init IMG display device 53 err = module->perform(module, GRALLOC_MODULE_GET_DISPLAY_DEVICE_IMG, (void **)&mIMGDisplayDevice); 54 if (err) { 55 ELOGTRACE("failed to get display device, error = %d", err); 56 return false; 57 } 58 59 mCount = 0; 60 mInitialized = true; 61 return true; 62 } 63 64 bool TngDisplayContext::commitBegin(size_t /* numDisplays */, 65 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 ELOGTRACE("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 ELOGTRACE("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 VLOGTRACE("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 = (uint32_t)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 VLOGTRACE("count %d, handle %#x, trans %#x, blending %#x" 124 " sourceCrop %f,%f - %fx%f, dst %d,%d - %dx%d, custom %#x", 125 mCount, 126 (uint32_t)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 VLOGTRACE("count = %d", mCount); 149 150 if (mIMGDisplayDevice && mCount) { 151 int err = mIMGDisplayDevice->post(mIMGDisplayDevice, 152 mImgLayers, 153 mCount, 154 &releaseFenceFd); 155 if (err) { 156 ELOGTRACE("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 (size_t 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 VLOGTRACE("handle %#x, acquiredFD %d, releaseFD %d", 217 (uint32_t)displays[i]->hwLayers[j].handle, 218 displays[i]->hwLayers[j].acquireFenceFd, 219 displays[i]->hwLayers[j].releaseFenceFd); 220 } 221 222 // retireFence is used for SurfaceFlinger to do DispSync; 223 // dup releaseFenceFd for physical displays and ignore virtual 224 // display; we don't distinguish between release and retire, and all 225 // physical displays are using a single releaseFence; for virtual 226 // display, fencing is handled by the VirtualDisplay class 227 if (i < IDisplayDevice::DEVICE_VIRTUAL) { 228 displays[i]->retireFenceFd = 229 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1; 230 } 231 } 232 233 // close original release fence fd 234 if (releaseFenceFd != -1) { 235 close(releaseFenceFd); 236 } 237 return true; 238 } 239 240 bool TngDisplayContext::compositionComplete() 241 { 242 return true; 243 } 244 245 bool TngDisplayContext::setCursorPosition(int disp, int x, int y) 246 { 247 DLOGTRACE("setCursorPosition"); 248 struct intel_dc_cursor_ctx ctx; 249 memset(&ctx, 0, sizeof(ctx)); 250 ctx.pipe = disp; 251 if (x < 0) { 252 ctx.pos |= 1 << 15; 253 x = -x; 254 } 255 if (y < 0) { 256 ctx.pos |= 1 << 31; 257 y = -y; 258 } 259 ctx.pos |= (y & 0xfff) << 16 | (x & 0xfff); 260 Drm *drm = Hwcomposer::getInstance().getDrm(); 261 return drm->writeIoctl(DRM_PSB_UPDATE_CURSOR_POS, &ctx, sizeof(ctx)); 262 } 263 264 265 void TngDisplayContext::deinitialize() 266 { 267 mIMGDisplayDevice = 0; 268 269 mCount = 0; 270 mInitialized = false; 271 } 272 273 274 } // namespace intel 275 } // namespace android 276