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 <Hwcomposer.h> 18 #include <BufferManager.h> 19 #include <ips/anniedale/AnnRGBPlane.h> 20 #include <ips/tangier/TngGrallocBuffer.h> 21 #include <ips/common/PixelFormat.h> 22 23 namespace android { 24 namespace intel { 25 26 AnnRGBPlane::AnnRGBPlane(int index, int type, int disp) 27 : DisplayPlane(index, type, disp) 28 { 29 CTRACE(); 30 memset(&mContext, 0, sizeof(mContext)); 31 } 32 33 AnnRGBPlane::~AnnRGBPlane() 34 { 35 CTRACE(); 36 } 37 38 bool AnnRGBPlane::enable() 39 { 40 return enablePlane(true); 41 } 42 43 bool AnnRGBPlane::disable() 44 { 45 return enablePlane(false); 46 } 47 48 bool AnnRGBPlane::reset() 49 { 50 while (!mScalingBufferMap.isEmpty()) { 51 uint32_t handle = mScalingBufferMap.valueAt(0); 52 Hwcomposer::getInstance().getBufferManager()->freeGrallocBuffer(handle); 53 mScalingBufferMap.removeItemsAt(0); 54 } 55 56 return DisplayPlane::reset(); 57 } 58 59 bool AnnRGBPlane::flip(void*) 60 { 61 if (mForceScaling) { 62 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 63 if (!bm->blitGrallocBuffer(mScalingSource, mScalingTarget, mDisplayCrop, 0)) { 64 ELOGTRACE("Failed to blit RGB buffer."); 65 return false; 66 } 67 } 68 69 return true; 70 } 71 72 void* AnnRGBPlane::getContext() const 73 { 74 CTRACE(); 75 return (void *)&mContext; 76 } 77 78 void AnnRGBPlane::setZOrderConfig(ZOrderConfig& /* config */, void * /* nativeConfig */) 79 { 80 CTRACE(); 81 } 82 83 bool AnnRGBPlane::setDataBuffer(uint32_t handle) 84 { 85 if (!handle) { 86 if (!mForceScaling) { 87 setFramebufferTarget(handle); 88 return true; 89 } else { 90 ELOGTRACE("Invalid handle while scaling is required."); 91 return false; 92 } 93 } 94 95 if (mForceScaling) { 96 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 97 ssize_t index = mScalingBufferMap.indexOfKey(handle); 98 if (index < 0) { 99 mScalingTarget = bm->allocGrallocBuffer( 100 mDisplayWidth, 101 mDisplayHeight, 102 HAL_PIXEL_FORMAT_RGBA_8888, 103 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE); 104 if (!mScalingTarget) { 105 ELOGTRACE("Failed to allocate gralloc buffer."); 106 return false; 107 } 108 mScalingBufferMap.add(handle, mScalingTarget); 109 } else { 110 mScalingTarget = mScalingBufferMap.valueAt(index); 111 } 112 mScalingSource = handle; 113 handle = mScalingTarget; 114 } 115 116 TngGrallocBuffer tmpBuf(handle); 117 uint32_t usage; 118 bool ret; 119 120 ALOGTRACE("handle = %#x", handle); 121 122 usage = tmpBuf.getUsage(); 123 if (GRALLOC_USAGE_HW_FB & usage) { 124 setFramebufferTarget(handle); 125 return true; 126 } 127 128 // use primary as a sprite 129 ret = DisplayPlane::setDataBuffer(handle); 130 if (ret == false) { 131 ELOGTRACE("failed to set data buffer"); 132 return ret; 133 } 134 135 return true; 136 } 137 138 bool AnnRGBPlane::setDataBuffer(BufferMapper& mapper) 139 { 140 int bpp; 141 int srcX, srcY, srcW, srcH; 142 int dstX, dstY, dstW, dstH; 143 uint32_t spriteFormat; 144 uint32_t stride; 145 uint32_t linoff; 146 uint32_t planeAlpha; 147 drmModeModeInfoPtr mode = &mModeInfo; 148 149 CTRACE(); 150 151 // setup plane position 152 dstX = mPosition.x; 153 dstY = mPosition.y; 154 dstW = mPosition.w; 155 dstH = mPosition.h; 156 157 checkPosition(dstX, dstY, dstW, dstH); 158 159 // setup plane format 160 if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) { 161 ELOGTRACE("unsupported format %#x", mapper.getFormat()); 162 return false; 163 } 164 165 // setup stride and source buffer crop 166 srcX = mapper.getCrop().x; 167 srcY = mapper.getCrop().y; 168 srcW = mapper.getWidth(); 169 srcH = mapper.getHeight(); 170 stride = mapper.getStride().rgb.stride; 171 172 if (mPanelOrientation == PANEL_ORIENTATION_180) 173 linoff = srcY * stride + srcX * bpp + (mapper.getCrop().h - 1) * stride + (mapper.getCrop().w - 1) * bpp; 174 else 175 linoff = srcY * stride + srcX * bpp; 176 177 // unlikely happen, but still we need make sure linoff is valid 178 if (linoff > (stride * mapper.getHeight())) { 179 ELOGTRACE("invalid source crop"); 180 return false; 181 } 182 183 // update context 184 if (mType == PLANE_SPRITE) 185 mContext.type = DC_SPRITE_PLANE; 186 else 187 mContext.type = DC_PRIMARY_PLANE; 188 189 // setup plane alpha 190 if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) { 191 planeAlpha = mPlaneAlpha | 0x80000000; 192 } else { 193 // disable plane alpha to offload HW 194 planeAlpha = 0xff; 195 } 196 197 mContext.ctx.sp_ctx.index = mIndex; 198 mContext.ctx.sp_ctx.pipe = mDevice; 199 mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000; 200 mContext.ctx.sp_ctx.linoff = linoff; 201 mContext.ctx.sp_ctx.stride = stride; 202 203 // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE 204 if (mBlending == HWC_BLENDING_COVERAGE) { 205 mContext.ctx.sp_ctx.cntr |= (0x1 << 23); 206 } 207 208 if (mPanelOrientation == PANEL_ORIENTATION_180) 209 mContext.ctx.sp_ctx.cntr |= (0x1 << 15); 210 211 if (mapper.isCompression()) { 212 mContext.ctx.sp_ctx.stride = align_to(srcW, 32) * 4; 213 mContext.ctx.sp_ctx.linoff = (align_to(srcW, 32) * srcH / 64) - 1; 214 mContext.ctx.sp_ctx.tileoff = (srcY & 0xfff) << 16 | (srcX & 0xfff); 215 mContext.ctx.sp_ctx.cntr |= (0x1 << 11); 216 } 217 218 mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12; 219 220 if (mPanelOrientation == PANEL_ORIENTATION_180) { 221 if (mode->vdisplay && mode->hdisplay) 222 mContext.ctx.sp_ctx.pos = ((mode->vdisplay - dstY - dstH) & 0xfff) << 16 | ((mode->hdisplay - dstX - dstW) & 0xfff); 223 else 224 mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff); 225 } else { 226 mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff); 227 } 228 229 mContext.ctx.sp_ctx.size = 230 ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff); 231 mContext.ctx.sp_ctx.contalpa = planeAlpha; 232 mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL; 233 234 VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x," 235 "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex, 236 mContext.ctx.sp_ctx.cntr, 237 mContext.ctx.sp_ctx.linoff, 238 mContext.ctx.sp_ctx.stride, 239 mContext.ctx.sp_ctx.surf, 240 mContext.ctx.sp_ctx.pos, 241 mContext.ctx.sp_ctx.size, 242 mContext.ctx.sp_ctx.contalpa); 243 return true; 244 } 245 246 bool AnnRGBPlane::enablePlane(bool enabled) 247 { 248 RETURN_FALSE_IF_NOT_INIT(); 249 250 struct drm_psb_register_rw_arg arg; 251 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 252 if (enabled) { 253 arg.plane_enable_mask = 1; 254 } else { 255 arg.plane_disable_mask = 1; 256 } 257 258 if (mType == PLANE_SPRITE) 259 arg.plane.type = DC_SPRITE_PLANE; 260 else 261 arg.plane.type = DC_PRIMARY_PLANE; 262 263 arg.plane.index = mIndex; 264 arg.plane.ctx = 0; 265 266 // issue ioctl 267 Drm *drm = Hwcomposer::getInstance().getDrm(); 268 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 269 if (ret == false) { 270 WLOGTRACE("plane enabling (%d) failed with error code %d", enabled, ret); 271 return false; 272 } 273 274 return true; 275 } 276 277 bool AnnRGBPlane::isDisabled() 278 { 279 RETURN_FALSE_IF_NOT_INIT(); 280 281 struct drm_psb_register_rw_arg arg; 282 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 283 284 if (mType == PLANE_SPRITE) 285 arg.plane.type = DC_SPRITE_PLANE; 286 else 287 arg.plane.type = DC_PRIMARY_PLANE; 288 289 arg.get_plane_state_mask = 1; 290 arg.plane.index = mIndex; 291 arg.plane.ctx = 0; 292 293 // issue ioctl 294 Drm *drm = Hwcomposer::getInstance().getDrm(); 295 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 296 if (ret == false) { 297 WLOGTRACE("plane state query failed with error code %d", ret); 298 return false; 299 } 300 301 return arg.plane.ctx == PSB_DC_PLANE_DISABLED; 302 } 303 304 void AnnRGBPlane::postFlip() 305 { 306 // prevent mUpdateMasks from being reset 307 // skipping flip may cause flicking 308 } 309 310 void AnnRGBPlane::setFramebufferTarget(uint32_t handle) 311 { 312 uint32_t stride; 313 uint32_t planeAlpha; 314 315 CTRACE(); 316 317 // do not need to update the buffer handle 318 if (mCurrentDataBuffer != handle) 319 mUpdateMasks |= PLANE_BUFFER_CHANGED; 320 else 321 mUpdateMasks &= ~PLANE_BUFFER_CHANGED; 322 323 // if no update then do Not need set data buffer 324 if (!mUpdateMasks) 325 return; 326 327 // don't need to map data buffer for primary plane 328 if (mType == PLANE_SPRITE) 329 mContext.type = DC_SPRITE_PLANE; 330 else 331 mContext.type = DC_PRIMARY_PLANE; 332 333 stride = align_to((4 * align_to(mPosition.w, 32)), 64); 334 335 if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) { 336 planeAlpha = mPlaneAlpha | 0x80000000; 337 } else { 338 // disable plane alpha to offload HW 339 planeAlpha = 0xff; 340 } 341 342 // FIXME: use sprite context for sprite plane 343 mContext.ctx.prim_ctx.update_mask = SPRITE_UPDATE_ALL; 344 mContext.ctx.prim_ctx.index = mIndex; 345 mContext.ctx.prim_ctx.pipe = mDevice; 346 347 if (mPanelOrientation == PANEL_ORIENTATION_180) 348 mContext.ctx.prim_ctx.linoff = (mPosition.h - 1) * stride + (mPosition.w - 1) * 4; 349 else 350 mContext.ctx.prim_ctx.linoff = 0; 351 352 mContext.ctx.prim_ctx.stride = stride; 353 mContext.ctx.prim_ctx.tileoff = 0; 354 mContext.ctx.prim_ctx.pos = 0; 355 mContext.ctx.prim_ctx.size = 356 ((mPosition.h - 1) & 0xfff) << 16 | ((mPosition.w - 1) & 0xfff); 357 mContext.ctx.prim_ctx.surf = 0; 358 mContext.ctx.prim_ctx.contalpa = planeAlpha; 359 mContext.ctx.prim_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888; 360 mContext.ctx.prim_ctx.cntr |= 0x80000000; 361 362 // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE 363 if (mBlending == HWC_BLENDING_COVERAGE) { 364 mContext.ctx.prim_ctx.cntr |= (0x1 << 23); 365 } 366 367 if (mPanelOrientation == PANEL_ORIENTATION_180) 368 mContext.ctx.prim_ctx.cntr |= (0x1 << 15); 369 370 VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x," 371 "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex, 372 mContext.ctx.prim_ctx.cntr, 373 mContext.ctx.prim_ctx.linoff, 374 mContext.ctx.prim_ctx.stride, 375 mContext.ctx.prim_ctx.surf, 376 mContext.ctx.prim_ctx.pos, 377 mContext.ctx.prim_ctx.size, 378 mContext.ctx.sp_ctx.contalpa); 379 380 mCurrentDataBuffer = handle; 381 } 382 383 } // namespace intel 384 } // namespace android 385