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 <common/utils/HwcTrace.h> 18 #include <Hwcomposer.h> 19 #include <BufferManager.h> 20 #include <ips/anniedale/AnnCursorPlane.h> 21 #include <ips/tangier/TngGrallocBuffer.h> 22 #include <hal_public.h> 23 24 namespace android { 25 namespace intel { 26 27 AnnCursorPlane::AnnCursorPlane(int index, int disp) 28 : DisplayPlane(index, PLANE_CURSOR, disp) 29 { 30 CTRACE(); 31 memset(&mContext, 0, sizeof(mContext)); 32 memset(&mCrop, 0, sizeof(mCrop)); 33 } 34 35 AnnCursorPlane::~AnnCursorPlane() 36 { 37 CTRACE(); 38 } 39 40 bool AnnCursorPlane::enable() 41 { 42 return enablePlane(true); 43 } 44 45 bool AnnCursorPlane::disable() 46 { 47 return enablePlane(false); 48 } 49 50 bool AnnCursorPlane::reset() 51 { 52 // clear mCrop once reset 53 memset(&mCrop, 0, sizeof(mCrop)); 54 return true; 55 } 56 57 void* AnnCursorPlane::getContext() const 58 { 59 CTRACE(); 60 return (void *)&mContext; 61 } 62 63 void AnnCursorPlane::setZOrderConfig(ZOrderConfig& config, void *nativeConfig) 64 { 65 (void) config; 66 (void) nativeConfig; 67 68 CTRACE(); 69 } 70 71 bool AnnCursorPlane::setDataBuffer(uint32_t handle) 72 { 73 bool ret; 74 75 if (!handle) { 76 ELOGTRACE("handle is NULL"); 77 return false; 78 } 79 80 ret = DisplayPlane::setDataBuffer(handle); 81 if (ret == false) { 82 ELOGTRACE("failed to set data buffer"); 83 return ret; 84 } 85 86 return true; 87 } 88 89 bool AnnCursorPlane::setDataBuffer(BufferMapper& mapper) 90 { 91 int w = mapper.getWidth(); 92 int h = mapper.getHeight(); 93 int cursorSize = 0; 94 95 CTRACE(); 96 97 // setup plane position 98 int dstX = mPosition.x; 99 int dstY = mPosition.y; 100 101 if (h < w) { 102 cursorSize = h; 103 } else { 104 cursorSize = w; 105 } 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 ELOGTRACE("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 if (!p) { 150 return false; 151 } 152 153 if (mCrop.w == 0 && mCrop.h == 0) { 154 mCrop = mSrcCrop; 155 for (int i = 0; i < cursorSize; i++) { 156 for (int j = 0; j < cursorSize; j++) { 157 srcPixel = p + i*stride + j*4; 158 if (i >= mCrop.h || j >= mCrop.w) { 159 if (srcPixel[0] == 0 && 160 srcPixel[3] == 0xff) 161 srcPixel[3] = 0; 162 } 163 } 164 } 165 } 166 167 // update context 168 mContext.type = DC_CURSOR_PLANE; 169 mContext.ctx.cs_ctx.index = mIndex; 170 mContext.ctx.cs_ctx.pipe = mDevice; 171 mContext.ctx.cs_ctx.cntr = cntr; 172 mContext.ctx.cs_ctx.surf = mapper.getGttOffsetInPage(0) << 12; 173 174 mContext.ctx.cs_ctx.pos = 0; 175 if (dstX < 0) { 176 mContext.ctx.cs_ctx.pos |= 1 << 15; 177 dstX = -dstX; 178 } 179 if (dstY < 0) { 180 mContext.ctx.cs_ctx.pos |= 1 << 31; 181 dstY = -dstY; 182 } 183 mContext.ctx.cs_ctx.pos |= (dstY & 0xfff) << 16 | (dstX & 0xfff); 184 return true; 185 } 186 187 bool AnnCursorPlane::enablePlane(bool enabled) 188 { 189 RETURN_FALSE_IF_NOT_INIT(); 190 191 struct drm_psb_register_rw_arg arg; 192 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 193 if (enabled) { 194 arg.plane_enable_mask = 1; 195 } else { 196 arg.plane_disable_mask = 1; 197 } 198 199 arg.plane.type = DC_CURSOR_PLANE; 200 arg.plane.index = mIndex; 201 arg.plane.ctx = 0; 202 203 // issue ioctl 204 Drm *drm = Hwcomposer::getInstance().getDrm(); 205 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 206 if (ret == false) { 207 WLOGTRACE("plane enabling (%d) failed with error code %d", enabled, ret); 208 return false; 209 } 210 211 return true; 212 } 213 214 bool AnnCursorPlane::isDisabled() 215 { 216 RETURN_FALSE_IF_NOT_INIT(); 217 218 struct drm_psb_register_rw_arg arg; 219 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 220 221 arg.plane.type = DC_CURSOR_PLANE; 222 arg.get_plane_state_mask = 1; 223 arg.plane.index = mIndex; 224 arg.plane.ctx = 0; 225 226 // issue ioctl 227 Drm *drm = Hwcomposer::getInstance().getDrm(); 228 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 229 if (ret == false) { 230 WLOGTRACE("plane state query failed with error code %d", ret); 231 return false; 232 } 233 234 return arg.plane.ctx == PSB_DC_PLANE_DISABLED; 235 } 236 237 void AnnCursorPlane::postFlip() 238 { 239 // prevent mUpdateMasks from being reset 240 // skipping flip may cause flicking 241 } 242 243 } // namespace intel 244 } // namespace android 245