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#include <HwcTrace.h> 17#include <Hwcomposer.h> 18#include <BufferManager.h> 19#include <tangier/TngSpritePlane.h> 20#include <common/PixelFormat.h> 21 22namespace android { 23namespace intel { 24 25TngSpritePlane::TngSpritePlane(int index, int disp) 26 : SpritePlaneBase(index, disp) 27{ 28 CTRACE(); 29 memset(&mContext, 0, sizeof(mContext)); 30} 31 32TngSpritePlane::~TngSpritePlane() 33{ 34 CTRACE(); 35} 36 37bool TngSpritePlane::setDataBuffer(BufferMapper& mapper) 38{ 39 int bpp; 40 int srcX, srcY; 41 int dstX, dstY, dstW, dstH; 42 uint32_t spriteFormat; 43 uint32_t stride; 44 uint32_t linoff; 45 uint32_t planeAlpha; 46 47 CTRACE(); 48 49 // setup plane position 50 dstX = mPosition.x; 51 dstY = mPosition.y; 52 dstW = mPosition.w; 53 dstH = mPosition.h; 54 55 checkPosition(dstX, dstY, dstW, dstH); 56 57 // setup plane format 58 if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) { 59 ETRACE("unsupported format %#x", mapper.getFormat()); 60 return false; 61 } 62 63 // setup stride and source buffer crop 64 srcX = mapper.getCrop().x; 65 srcY = mapper.getCrop().y; 66 stride = mapper.getStride().rgb.stride; 67#ifdef ENABLE_ROTATION_180 68 linoff = (mapper.getCrop().h + srcY - 1) * stride + (srcX + mapper.getCrop().w - 1) * bpp; 69#else 70 linoff = srcY * stride + srcX * bpp; 71#endif 72 73 // setup plane alpha 74 if ((mBlending == HWC_BLENDING_PREMULT) && (mPlaneAlpha == 0)) { 75 planeAlpha = mPlaneAlpha | 0x80000000; 76 } else { 77 // disable plane alpha to offload HW 78 planeAlpha = 0; 79 } 80 81 // unlikely happen, but still we need make sure linoff is valid 82 if (linoff > (stride * mapper.getHeight())) { 83 ETRACE("invalid source crop"); 84 return false; 85 } 86 87 // update context 88 mContext.type = DC_SPRITE_PLANE; 89 mContext.ctx.sp_ctx.index = mIndex; 90 mContext.ctx.sp_ctx.pipe = mDevice; 91 // none blending and BRGA format layer,set format to BGRX8888 92 if (mBlending == HWC_BLENDING_NONE && spriteFormat == PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888) 93 mContext.ctx.sp_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRX8888 94 | 0x80000000; 95 else 96 mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000; 97 mContext.ctx.sp_ctx.linoff = linoff; 98 mContext.ctx.sp_ctx.stride = stride; 99 mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12; 100 mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff); 101 mContext.ctx.sp_ctx.size = 102 ((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff); 103 mContext.ctx.sp_ctx.contalpa = planeAlpha; 104 mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL; 105 mContext.gtt_key = (uint64_t)mapper.getCpuAddress(0); 106#ifdef ENABLE_ROTATION_180 107 mContext.ctx.sp_ctx.cntr |= 1 << 15; 108#endif 109 VTRACE("cntr = %#x, linoff = %#x, stride = %#x," 110 "surf = %#x, pos = %#x, size = %#x, contalpa = %#x", 111 mContext.ctx.sp_ctx.cntr, 112 mContext.ctx.sp_ctx.linoff, 113 mContext.ctx.sp_ctx.stride, 114 mContext.ctx.sp_ctx.surf, 115 mContext.ctx.sp_ctx.pos, 116 mContext.ctx.sp_ctx.size, 117 mContext.ctx.sp_ctx.contalpa); 118 return true; 119} 120 121void* TngSpritePlane::getContext() const 122{ 123 CTRACE(); 124 return (void *)&mContext; 125} 126 127bool TngSpritePlane::enablePlane(bool enabled) 128{ 129 RETURN_FALSE_IF_NOT_INIT(); 130 131 struct drm_psb_register_rw_arg arg; 132 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 133 if (enabled) { 134 arg.plane_enable_mask = 1; 135 } else { 136 arg.plane_disable_mask = 1; 137 } 138 arg.plane.type = DC_SPRITE_PLANE; 139 arg.plane.index = mIndex; 140 arg.plane.ctx = 0; 141 142 // issue ioctl 143 Drm *drm = Hwcomposer::getInstance().getDrm(); 144 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 145 if (ret == false) { 146 WTRACE("sprite enabling (%d) failed with error code %d", enabled, ret); 147 return false; 148 } 149 150 Hwcomposer& hwc = Hwcomposer::getInstance(); 151 DisplayPlaneManager *pm = hwc.getPlaneManager(); 152 void *config = pm->getZOrderConfig(); 153 if (config != NULL) { 154 struct intel_dc_plane_zorder *zorder = (struct intel_dc_plane_zorder *)config; 155 zorder->abovePrimary = 0; 156 } 157 158 return true; 159 160} 161 162bool TngSpritePlane::isDisabled() 163{ 164 RETURN_FALSE_IF_NOT_INIT(); 165 166 struct drm_psb_register_rw_arg arg; 167 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 168 169 if (mType == DisplayPlane::PLANE_SPRITE) 170 arg.plane.type = DC_SPRITE_PLANE; 171 else 172 arg.plane.type = DC_PRIMARY_PLANE; 173 174 arg.get_plane_state_mask = 1; 175 arg.plane.index = mIndex; 176 arg.plane.ctx = 0; 177 178 // issue ioctl 179 Drm *drm = Hwcomposer::getInstance().getDrm(); 180 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 181 if (ret == false) { 182 WTRACE("plane state query failed with error code %d", ret); 183 return false; 184 } 185 186 return arg.plane.ctx == PSB_DC_PLANE_DISABLED; 187} 188 189void TngSpritePlane::setZOrderConfig(ZOrderConfig& zorderConfig, 190 void *nativeConfig) 191{ 192 if (!nativeConfig) { 193 ETRACE("Invalid parameter, no native config"); 194 return; 195 } 196 197 mAbovePrimary = false; 198 199 int primaryIndex = -1; 200 int spriteIndex = -1; 201 // only consider force bottom when overlay is active 202 for (size_t i = 0; i < zorderConfig.size(); i++) { 203 DisplayPlane *plane = zorderConfig[i]->plane; 204 if (plane->getType() == DisplayPlane::PLANE_PRIMARY) 205 primaryIndex = i; 206 if (plane->getType() == DisplayPlane::PLANE_SPRITE) { 207 spriteIndex = i; 208 } 209 } 210 211 // if has overlay plane which is below primary plane 212 if (spriteIndex > primaryIndex) { 213 mAbovePrimary = true; 214 } 215 216 struct intel_dc_plane_zorder *zorder = 217 (struct intel_dc_plane_zorder *)nativeConfig; 218 zorder->abovePrimary = mAbovePrimary ? 1 : 0; 219} 220} // namespace intel 221} // namespace android 222