liboverlay: comp. bypass changes.

This change addresses following:
1. Add new classes for comp. bypass.
2. Remove comp. bypas specific code from exisiting flow.

Change-Id: Id9424b42a9a113cfbb18ceac8d59bbe07ea8e773
This commit is contained in:
Omprakash Dhyade 2011-03-05 09:30:05 -08:00 committed by Govind Surti
parent 9d25efb361
commit dac6f95b56
5 changed files with 657 additions and 17 deletions

View File

@ -1,4 +1,5 @@
# Copyright (C) 2008 The Android Open Source Project
# Copyright (c) 2011, Code Aurora Forum. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -22,7 +23,10 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_C_INCLUDES += hardware/msm7k/libgralloc-qsd8k
LOCAL_SRC_FILES := overlayLib.cpp
LOCAL_SRC_FILES := \
overlayLib.cpp \
overlayLibUI.cpp \
LOCAL_CFLAGS:= -DLOG_TAG=\"OverlayLib\"
LOCAL_MODULE := liboverlay
include $(BUILD_SHARED_LIBRARY)

View File

@ -24,7 +24,7 @@ static inline size_t ALIGN(size_t x, size_t align) {
return (x + align-1) & ~(align-1);
}
static int get_mdp_format(int format) {
int overlay::get_mdp_format(int format) {
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888 :
return MDP_RGBA_8888;
@ -46,7 +46,7 @@ static int get_mdp_format(int format) {
return -1;
}
static int get_size(int format, int w, int h) {
int overlay::get_size(int format, int w, int h) {
int size, aligned_height, pitch;
size = w * h;
@ -84,7 +84,7 @@ static int get_size(int format, int w, int h) {
return size;
}
static int get_mdp_orientation(int rotation, int flip) {
int overlay::get_mdp_orientation(int rotation, int flip) {
switch(flip) {
case HAL_TRANSFORM_FLIP_V:
switch(rotation) {
@ -178,8 +178,7 @@ unsigned int overlay::getOverlayConfig (unsigned int format3D) {
}
Overlay::Overlay() : mChannelUP(false), mHDMIConnected(false),
mCloseChannel(false), mS3DFormat(0),
mWidth(0), mHeight(0),
mS3DFormat(0), mWidth(0), mHeight(0),
mCroppedSrcWidth(0), mCroppedSrcHeight(0) {
}
@ -242,7 +241,7 @@ bool Overlay::startChannelS3D(int w, int h, int format, bool norot) {
bool Overlay::closeChannel() {
if (!mCloseChannel && !mChannelUP)
if (!mChannelUP)
return true;
if(mS3DFormat) {
@ -253,7 +252,6 @@ bool Overlay::closeChannel() {
objOvDataChannel[i].closeDataChannel();
}
mChannelUP = false;
mCloseChannel = false;
mS3DFormat = 0;
mWidth = 0;
mHeight = 0;
@ -355,9 +353,6 @@ int Overlay::hasHDMIStatusChanged() {
bool Overlay::setSource(uint32_t w, uint32_t h, int format, int orientation,
bool hdmiConnected, bool ignoreFB, int num_buffers) {
if (mCloseChannel)
closeChannel();
// Separate the color format from the 3D format.
// If there is 3D content; the effective format passed by the client is:
// effectiveFormat = 3D_IN | 3D_OUT | ColorFormat
@ -1334,10 +1329,6 @@ bool OverlayDataChannel::queue(uint32_t offset) {
mOvDataRot.data.offset = (uint32_t) mRotData.dst.offset;
odPtr = &mOvDataRot;
}
else if (max_num_buffers == mNumBuffers) {
reportError("Rotator failed..");
return false;
}
}
if (ioctl(mFD, MSMFB_OVERLAY_PLAY, odPtr)) {

View File

@ -100,12 +100,15 @@ enum {
OV_3D_VIDEO_3D_PANEL,
OV_3D_VIDEO_3D_TV
};
bool isHDMIConnected();
bool is3DTV();
bool send3DInfoPacket(unsigned int format3D);
unsigned int getOverlayConfig (unsigned int format3D);
int get_mdp_format(int format);
int get_size(int format, int w, int h);
int get_mdp_orientation(int rotation, int flip);
const int max_num_buffers = 3;
typedef struct mdp_rect overlay_rect;
@ -208,7 +211,6 @@ class Overlay {
bool mChannelUP;
bool mHDMIConnected;
bool mCloseChannel;
unsigned int mS3DFormat;
int mWidth;
int mHeight;

491
liboverlay/overlayLibUI.cpp Normal file
View File

@ -0,0 +1,491 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* 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 "overlayLibUI.h"
#include "gralloc_priv.h"
namespace {
/* helper functions */
bool checkOVState(int w, int h, int format, int orientation,
int zorder, const mdp_overlay& ov) {
switch(orientation) {
case OVERLAY_TRANSFORM_ROT_90:
case OVERLAY_TRANSFORM_ROT_270: {
int tmp = w;
w = h;
h = tmp;
break;
}
default:
break;
}
bool displayAttrsCheck = ((w == ov.src.width) && (h == ov.src.height) &&
(format == ov.src.format));
bool zOrderCheck = (ov.z_order == zorder);
if (displayAttrsCheck && zorder == overlay::NO_INIT)
return true;
if (displayAttrsCheck && zorder != overlay::NO_INIT
&& ov.z_order == zorder)
return true;
return false;
}
void swapOVRotWidthHeight(msm_rotator_img_info& rotInfo,
mdp_overlay& ovInfo) {
int srcWidth = ovInfo.src.width;
ovInfo.src.width = ovInfo.src.height;
ovInfo.src.height = srcWidth;
int srcRectWidth = ovInfo.src_rect.w;
ovInfo.src_rect.w = ovInfo.src_rect.h;
ovInfo.src_rect.h = srcRectWidth;
int dstWidth = rotInfo.dst.width;
rotInfo.dst.width = rotInfo.dst.height;
rotInfo.dst.height = dstWidth;
}
void setupOvRotInfo(int w, int h, int format, int orientation,
mdp_overlay& ovInfo, msm_rotator_img_info& rotInfo) {
memset(&ovInfo, 0, sizeof(ovInfo));
memset(&rotInfo, 0, sizeof(rotInfo));
ovInfo.id = MSMFB_NEW_REQUEST;
ovInfo.src.width = w;
ovInfo.src.height = h;
ovInfo.src.format = format;
ovInfo.src_rect.w = w;
ovInfo.src_rect.h = h;
ovInfo.alpha = 0xff;
ovInfo.transp_mask = 0xffffffff;
rotInfo.src.format = format;
rotInfo.dst.format = format;
w = (w + 31) & ~31;
h = (h + 31) & ~31;
rotInfo.src.width = w;
rotInfo.src.height = h;
rotInfo.src_rect.w = w;
rotInfo.src_rect.h = h;
rotInfo.dst.width = w;
rotInfo.dst.height = h;
int rot = orientation;
int flip = 0;
switch(rot) {
case 0:
case HAL_TRANSFORM_FLIP_H:
case HAL_TRANSFORM_FLIP_V:
rot = 0;
flip = orientation & (HAL_TRANSFORM_FLIP_H|HAL_TRANSFORM_FLIP_V);
break;
case HAL_TRANSFORM_ROT_90:
case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V): {
int tmp = ovInfo.src_rect.x;
ovInfo.src_rect.x = ovInfo.src.height -
(ovInfo.src_rect.y + ovInfo.src_rect.h);
ovInfo.src_rect.y = tmp;
swapOVRotWidthHeight(rotInfo, ovInfo);
rot = HAL_TRANSFORM_ROT_90;
flip = orientation & (HAL_TRANSFORM_FLIP_H|HAL_TRANSFORM_FLIP_V);
break;
}
case HAL_TRANSFORM_ROT_180:
break;
case HAL_TRANSFORM_ROT_270: {
int tmp = ovInfo.src_rect.y;
ovInfo.src_rect.y = ovInfo.src.width -
(ovInfo.src_rect.x + ovInfo.src_rect.w);
ovInfo.src_rect.x = tmp;
swapOVRotWidthHeight(rotInfo, ovInfo);
break;
}
default:
break;
}
int mdp_rotation = overlay::get_mdp_orientation(rot, flip);
if (mdp_rotation < 0)
mdp_rotation = 0;
ovInfo.user_data[0] = mdp_rotation;
rotInfo.rotations = ovInfo.user_data[0];
if (mdp_rotation)
rotInfo.enable = 1;
ovInfo.dst_rect.w = ovInfo.src_rect.w;
ovInfo.dst_rect.h = ovInfo.src_rect.h;
}
bool isRGBType(int format) {
bool ret = false;
switch(format) {
case MDP_RGBA_8888:
case MDP_BGRA_8888:
case MDP_RGBX_8888:
case MDP_RGB_565:
ret = true;
break;
default:
ret = false;
break;
}
return ret;
}
int getRGBBpp(int format) {
int ret = -1;
switch(format) {
case MDP_RGBA_8888:
case MDP_BGRA_8888:
case MDP_RGBX_8888:
ret = 4;
break;
case MDP_RGB_565:
ret = 2;
break;
default:
ret = -1;
break;
}
return ret;
}
bool turnOFFVSync() {
static int swapIntervalPropVal = -1;
if (swapIntervalPropVal == -1) {
char pval[PROPERTY_VALUE_MAX];
property_get("debug.gr.swapinterval", pval, "1");
swapIntervalPropVal = atoi(pval);
}
return (swapIntervalPropVal == 0);
}
};
namespace overlay {
status_t Display::openDisplay(int fbnum) {
if (mFD != NO_INIT)
return ALREADY_EXISTS;
status_t ret = NO_INIT;
char const * const device_template =
"/dev/graphics/fb%u";
char dev_name[64];
snprintf(dev_name, 64, device_template, fbnum);
mFD = open(dev_name, O_RDWR, 0);
if (mFD < 0) {
LOGE("Failed to open FB %d", fbnum);
return ret;
}
fb_var_screeninfo vinfo;
if (ioctl(mFD, FBIOGET_VSCREENINFO, &vinfo)) {
LOGE("FBIOGET_VSCREENINFO on failed on FB %d", fbnum);
close(mFD);
mFD = NO_INIT;
return ret;
}
mFBWidth = vinfo.xres;
mFBHeight = vinfo.yres;
mFBBpp = vinfo.bits_per_pixel;
ret = NO_ERROR;
return ret;
}
status_t OVHelper::startOVSession(mdp_overlay& ovInfo, int fbnum) {
status_t ret = NO_INIT;
if (mSessionID == NO_INIT) {
ret = mobjDisplay.openDisplay(fbnum);
if (ret != NO_ERROR)
return ret;
if (ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_SET, &ovInfo)) {
LOGE("OVerlay set failed..");
mobjDisplay.closeDisplay();
ret = BAD_VALUE;
}
else {
mSessionID = ovInfo.id;
mOVInfo = ovInfo;
ret = NO_ERROR;
}
}
else
ret = ALREADY_EXISTS;
return ret;
}
status_t OVHelper::queueBuffer(msmfb_overlay_data ovData) {
if (mSessionID == NO_INIT)
return NO_INIT;
ovData.id = mSessionID;
if (ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_PLAY, &ovData))
return BAD_VALUE;
return NO_ERROR;
}
status_t OVHelper::closeOVSession() {
if (mSessionID != NO_INIT) {
ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_UNSET, &mSessionID);
mobjDisplay.closeDisplay();
}
mSessionID = NO_INIT;
return NO_ERROR;
}
status_t OVHelper::setPosition(int x, int y, int w, int h) {
status_t ret = BAD_VALUE;
if (mSessionID != NO_INIT) {
int fd = mobjDisplay.getFD();
if (x < 0 || y < 0 || ((x + w) > getFBWidth())) {
LOGE("set position failed, invalid argument");
return ret;
}
mdp_overlay ov;
ov.id = mSessionID;
if (!ioctl(fd, MSMFB_OVERLAY_GET, &ov)) {
if (x != ov.dst_rect.x || y != ov.dst_rect.y ||
w != ov.dst_rect.w || h != ov.dst_rect.h) {
ov.dst_rect.x = x;
ov.dst_rect.y = y;
ov.dst_rect.w = w;
ov.dst_rect.h = h;
if (ioctl(fd, MSMFB_OVERLAY_SET, &ov)) {
LOGE("set position failed");
return ret;
}
}
mOVInfo = ov;
return NO_ERROR;
}
return ret;
}
return NO_INIT;
}
status_t OVHelper::getOVInfo(mdp_overlay& ovInfo) {
if (mSessionID == NO_INIT)
return NO_INIT;
ovInfo = mOVInfo;
return NO_ERROR;
}
status_t Rotator::startRotSession(msm_rotator_img_info& rotInfo,
int numBuffers) {
status_t ret = ALREADY_EXISTS;
if (mSessionID == NO_INIT && mFD == NO_INIT) {
mNumBuffers = numBuffers;
mFD = open("/dev/msm_rotator", O_RDWR, 0);
if (mFD < 0) {
LOGE("Couldnt open rotator device");
return NO_INIT;
}
if (int check = ioctl(mFD, MSM_ROTATOR_IOCTL_START, &rotInfo)) {
close(mFD);
mFD = NO_INIT;
return NO_INIT;
}
mSessionID = rotInfo.session_id;
mPmemFD = open("/dev/pmem_adsp", O_RDWR | O_SYNC);
if (mPmemFD < 0) {
closeRotSession();
return NO_INIT;
}
mSize = get_size(rotInfo.src.format, rotInfo.src.width, rotInfo.src.height);
mPmemAddr = (void *) mmap(NULL, mSize* mNumBuffers, PROT_READ | PROT_WRITE,
MAP_SHARED, mPmemFD, 0);
if (mPmemAddr == MAP_FAILED) {
closeRotSession();
return NO_INIT;
}
mCurrentItem = 0;
for (int i = 0; i < mNumBuffers; i++)
mRotOffset[i] = i * mSize;
ret = NO_ERROR;
}
return ret;
}
status_t Rotator::closeRotSession() {
if (mSessionID != NO_INIT && mFD != NO_INIT) {
ioctl(mFD, MSM_ROTATOR_IOCTL_FINISH, &mSessionID);
close(mFD);
munmap(mPmemAddr, mSize * mNumBuffers);
close(mPmemFD);
}
mFD = NO_INIT;
mSessionID = NO_INIT;
mPmemFD = NO_INIT;
mPmemAddr = MAP_FAILED;
return NO_ERROR;
}
status_t Rotator::rotateBuffer(msm_rotator_data_info& rotData) {
status_t ret = NO_INIT;
if (mSessionID != NO_INIT) {
rotData.dst.memory_id = mPmemFD;
rotData.dst.offset = mRotOffset[mCurrentItem];
rotData.session_id = mSessionID;
mCurrentItem = (mCurrentItem + 1) % mNumBuffers;
if (ioctl(mFD, MSM_ROTATOR_IOCTL_ROTATE, &rotData)) {
LOGE("Rotator failed to rotate");
return BAD_VALUE;
}
return NO_ERROR;
}
return ret;
}
status_t OverlayUI::closeChannel() {
mobjOVHelper.closeOVSession();
mobjRotator.closeRotSession();
mChannelState = CLOSED;
return NO_ERROR;
}
status_t OverlayUI::setSource(int w, int h, int format, int orientation,
bool useVGPipe, bool ignoreFB,
int fbnum, int zorder) {
status_t ret = NO_INIT;
int format3D = FORMAT_3D(format);
int colorFormat = COLOR_FORMAT(format);
format = get_mdp_format(colorFormat);
if (format3D || !isRGBType(format))
return ret;
if (mChannelState == PENDING_CLOSE)
closeChannel();
if (mChannelState == UP) {
mdp_overlay ov;
if (mobjOVHelper.getOVInfo(ov) == NO_ERROR) {
if (mOrientation == orientation &&
mFBNum == fbnum &&
checkOVState(w, h, format, orientation, zorder, ov))
return NO_ERROR;
else
mChannelState = PENDING_CLOSE;
}
else
mChannelState = PENDING_CLOSE;
return ret;
}
mOrientation = orientation;
mdp_overlay ovInfo;
msm_rotator_img_info rotInfo;
setupOvRotInfo(w, h, format, orientation, ovInfo, rotInfo);
int flags = 0;
if (ignoreFB)
ovInfo.is_fg = 1;
else
flags |= MDP_OV_PLAY_NOWAIT;
if (turnOFFVSync())
flags |= MDP_OV_PLAY_NOWAIT;
if (useVGPipe ||
(fbnum == FB0 && getRGBBpp(format) != mobjOVHelper.getFBBpp()))
flags |= MDP_OV_PIPE_SHARE;
ovInfo.flags = flags;
if (zorder != NO_INIT)
ovInfo.z_order = zorder;
ret = startChannel(fbnum, ovInfo, rotInfo);
return ret;
}
status_t OverlayUI::startChannel(int fbnum, mdp_overlay& ovInfo,
msm_rotator_img_info& rotInfo) {
status_t ret = BAD_VALUE;
if (mChannelState == UP)
return ret;
ret = mobjOVHelper.startOVSession(ovInfo, fbnum);
if (ret == NO_ERROR && mOrientation)
ret = mobjRotator.startRotSession(rotInfo);
if (ret == NO_ERROR) {
mChannelState = UP;
mFBNum = fbnum;
}
else
LOGE("start channel failed.");
return ret;
}
status_t OverlayUI::queueBuffer(buffer_handle_t buffer) {
status_t ret = NO_INIT;
if (mChannelState != UP)
return ret;
msmfb_overlay_data ovData;
memset(&ovData, 0, sizeof(ovData));
private_handle_t const* hnd = reinterpret_cast
<private_handle_t const*>(buffer);
ovData.data.memory_id = hnd->fd;
ovData.data.offset = hnd->offset;
if (mOrientation) {
msm_rotator_data_info rotData;
memset(&rotData, 0, sizeof(rotData));
rotData.src.memory_id = hnd->fd;
rotData.src.offset = hnd->offset;
if (mobjRotator.rotateBuffer(rotData) != NO_ERROR) {
LOGE("Rotator failed.. ");
return BAD_VALUE;
}
ovData.data.memory_id = rotData.dst.memory_id;
ovData.data.offset = rotData.dst.offset;
}
ret = mobjOVHelper.queueBuffer(ovData);
if (ret != NO_ERROR)
LOGE("Queuebuffer failed ");
return ret;
}
};

152
liboverlay/overlayLibUI.h Normal file
View File

@ -0,0 +1,152 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
*
* 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.
*/
#ifndef INCLUDE_OVERLAY_LIB_UI
#define INCLUDE_OVERLAY_LIB_UI
#include <errno.h>
#include "overlayLib.h"
namespace overlay {
enum channel_state_t { UP, CLOSED, PENDING_CLOSE };
enum status_t {
NO_ERROR,
INVALID_OPERATION = -ENOSYS,
BAD_VALUE = -EINVAL,
NO_INIT = -ENODEV,
ALREADY_EXISTS = -EEXIST
};
/*
* Display class provides following services
* Open FB
* FB information (Width, Height and Bpp)
*/
class Display {
int mFD;
int mFBWidth;
int mFBHeight;
int mFBBpp;
Display(const Display& objDisplay);
Display& operator=(const Display& objDisplay);
public:
explicit Display() : mFD(NO_INIT) { };
~Display() { close(mFD); };
int getFD() const { return mFD; };
int getFBWidth() const { return mFBWidth; };
int getFBHeight() const { return mFBHeight; };
int getFBBpp() const { return mFBBpp; };
status_t openDisplay(int fbnum);
void closeDisplay() { close(mFD); mFD = NO_INIT; };
};
/*
* OVHelper class, provides apis related to Overlay
* It communicates with MDP driver, provides following services
* Start overlay session
* Set position of the destination on to display
*/
class OVHelper {
int mSessionID;
Display mobjDisplay;
mdp_overlay mOVInfo;
OVHelper(const OVHelper& objOVHelper);
OVHelper& operator=(const OVHelper& objOVHelper);
public:
explicit OVHelper() : mSessionID(NO_INIT) { };
~OVHelper() { closeOVSession(); };
status_t startOVSession(mdp_overlay& ovInfo, int fbnum);
status_t closeOVSession();
status_t queueBuffer(msmfb_overlay_data ovData);
int getFBWidth() const { return mobjDisplay.getFBWidth(); };
int getFBHeight() const { return mobjDisplay.getFBHeight(); };
int getFBBpp() const { return mobjDisplay.getFBBpp(); };
status_t setPosition(int x, int y, int w, int h);
status_t getOVInfo(mdp_overlay& ovInfo);
};
/*
* Rotator class, manages rotation of the buffers
* It communicates with Rotator driver, provides following services
* Start rotator session
* Rotate buffer
*/
class Rotator {
int mFD;
int mSessionID;
int mPmemFD;
void* mPmemAddr;
int mRotOffset[max_num_buffers];
int mCurrentItem;
int mNumBuffers;
int mSize;
Rotator(const Rotator& objROtator);
Rotator& operator=(const Rotator& objRotator);
public:
explicit Rotator() : mFD(NO_INIT), mSessionID(NO_INIT), mPmemFD(-1) { };
~Rotator() { closeRotSession(); }
status_t startRotSession(msm_rotator_img_info& rotInfo, int numBuffers = max_num_buffers);
status_t closeRotSession();
status_t rotateBuffer(msm_rotator_data_info& rotData);
};
/*
* Overlay class for Comp. Bypass
* We merge control and data channel classes.
*/
class OverlayUI {
channel_state_t mChannelState;
int mOrientation;
int mFBNum;
OVHelper mobjOVHelper;
Rotator mobjRotator;
OverlayUI(const OverlayUI& objOverlay);
OverlayUI& operator=(const OverlayUI& objOverlay);
status_t startChannel(int fbnum, mdp_overlay& ovInfo,
msm_rotator_img_info& rotInfo);
public:
enum fbnum_t { FB0, FB1 };
explicit OverlayUI() : mChannelState(CLOSED), mOrientation(NO_INIT), mFBNum(NO_INIT) { };
~OverlayUI() { closeChannel(); };
status_t setSource(int w, int h, int format, int orientation,
bool useVGPipe = false, bool ignoreFB = true,
int fbnum = FB0, int zorder = NO_INIT);
status_t setPosition(int x, int y, int w, int h) {
return mobjOVHelper.setPosition(x, y, w, h);
};
status_t closeChannel();
channel_state_t isChannelUP() const { return mChannelState; };
int getFBWidth() const { return mobjOVHelper.getFBWidth(); };
int getFBHeight() const { return mobjOVHelper.getFBHeight(); };
status_t queueBuffer(buffer_handle_t buffer);
};
};
#endif