1/* 2// Copyright (c) 2014 Intel Corporation 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15*/ 16 17#include <HwcTrace.h> 18#include <Hwcomposer.h> 19#include <BufferManager.h> 20#include <anniedale/AnnCursorPlane.h> 21#include <tangier/TngGrallocBuffer.h> 22#include <hal_public.h> 23 24namespace android { 25namespace intel { 26 27AnnCursorPlane::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 35AnnCursorPlane::~AnnCursorPlane() 36{ 37 CTRACE(); 38} 39 40bool AnnCursorPlane::enable() 41{ 42 return enablePlane(true); 43 44} 45 46bool AnnCursorPlane::disable() 47{ 48 return enablePlane(false); 49} 50 51bool AnnCursorPlane::reset() 52{ 53 // clear mCrop once reset 54 memset(&mCrop, 0, sizeof(mCrop)); 55 return true; 56} 57 58void* AnnCursorPlane::getContext() const 59{ 60 CTRACE(); 61 return (void *)&mContext; 62} 63 64void AnnCursorPlane::setZOrderConfig(ZOrderConfig& config, void *nativeConfig) 65{ 66 (void) config; 67 (void) nativeConfig; 68 69 CTRACE(); 70} 71 72bool AnnCursorPlane::setDataBuffer(buffer_handle_t handle) 73{ 74 bool ret; 75 76 if (!handle) { 77 ETRACE("handle is NULL"); 78 return false; 79 } 80 81 ret = DisplayPlane::setDataBuffer(handle); 82 if (ret == false) { 83 ETRACE("failed to set data buffer"); 84 return ret; 85 } 86 87 return true; 88} 89 90bool AnnCursorPlane::setDataBuffer(BufferMapper& mapper) 91{ 92 int w = mapper.getWidth(); 93 int h = mapper.getHeight(); 94 int cursorSize = 0; 95 96 CTRACE(); 97 98 // setup plane position 99 int dstX = mPosition.x; 100 int dstY = mPosition.y; 101 102 if (h < w) { 103 cursorSize = h; 104 } else { 105 cursorSize = w; 106 } 107 108 uint32_t cntr = 0; 109 if (64 <= cursorSize && cursorSize < 128) { 110 cursorSize = 64; 111 cntr = 0x7; 112 } else if (128 <= cursorSize && cursorSize < 256) { 113 cursorSize = 128; 114 cntr = 0x2; 115 } else { 116 cursorSize = 256; 117 cntr = 0x3; 118 } 119 120 if (mapper.getFormat() == HAL_PIXEL_FORMAT_RGBA_8888) { 121 cntr |= 1 << 5; 122 } else if (mapper.getFormat() == HAL_PIXEL_FORMAT_BGRA_8888) { 123 // swap color from BGRA to RGBA - alpha is MSB 124 uint8_t *p = (uint8_t *)(mapper.getCpuAddress(0)); 125 uint8_t *srcPixel; 126 uint32_t stride = mapper.getStride().rgb.stride; 127 uint8_t temp; 128 if (!p) { 129 return false; 130 } 131 132 for (int i = 0; i < cursorSize; i++) { 133 for (int j = 0; j < cursorSize; j++) { 134 srcPixel = p + i*stride + j*4; 135 temp = srcPixel[0]; 136 srcPixel[0] = srcPixel[2]; 137 srcPixel[2] = temp; 138 } 139 } 140 cntr |= 1 << 5; 141 } else { 142 ETRACE("invalid color format"); 143 return false; 144 } 145 146 // update context 147 mContext.type = DC_CURSOR_PLANE; 148 mContext.ctx.cs_ctx.index = mIndex; 149 mContext.ctx.cs_ctx.pipe = mDevice; 150 mContext.ctx.cs_ctx.cntr = cntr; 151 mContext.ctx.cs_ctx.surf = mapper.getGttOffsetInPage(0) << 12; 152 153 mContext.ctx.cs_ctx.pos = 0; 154 if (dstX < 0) { 155 mContext.ctx.cs_ctx.pos |= 1 << 15; 156 dstX = -dstX; 157 } 158 if (dstY < 0) { 159 mContext.ctx.cs_ctx.pos |= 1 << 31; 160 dstY = -dstY; 161 } 162 mContext.ctx.cs_ctx.pos |= (dstY & 0xfff) << 16 | (dstX & 0xfff); 163 return true; 164} 165 166bool AnnCursorPlane::enablePlane(bool enabled) 167{ 168 RETURN_FALSE_IF_NOT_INIT(); 169 170 struct drm_psb_register_rw_arg arg; 171 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 172 if (enabled) { 173 arg.plane_enable_mask = 1; 174 } else { 175 arg.plane_disable_mask = 1; 176 } 177 178 arg.plane.type = DC_CURSOR_PLANE; 179 arg.plane.index = mIndex; 180 arg.plane.ctx = 0; 181 182 // issue ioctl 183 Drm *drm = Hwcomposer::getInstance().getDrm(); 184 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 185 if (ret == false) { 186 WTRACE("plane enabling (%d) failed with error code %d", enabled, ret); 187 return false; 188 } 189 190 return true; 191} 192 193bool AnnCursorPlane::isDisabled() 194{ 195 RETURN_FALSE_IF_NOT_INIT(); 196 197 struct drm_psb_register_rw_arg arg; 198 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 199 200 arg.plane.type = DC_CURSOR_PLANE; 201 arg.get_plane_state_mask = 1; 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 state query failed with error code %d", ret); 210 return false; 211 } 212 213 return arg.plane.ctx == PSB_DC_PLANE_DISABLED; 214} 215 216void AnnCursorPlane::postFlip() 217{ 218 // prevent mUpdateMasks from being reset 219 // skipping flip may cause flicking 220} 221 222} // namespace intel 223} // namespace android 224