|
|
/* |
|
|
// 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 <Hwcomposer.h> |
|
|
#include <BufferManager.h> |
|
|
#include <tangier/TngSpritePlane.h> |
|
|
#include <common/PixelFormat.h> |
|
|
|
|
|
namespace android { |
|
|
namespace intel { |
|
|
|
|
|
TngSpritePlane::TngSpritePlane(int index, int disp) |
|
|
: SpritePlaneBase(index, disp) |
|
|
{ |
|
|
CTRACE(); |
|
|
memset(&mContext, 0, sizeof(mContext)); |
|
|
} |
|
|
|
|
|
TngSpritePlane::~TngSpritePlane() |
|
|
{ |
|
|
CTRACE(); |
|
|
} |
|
|
|
|
|
bool TngSpritePlane::setDataBuffer(BufferMapper& mapper) |
|
|
{ |
|
|
int bpp; |
|
|
int srcX, srcY; |
|
|
int dstX, dstY, dstW, dstH; |
|
|
uint32_t spriteFormat; |
|
|
uint32_t stride; |
|
|
uint32_t linoff; |
|
|
uint32_t planeAlpha; |
|
|
|
|
|
CTRACE(); |
|
|
|
|
|
// setup plane position |
|
|
dstX = mPosition.x; |
|
|
dstY = mPosition.y; |
|
|
dstW = mPosition.w; |
|
|
dstH = mPosition.h; |
|
|
|
|
|
checkPosition(dstX, dstY, dstW, dstH); |
|
|
|
|
|
// setup plane format |
|
|
if (!PixelFormat::convertFormat(mapper.getFormat(), spriteFormat, bpp)) { |
|
|
ETRACE("unsupported format %#x", mapper.getFormat()); |
|
|
return false; |
|
|
} |
|
|
|
|
|
// setup stride and source buffer crop |
|
|
srcX = mapper.getCrop().x; |
|
|
srcY = mapper.getCrop().y; |
|
|
stride = mapper.getStride().rgb.stride; |
|
|
#ifdef ENABLE_ROTATION_180 |
|
|
linoff = (mapper.getCrop().h + srcY - 1) * stride + (srcX + mapper.getCrop().w - 1) * bpp; |
|
|
#else |
|
|
linoff = srcY * stride + srcX * bpp; |
|
|
#endif |
|
|
|
|
|
// setup plane alpha |
|
|
if ((mBlending == HWC_BLENDING_PREMULT) && (mPlaneAlpha == 0)) { |
|
|
planeAlpha = mPlaneAlpha | 0x80000000; |
|
|
} else { |
|
|
// disable plane alpha to offload HW |
|
|
planeAlpha = 0; |
|
|
} |
|
|
|
|
|
// unlikely happen, but still we need make sure linoff is valid |
|
|
if (linoff > (stride * mapper.getHeight())) { |
|
|
ETRACE("invalid source crop"); |
|
|
return false; |
|
|
} |
|
|
|
|
|
// update context |
|
|
mContext.type = DC_SPRITE_PLANE; |
|
|
mContext.ctx.sp_ctx.index = mIndex; |
|
|
mContext.ctx.sp_ctx.pipe = mDevice; |
|
|
// none blending and BRGA format layer,set format to BGRX8888 |
|
|
if (mBlending == HWC_BLENDING_NONE && spriteFormat == PixelFormat::PLANE_PIXEL_FORMAT_BGRA8888) |
|
|
mContext.ctx.sp_ctx.cntr = PixelFormat::PLANE_PIXEL_FORMAT_BGRX8888 |
|
|
| 0x80000000; |
|
|
else |
|
|
mContext.ctx.sp_ctx.cntr = spriteFormat | 0x80000000; |
|
|
mContext.ctx.sp_ctx.linoff = linoff; |
|
|
mContext.ctx.sp_ctx.stride = stride; |
|
|
mContext.ctx.sp_ctx.surf = mapper.getGttOffsetInPage(0) << 12; |
|
|
mContext.ctx.sp_ctx.pos = (dstY & 0xfff) << 16 | (dstX & 0xfff); |
|
|
mContext.ctx.sp_ctx.size = |
|
|
((dstH - 1) & 0xfff) << 16 | ((dstW - 1) & 0xfff); |
|
|
mContext.ctx.sp_ctx.contalpa = planeAlpha; |
|
|
mContext.ctx.sp_ctx.update_mask = SPRITE_UPDATE_ALL; |
|
|
mContext.gtt_key = (uint64_t)mapper.getCpuAddress(0); |
|
|
#ifdef ENABLE_ROTATION_180 |
|
|
mContext.ctx.sp_ctx.cntr |= 1 << 15; |
|
|
#endif |
|
|
VTRACE("cntr = %#x, linoff = %#x, stride = %#x," |
|
|
"surf = %#x, pos = %#x, size = %#x, contalpa = %#x", |
|
|
mContext.ctx.sp_ctx.cntr, |
|
|
mContext.ctx.sp_ctx.linoff, |
|
|
mContext.ctx.sp_ctx.stride, |
|
|
mContext.ctx.sp_ctx.surf, |
|
|
mContext.ctx.sp_ctx.pos, |
|
|
mContext.ctx.sp_ctx.size, |
|
|
mContext.ctx.sp_ctx.contalpa); |
|
|
return true; |
|
|
} |
|
|
|
|
|
void* TngSpritePlane::getContext() const |
|
|
{ |
|
|
CTRACE(); |
|
|
return (void *)&mContext; |
|
|
} |
|
|
|
|
|
bool TngSpritePlane::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_SPRITE_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("sprite enabling (%d) failed with error code %d", enabled, ret); |
|
|
return false; |
|
|
} |
|
|
|
|
|
Hwcomposer& hwc = Hwcomposer::getInstance(); |
|
|
DisplayPlaneManager *pm = hwc.getPlaneManager(); |
|
|
void *config = pm->getZOrderConfig(); |
|
|
if (config != NULL) { |
|
|
struct intel_dc_plane_zorder *zorder = (struct intel_dc_plane_zorder *)config; |
|
|
zorder->abovePrimary = 0; |
|
|
} |
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
bool TngSpritePlane::isDisabled() |
|
|
{ |
|
|
RETURN_FALSE_IF_NOT_INIT(); |
|
|
|
|
|
struct drm_psb_register_rw_arg arg; |
|
|
memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg)); |
|
|
|
|
|
if (mType == DisplayPlane::PLANE_SPRITE) |
|
|
arg.plane.type = DC_SPRITE_PLANE; |
|
|
else |
|
|
arg.plane.type = DC_PRIMARY_PLANE; |
|
|
|
|
|
arg.get_plane_state_mask = 1; |
|
|
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("plane state query failed with error code %d", ret); |
|
|
return false; |
|
|
} |
|
|
|
|
|
return arg.plane.ctx == PSB_DC_PLANE_DISABLED; |
|
|
} |
|
|
|
|
|
void TngSpritePlane::setZOrderConfig(ZOrderConfig& zorderConfig, |
|
|
void *nativeConfig) |
|
|
{ |
|
|
if (!nativeConfig) { |
|
|
ETRACE("Invalid parameter, no native config"); |
|
|
return; |
|
|
} |
|
|
|
|
|
mAbovePrimary = false; |
|
|
|
|
|
int primaryIndex = -1; |
|
|
int spriteIndex = -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_SPRITE) { |
|
|
spriteIndex = i; |
|
|
} |
|
|
} |
|
|
|
|
|
// if has overlay plane which is below primary plane |
|
|
if (spriteIndex > primaryIndex) { |
|
|
mAbovePrimary = true; |
|
|
} |
|
|
|
|
|
struct intel_dc_plane_zorder *zorder = |
|
|
(struct intel_dc_plane_zorder *)nativeConfig; |
|
|
zorder->abovePrimary = mAbovePrimary ? 1 : 0; |
|
|
} |
|
|
} // namespace intel |
|
|
} // namespace android
|
|
|
|