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