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 109 if (mScalingBufferMap.size() >= MAX_SCALING_BUF_COUNT) { 110 while (!mScalingBufferMap.isEmpty()) { 111 uint32_t handle = mScalingBufferMap.valueAt(0); 112 bm->freeGrallocBuffer(handle); 113 mScalingBufferMap.removeItemsAt(0); 114 } 115 } 116 117 mScalingBufferMap.add(handle, mScalingTarget); 118 } else { 119 mScalingTarget = mScalingBufferMap.valueAt(index); 120 } 121 mScalingSource = handle; 122 handle = mScalingTarget; 123 } 124 125 TngGrallocBuffer tmpBuf(handle); 126 uint32_t usage; 127 bool ret; 128 129 ALOGTRACE("handle = %#x", handle); 130 131 usage = tmpBuf.getUsage(); 132 if (GRALLOC_USAGE_HW_FB & usage) { 133 setFramebufferTarget(handle); 134 return true; 135 } 136 137 // use primary as a sprite 138 ret = DisplayPlane::setDataBuffer(handle); 139 if (ret == false) { 140 ELOGTRACE("failed to set data buffer"); 141 return ret; 142 } 143 144 return true; 145 } 146 147 bool AnnRGBPlane::setDataBuffer(BufferMapper& mapper) 148 { 149 int bpp; 150 int srcX, srcY, srcW, srcH; 151 int dstX, dstY, dstW, dstH; 152 uint32_t spriteFormat; 153 uint32_t stride; 154 uint32_t linoff; 155 uint32_t planeAlpha; 156 drmModeModeInfoPtr mode = &mModeInfo; 157 158 CTRACE(); 159 160 // setup plane position 161 dstX = mPosition.x; 162 dstY = mPosition.y; 163 dstW = mPosition.w; 164 dstH = mPosition.h; 165 166 checkPosition(dstX, dstY, dstW, dstH); 167 168 // setup plane format 169 if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) { 170 ELOGTRACE("unsupported format %#x", mapper.getFormat()); 171 return false; 172 } 173 174 // setup stride and source buffer crop 175 srcX = mapper.getCrop().x; 176 srcY = mapper.getCrop().y; 177 srcW = mapper.getWidth(); 178 srcH = mapper.getHeight(); 179 stride = mapper.getStride().rgb.stride; 180 181 if (mPanelOrientation == PANEL_ORIENTATION_180) 182 linoff = srcY * stride + srcX * bpp + (mapper.getCrop().h - 1) * stride + (mapper.getCrop().w - 1) * bpp; 183 else 184 linoff = srcY * stride + srcX * bpp; 185 186 // unlikely happen, but still we need make sure linoff is valid 187 if (linoff > (stride * mapper.getHeight())) { 188 ELOGTRACE("invalid source crop"); 189 return false; 190 } 191 192 // update context 193 if (mType == PLANE_SPRITE) 194 mContext.type = DC_SPRITE_PLANE; 195 else 196 mContext.type = DC_PRIMARY_PLANE; 197 198 // setup plane alpha 199 if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) { 200 planeAlpha = mPlaneAlpha | 0x80000000; 201 } else { 202 // disable plane alpha to offload HW 203 planeAlpha = 0xff; 204 } 205 206 mContext.ctx.sp_ctx.index = mIndex; 207 mContext.ctx.sp_ctx.pipe = mDevice; 208 mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000; 209 mContext.ctx.sp_ctx.linoff = linoff; 210 mContext.ctx.sp_ctx.stride = stride; 211 212 // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE 213 if (mBlending == HWC_BLENDING_COVERAGE) { 214 mContext.ctx.sp_ctx.cntr |= (0x1 << 23); 215 } 216 217 if (mPanelOrientation == PANEL_ORIENTATION_180) 218 mContext.ctx.sp_ctx.cntr |= (0x1 << 15); 219 220 if (mapper.isCompression()) { 221 mContext.ctx.sp_ctx.stride = align_to(srcW, 32) * 4; 222 mContext.ctx.sp_ctx.linoff = (align_to(srcW, 32) * srcH / 64) - 1; 223 mContext.ctx.sp_ctx.tileoff = (srcY & 0xfff) << 16 | (srcX & 0xfff); 224 mContext.ctx.sp_ctx.cntr |= (0x1 << 11); 225 } 226 227 mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12; 228 229 if (mPanelOrientation == PANEL_ORIENTATION_180) { 230 if (mode->vdisplay && mode->hdisplay) 231 mContext.ctx.sp_ctx.pos = ((mode->vdisplay - dstY - dstH) & 0xfff) << 16 | ((mode->hdisplay - dstX - dstW) & 0xfff); 232 else 233 mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff); 234 } else { 235 mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff); 236 } 237 238 mContext.ctx.sp_ctx.size = 239 ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff); 240 mContext.ctx.sp_ctx.contalpa = planeAlpha; 241 mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL; 242 243 VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x," 244 "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex, 245 mContext.ctx.sp_ctx.cntr, 246 mContext.ctx.sp_ctx.linoff, 247 mContext.ctx.sp_ctx.stride, 248 mContext.ctx.sp_ctx.surf, 249 mContext.ctx.sp_ctx.pos, 250 mContext.ctx.sp_ctx.size, 251 mContext.ctx.sp_ctx.contalpa); 252 return true; 253 } 254 255 bool AnnRGBPlane::enablePlane(bool enabled) 256 { 257 RETURN_FALSE_IF_NOT_INIT(); 258 259 struct drm_psb_register_rw_arg arg; 260 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 261 if (enabled) { 262 arg.plane_enable_mask = 1; 263 } else { 264 arg.plane_disable_mask = 1; 265 } 266 267 if (mType == PLANE_SPRITE) 268 arg.plane.type = DC_SPRITE_PLANE; 269 else 270 arg.plane.type = DC_PRIMARY_PLANE; 271 272 arg.plane.index = mIndex; 273 arg.plane.ctx = 0; 274 275 // issue ioctl 276 Drm *drm = Hwcomposer::getInstance().getDrm(); 277 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 278 if (ret == false) { 279 WLOGTRACE("plane enabling (%d) failed with error code %d", enabled, ret); 280 return false; 281 } 282 283 return true; 284 } 285 286 bool AnnRGBPlane::isDisabled() 287 { 288 RETURN_FALSE_IF_NOT_INIT(); 289 290 struct drm_psb_register_rw_arg arg; 291 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 292 293 if (mType == PLANE_SPRITE) 294 arg.plane.type = DC_SPRITE_PLANE; 295 else 296 arg.plane.type = DC_PRIMARY_PLANE; 297 298 arg.get_plane_state_mask = 1; 299 arg.plane.index = mIndex; 300 arg.plane.ctx = 0; 301 302 // issue ioctl 303 Drm *drm = Hwcomposer::getInstance().getDrm(); 304 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 305 if (ret == false) { 306 WLOGTRACE("plane state query failed with error code %d", ret); 307 return false; 308 } 309 310 return arg.plane.ctx == PSB_DC_PLANE_DISABLED; 311 } 312 313 void AnnRGBPlane::postFlip() 314 { 315 // prevent mUpdateMasks from being reset 316 // skipping flip may cause flicking 317 } 318 319 void AnnRGBPlane::setFramebufferTarget(uint32_t handle) 320 { 321 uint32_t stride; 322 uint32_t planeAlpha; 323 324 CTRACE(); 325 326 // do not need to update the buffer handle 327 if (mCurrentDataBuffer != handle) 328 mUpdateMasks |= PLANE_BUFFER_CHANGED; 329 else 330 mUpdateMasks &= ~PLANE_BUFFER_CHANGED; 331 332 // if no update then do Not need set data buffer 333 if (!mUpdateMasks) 334 return; 335 336 // don't need to map data buffer for primary plane 337 if (mType == PLANE_SPRITE) 338 mContext.type = DC_SPRITE_PLANE; 339 else 340 mContext.type = DC_PRIMARY_PLANE; 341 342 stride = align_to((4 * align_to(mPosition.w, 32)), 64); 343 344 if (0 < mPlaneAlpha && mPlaneAlpha < 0xff) { 345 planeAlpha = mPlaneAlpha | 0x80000000; 346 } else { 347 // disable plane alpha to offload HW 348 planeAlpha = 0xff; 349 } 350 351 // FIXME: use sprite context for sprite plane 352 mContext.ctx.prim_ctx.update_mask = SPRITE_UPDATE_ALL; 353 mContext.ctx.prim_ctx.index = mIndex; 354 mContext.ctx.prim_ctx.pipe = mDevice; 355 356 if (mPanelOrientation == PANEL_ORIENTATION_180) 357 mContext.ctx.prim_ctx.linoff = (mPosition.h - 1) * stride + (mPosition.w - 1) * 4; 358 else 359 mContext.ctx.prim_ctx.linoff = 0; 360 361 mContext.ctx.prim_ctx.stride = stride; 362 mContext.ctx.prim_ctx.tileoff = 0; 363 mContext.ctx.prim_ctx.pos = 0; 364 mContext.ctx.prim_ctx.size = 365 ((mPosition.h - 1) & 0xfff) << 16 | ((mPosition.w - 1) & 0xfff); 366 mContext.ctx.prim_ctx.surf = 0; 367 mContext.ctx.prim_ctx.contalpa = planeAlpha; 368 mContext.ctx.prim_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888; 369 mContext.ctx.prim_ctx.cntr |= 0x80000000; 370 371 // turn off premultipled alpha blending for HWC_BLENDING_COVERAGE 372 if (mBlending == HWC_BLENDING_COVERAGE) { 373 mContext.ctx.prim_ctx.cntr |= (0x1 << 23); 374 } 375 376 if (mPanelOrientation == PANEL_ORIENTATION_180) 377 mContext.ctx.prim_ctx.cntr |= (0x1 << 15); 378 379 VLOGTRACE("type = %d, index = %d, cntr = %#x, linoff = %#x, stride = %#x," 380 "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", mType, mIndex, 381 mContext.ctx.prim_ctx.cntr, 382 mContext.ctx.prim_ctx.linoff, 383 mContext.ctx.prim_ctx.stride, 384 mContext.ctx.prim_ctx.surf, 385 mContext.ctx.prim_ctx.pos, 386 mContext.ctx.prim_ctx.size, 387 mContext.ctx.sp_ctx.contalpa); 388 389 mCurrentDataBuffer = handle; 390 } 391 392 } // namespace intel 393 } // namespace android 394