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 17 #include <HwcTrace.h> 18 #include <Hwcomposer.h> 19 #include <BufferManager.h> 20 #include <BufferManager.h> 21 #include <tangier/TngCursorPlane.h> 22 #include <tangier/TngGrallocBuffer.h> 23 #include <hal_public.h> 24 25 namespace android { 26 namespace intel { 27 28 TngCursorPlane::TngCursorPlane(int index, int disp) 29 : DisplayPlane(index, PLANE_CURSOR, disp) 30 { 31 CTRACE(); 32 memset(&mContext, 0, sizeof(mContext)); 33 memset(&mCrop, 0, sizeof(mCrop)); 34 } 35 36 TngCursorPlane::~TngCursorPlane() 37 { 38 CTRACE(); 39 } 40 41 bool TngCursorPlane::enable() 42 { 43 return enablePlane(true); 44 } 45 46 bool TngCursorPlane::disable() 47 { 48 return enablePlane(false); 49 } 50 51 void* TngCursorPlane::getContext() const 52 { 53 CTRACE(); 54 return (void *)&mContext; 55 } 56 57 void TngCursorPlane::setZOrderConfig(ZOrderConfig& config, void *nativeConfig) 58 { 59 (void) config; 60 (void) nativeConfig; 61 62 VTRACE("\n *** need to implement zorder config *** "); 63 CTRACE(); 64 } 65 66 bool TngCursorPlane::setDataBuffer(buffer_handle_t handle) 67 { 68 bool ret; 69 70 if (!handle) { 71 ETRACE("handle is NULL"); 72 return false; 73 } 74 75 ret = DisplayPlane::setDataBuffer(handle); 76 if (ret == false) { 77 ETRACE("failed to set data buffer"); 78 return ret; 79 } 80 81 return true; 82 } 83 84 bool TngCursorPlane::setDataBuffer(BufferMapper& mapper) 85 { 86 int w = mapper.getWidth(); 87 int h = mapper.getHeight(); 88 int cursorSize = 0; 89 90 CTRACE(); 91 92 // setup plane position 93 int dstX = mPosition.x; 94 int dstY = mPosition.y; 95 96 if (h < w) { 97 cursorSize = h; 98 } else { 99 cursorSize = w; 100 } 101 102 #if ENABLE_ROTATION_180 103 dstX = mModeInfo.hdisplay - dstX - cursorSize; 104 dstY = mModeInfo.vdisplay - dstY - cursorSize; 105 #endif 106 107 uint32_t cntr = 0; 108 if (64 <= cursorSize && cursorSize < 128) { 109 cursorSize = 64; 110 cntr = 0x7; 111 } else if (128 <= cursorSize && cursorSize < 256) { 112 cursorSize = 128; 113 cntr = 0x2; 114 } else { 115 cursorSize = 256; 116 cntr = 0x3; 117 } 118 119 if (mapper.getFormat() == HAL_PIXEL_FORMAT_RGBA_8888) { 120 cntr |= 1 << 5; 121 } else if (mapper.getFormat() == HAL_PIXEL_FORMAT_BGRA_8888) { 122 // swap color from BGRA to RGBA - alpha is MSB 123 uint8_t *p = (uint8_t *)(mapper.getCpuAddress(0)); 124 uint8_t *srcPixel; 125 uint32_t stride = mapper.getStride().rgb.stride; 126 uint8_t temp; 127 if (!p) { 128 return false; 129 } 130 131 for (int i = 0; i < cursorSize; i++) { 132 for (int j = 0; j < cursorSize; j++) { 133 srcPixel = p + i*stride + j*4; 134 temp = srcPixel[0]; 135 srcPixel[0] = srcPixel[2]; 136 srcPixel[2] = temp; 137 } 138 } 139 cntr |= 1 << 5; 140 } else { 141 ETRACE("invalid color format"); 142 return false; 143 } 144 145 // TODO: clean spare mem to be 0 in gralloc instead 146 uint8_t *p = (uint8_t *)(mapper.getCpuAddress(0)); 147 uint8_t *srcPixel; 148 uint32_t stride = mapper.getStride().rgb.stride; 149 uint8_t temp; 150 if (!p) { 151 return false; 152 } 153 154 if (mCrop.w == 0 && mCrop.h == 0) { 155 mCrop = mSrcCrop; 156 for (int i = 0; i < cursorSize; i++) { 157 for (int j = 0; j < cursorSize; j++) { 158 srcPixel = p + i*stride + j*4; 159 temp = srcPixel[0]; 160 if (i >= mCrop.h || j >= mCrop.w) { 161 if (srcPixel[0] == 0 && 162 srcPixel[3] == 0xff) 163 srcPixel[3] = 0; 164 } 165 } 166 } 167 } 168 169 // update context 170 mContext.type = DC_CURSOR_PLANE; 171 mContext.ctx.cs_ctx.index = mIndex; 172 mContext.ctx.cs_ctx.pipe = mDevice; 173 mContext.ctx.cs_ctx.cntr = cntr | (mIndex << 28); 174 mContext.ctx.cs_ctx.surf = mapper.getGttOffsetInPage(0) << 12; 175 176 mContext.ctx.cs_ctx.pos = 0; 177 if (dstX < 0) { 178 mContext.ctx.cs_ctx.pos |= 1 << 15; 179 dstX = -dstX; 180 } 181 if (dstY < 0) { 182 mContext.ctx.cs_ctx.pos |= 1 << 31; 183 dstY = -dstY; 184 } 185 mContext.ctx.cs_ctx.pos |= (dstY & 0xfff) << 16 | (dstX & 0xfff); 186 return true; 187 } 188 189 bool TngCursorPlane::enablePlane(bool enabled) 190 { 191 RETURN_FALSE_IF_NOT_INIT(); 192 193 struct drm_psb_register_rw_arg arg; 194 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 195 if (enabled) { 196 arg.plane_enable_mask = 1; 197 } else { 198 arg.plane_disable_mask = 1; 199 } 200 201 arg.plane.type = DC_CURSOR_PLANE; 202 arg.plane.index = mIndex; 203 arg.plane.ctx = 0; 204 205 // issue ioctl 206 Drm *drm = Hwcomposer::getInstance().getDrm(); 207 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 208 if (ret == false) { 209 WTRACE("plane enabling (%d) failed with error code %d", enabled, ret); 210 return false; 211 } 212 213 return true; 214 } 215 216 bool TngCursorPlane::isDisabled() 217 { 218 RETURN_FALSE_IF_NOT_INIT(); 219 220 struct drm_psb_register_rw_arg arg; 221 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 222 223 arg.plane.type = DC_CURSOR_PLANE; 224 arg.get_plane_state_mask = 1; 225 arg.plane.index = mIndex; 226 arg.plane.ctx = 0; 227 228 // issue ioctl 229 Drm *drm = Hwcomposer::getInstance().getDrm(); 230 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 231 if (ret == false) { 232 WTRACE("plane state query failed with error code %d", ret); 233 return false; 234 } 235 236 return arg.plane.ctx == PSB_DC_PLANE_DISABLED; 237 //return arg.plane.ctx == 0; //implement this PSB_DC_PLANE_DISABLED similar in imin_legacy 238 239 return true; 240 } 241 242 void TngCursorPlane::postFlip() 243 { 244 // prevent mUpdateMasks from being reset 245 // skipping flip may cause flicking 246 } 247 248 } // namespace intel 249 } // namespace android 250