diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk index 0beefbe..d271fb5 100644 --- a/liboverlay/Android.mk +++ b/liboverlay/Android.mk @@ -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) diff --git a/liboverlay/overlayLib.cpp b/liboverlay/overlayLib.cpp index f4b4609..f9bd8b0 100644 --- a/liboverlay/overlayLib.cpp +++ b/liboverlay/overlayLib.cpp @@ -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)) { diff --git a/liboverlay/overlayLib.h b/liboverlay/overlayLib.h index 4d7f2ea..fbc6c60 100644 --- a/liboverlay/overlayLib.h +++ b/liboverlay/overlayLib.h @@ -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; diff --git a/liboverlay/overlayLibUI.cpp b/liboverlay/overlayLibUI.cpp new file mode 100644 index 0000000..5066681 --- /dev/null +++ b/liboverlay/overlayLibUI.cpp @@ -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 + (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; +} + +}; diff --git a/liboverlay/overlayLibUI.h b/liboverlay/overlayLibUI.h new file mode 100644 index 0000000..bf749fa --- /dev/null +++ b/liboverlay/overlayLibUI.h @@ -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 + +#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