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 <Drm.h> 18#include <tangier/TngPrimaryPlane.h> 19#include <tangier/TngGrallocBuffer.h> 20#include <common/PixelFormat.h> 21 22namespace android { 23namespace intel { 24 25TngPrimaryPlane::TngPrimaryPlane(int index, int disp) 26 : TngSpritePlane(index, disp) 27{ 28 CTRACE(); 29 mType = PLANE_PRIMARY; 30 mForceBottom = true; 31 mAbovePrimary = false; 32} 33 34TngPrimaryPlane::~TngPrimaryPlane() 35{ 36 CTRACE(); 37} 38 39void TngPrimaryPlane::setFramebufferTarget(buffer_handle_t handle) 40{ 41 CTRACE(); 42 43 // do not need to update the buffer handle 44 if (mCurrentDataBuffer != handle) 45 mUpdateMasks |= PLANE_BUFFER_CHANGED; 46 else 47 mUpdateMasks &= ~PLANE_BUFFER_CHANGED; 48 49 // if no update then do Not need set data buffer 50 if (!mUpdateMasks) 51 return; 52 53 // don't need to map data buffer for primary plane 54 mContext.type = DC_PRIMARY_PLANE; 55 mContext.ctx.prim_ctx.update_mask = SPRITE_UPDATE_ALL; 56 mContext.ctx.prim_ctx.index = mIndex; 57 mContext.ctx.prim_ctx.pipe = mDevice; 58 mContext.ctx.prim_ctx.stride = align_to((4 * align_to(mPosition.w, 32)), 64); 59#ifdef ENABLE_ROTATION_180 60 mContext.ctx.prim_ctx.linoff = (mPosition.h - 1) * mContext.ctx.prim_ctx.stride + (mPosition.w - 1)* 4; 61#else 62 mContext.ctx.prim_ctx.linoff = 0; 63#endif 64 mContext.ctx.prim_ctx.pos = 0; 65 mContext.ctx.prim_ctx.size = 66 ((mPosition.h - 1) & 0xfff) << 16 | ((mPosition.w - 1) & 0xfff); 67 mContext.ctx.prim_ctx.surf = 0; 68 mContext.ctx.prim_ctx.contalpa = 0; 69 70 mContext.ctx.prim_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888; 71#ifdef ENABLE_ROTATION_180 72 mContext.ctx.prim_ctx.cntr |= 0x80008000; 73#else 74 mContext.ctx.prim_ctx.cntr |= 0x80000000; 75#endif 76 mCurrentDataBuffer = handle; 77} 78 79bool TngPrimaryPlane::enablePlane(bool enabled) 80{ 81 RETURN_FALSE_IF_NOT_INIT(); 82 83 struct drm_psb_register_rw_arg arg; 84 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); 85 if (enabled) { 86 arg.plane_enable_mask = 1; 87 } else { 88 arg.plane_disable_mask = 1; 89 } 90 arg.plane.type = DC_PRIMARY_PLANE; 91 arg.plane.index = mIndex; 92 arg.plane.ctx = 0; 93 94 // issue ioctl 95 Drm *drm = Hwcomposer::getInstance().getDrm(); 96 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); 97 if (ret == false) { 98 WTRACE("primary enabling (%d) failed with error code %d", enabled, ret); 99 return false; 100 } 101 102 return true; 103 104} 105 106bool TngPrimaryPlane::setDataBuffer(buffer_handle_t handle) 107{ 108 if (!handle) { 109 setFramebufferTarget(handle); 110 return true; 111 } 112 113 TngGrallocBuffer tmpBuf(handle); 114 uint32_t usage; 115 bool ret; 116 117 ATRACE("handle = %#x", handle); 118 119 usage = tmpBuf.getUsage(); 120 if (GRALLOC_USAGE_HW_FB & usage) { 121 setFramebufferTarget(handle); 122 return true; 123 } 124 125 // use primary as a sprite 126 ret = DisplayPlane::setDataBuffer(handle); 127 if (ret == false) { 128 ETRACE("failed to set data buffer"); 129 return ret; 130 } 131 132 mContext.type = DC_PRIMARY_PLANE; 133 return true; 134} 135 136void TngPrimaryPlane::setZOrderConfig(ZOrderConfig& zorderConfig, 137 void *nativeConfig) 138{ 139 if (!nativeConfig) { 140 ETRACE("Invalid parameter, no native config"); 141 return; 142 } 143 144 mForceBottom = false; 145 146 int primaryIndex = -1; 147 int overlayIndex = -1; 148 // only consider force bottom when overlay is active 149 for (size_t i = 0; i < zorderConfig.size(); i++) { 150 DisplayPlane *plane = zorderConfig[i]->plane; 151 if (plane->getType() == DisplayPlane::PLANE_PRIMARY) 152 primaryIndex = i; 153 if (plane->getType() == DisplayPlane::PLANE_OVERLAY) { 154 overlayIndex = i; 155 } 156 } 157 158 // if has overlay plane which is below primary plane 159 if (overlayIndex > primaryIndex) { 160 mForceBottom = true; 161 } 162 163 struct intel_dc_plane_zorder *zorder = 164 (struct intel_dc_plane_zorder *)nativeConfig; 165 zorder->forceBottom[mIndex] = mForceBottom ? 1 : 0; 166} 167 168bool TngPrimaryPlane::assignToDevice(int disp) 169{ 170 DisplayPlane::assignToDevice(disp); 171 return true; 172} 173 174} // namespace intel 175} // namespace android 176