/* // Copyright (c) 2014 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. */ #include <HwcTrace.h> #include <Drm.h> #include <tangier/TngPrimaryPlane.h> #include <tangier/TngGrallocBuffer.h> #include <common/PixelFormat.h> namespace android { namespace intel { TngPrimaryPlane::TngPrimaryPlane(int index, int disp) : TngSpritePlane(index, disp) { CTRACE(); mType = PLANE_PRIMARY; mForceBottom = true; mAbovePrimary = false; } TngPrimaryPlane::~TngPrimaryPlane() { CTRACE(); } void TngPrimaryPlane::setFramebufferTarget(buffer_handle_t handle) { CTRACE(); // do not need to update the buffer handle if (mCurrentDataBuffer != handle) mUpdateMasks |= PLANE_BUFFER_CHANGED; else mUpdateMasks &= ~PLANE_BUFFER_CHANGED; // if no update then do Not need set data buffer if (!mUpdateMasks) return; // don't need to map data buffer for primary plane mContext.type = DC_PRIMARY_PLANE; mContext.ctx.prim_ctx.update_mask = SPRITE_UPDATE_ALL; mContext.ctx.prim_ctx.index = mIndex; mContext.ctx.prim_ctx.pipe = mDevice; mContext.ctx.prim_ctx.stride = align_to((4 * align_to(mPosition.w, 32)), 64); #ifdef ENABLE_ROTATION_180 mContext.ctx.prim_ctx.linoff = (mPosition.h - 1) * mContext.ctx.prim_ctx.stride + (mPosition.w - 1)* 4; #else mContext.ctx.prim_ctx.linoff = 0; #endif mContext.ctx.prim_ctx.pos = 0; mContext.ctx.prim_ctx.size = ((mPosition.h - 1) & 0xfff) << 16 | ((mPosition.w - 1) & 0xfff); mContext.ctx.prim_ctx.surf = 0; mContext.ctx.prim_ctx.contalpa = 0; mContext.ctx.prim_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888; #ifdef ENABLE_ROTATION_180 mContext.ctx.prim_ctx.cntr |= 0x80008000; #else mContext.ctx.prim_ctx.cntr |= 0x80000000; #endif mCurrentDataBuffer = handle; } bool TngPrimaryPlane::enablePlane(bool enabled) { RETURN_FALSE_IF_NOT_INIT(); struct drm_psb_register_rw_arg arg; memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); if (enabled) { arg.plane_enable_mask = 1; } else { arg.plane_disable_mask = 1; } arg.plane.type = DC_PRIMARY_PLANE; arg.plane.index = mIndex; arg.plane.ctx = 0; // issue ioctl Drm *drm = Hwcomposer::getInstance().getDrm(); bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg)); if (ret == false) { WTRACE("primary enabling (%d) failed with error code %d", enabled, ret); return false; } return true; } bool TngPrimaryPlane::setDataBuffer(buffer_handle_t handle) { if (!handle) { setFramebufferTarget(handle); return true; } TngGrallocBuffer tmpBuf(handle); uint32_t usage; bool ret; ATRACE("handle = %#x", handle); usage = tmpBuf.getUsage(); if (GRALLOC_USAGE_HW_FB & usage) { setFramebufferTarget(handle); return true; } // use primary as a sprite ret = DisplayPlane::setDataBuffer(handle); if (ret == false) { ETRACE("failed to set data buffer"); return ret; } mContext.type = DC_PRIMARY_PLANE; return true; } void TngPrimaryPlane::setZOrderConfig(ZOrderConfig& zorderConfig, void *nativeConfig) { if (!nativeConfig) { ETRACE("Invalid parameter, no native config"); return; } mForceBottom = false; int primaryIndex = -1; int overlayIndex = -1; // only consider force bottom when overlay is active for (size_t i = 0; i < zorderConfig.size(); i++) { DisplayPlane *plane = zorderConfig[i]->plane; if (plane->getType() == DisplayPlane::PLANE_PRIMARY) primaryIndex = i; if (plane->getType() == DisplayPlane::PLANE_OVERLAY) { overlayIndex = i; } } // if has overlay plane which is below primary plane if (overlayIndex > primaryIndex) { mForceBottom = true; } struct intel_dc_plane_zorder *zorder = (struct intel_dc_plane_zorder *)nativeConfig; zorder->forceBottom[mIndex] = mForceBottom ? 1 : 0; } bool TngPrimaryPlane::assignToDevice(int disp) { DisplayPlane::assignToDevice(disp); return true; } } // namespace intel } // namespace android