initial GL libraries for msm8960
Change-Id: I16451c70a079894ac326d3564d96f1fbafcd4f1b
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/liboverlay/overlayLibUI.cpp b/liboverlay/overlayLibUI.cpp
new file mode 100755
index 0000000..d3fd80a
--- /dev/null
+++ b/liboverlay/overlayLibUI.cpp
@@ -0,0 +1,482 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2011-2012, 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"
+#define LOG_TAG "OverlayUI"
+
+using android::sp;
+using gralloc::IMemAlloc;
+using gralloc::alloc_data;
+
+namespace {
+/* helper functions */
+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;
+}
+
+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 NO_ERROR;
+
+ status_t ret = NO_INIT;
+ char dev_name[64];
+ snprintf(dev_name, 64, FB_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;
+}
+
+void Display::closeDisplay() {
+ close(mFD);
+ mFD = NO_INIT;
+}
+
+Rotator::Rotator() : mFD(NO_INIT), mSessionID(NO_INIT), mPmemFD(NO_INIT)
+{
+ mAlloc = gralloc::IAllocController::getInstance(false);
+}
+
+Rotator::~Rotator()
+{
+ closeRotSession();
+}
+
+status_t Rotator::startRotSession(msm_rotator_img_info& rotInfo,
+ int size, int numBuffers) {
+ status_t ret = NO_ERROR;
+ 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 (ioctl(mFD, MSM_ROTATOR_IOCTL_START, &rotInfo)) {
+ close(mFD);
+ mFD = NO_INIT;
+ return NO_INIT;
+ }
+
+ mSessionID = rotInfo.session_id;
+ alloc_data data;
+ data.base = 0;
+ data.fd = -1;
+ data.offset = 0;
+ data.size = mSize * mNumBuffers;
+ data.align = getpagesize();
+ data.uncached = true;
+
+ int allocFlags = GRALLOC_USAGE_PRIVATE_MM_HEAP |
+ GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP |
+ GRALLOC_USAGE_PRIVATE_ADSP_HEAP |
+ GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
+ GRALLOC_USAGE_PRIVATE_SMI_HEAP |
+ GRALLOC_USAGE_PRIVATE_DO_NOT_MAP;
+
+ int err = mAlloc->allocate(data, allocFlags, 0);
+
+ if(err) {
+ LOGE("%s: Can't allocate rotator memory", __func__);
+ closeRotSession();
+ return NO_INIT;
+ }
+ mPmemFD = data.fd;
+ mPmemAddr = data.base;
+ mBufferType = data.allocType;
+
+ 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);
+ if (NO_INIT != mPmemFD) {
+ sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
+ memalloc->free_buffer(mPmemAddr, mSize * mNumBuffers, 0, mPmemFD);
+ 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;
+}
+
+//===================== OverlayUI =================//
+
+OverlayUI::OverlayUI() : mChannelState(CLOSED), mOrientation(NO_INIT),
+ mFBNum(NO_INIT), mZorder(NO_INIT), mWaitForVsync(false), mIsFg(false),
+ mSessionID(NO_INIT), mParamsChanged(false) {
+ memset(&mOvInfo, 0, sizeof(mOvInfo));
+ memset(&mRotInfo, 0, sizeof(mRotInfo));
+}
+
+OverlayUI::~OverlayUI() {
+ closeChannel();
+}
+
+void OverlayUI::setSource(const overlay_buffer_info& info, int orientation) {
+ status_t ret = NO_INIT;
+ int format3D = FORMAT_3D(info.format);
+ int colorFormat = COLOR_FORMAT(info.format);
+ int format = get_mdp_format(colorFormat);
+
+ if (format3D || !isRGBType(format)) {
+ LOGE("%s: Unsupported format", __func__);
+ return;
+ }
+
+ mParamsChanged |= (mSource.width ^ info.width) ||
+ (mSource.height ^ info.height) ||
+ (mSource.format ^ format) ||
+ (mSource.size ^ info.size) ||
+ (mOrientation ^ orientation);
+
+ mSource.width = info.width;
+ mSource.height = info.height;
+ mSource.format = format;
+ mSource.size = info.size;
+ mOrientation = orientation;
+ setupOvRotInfo();
+}
+
+void OverlayUI::setDisplayParams(int fbNum, bool waitForVsync, bool isFg, int
+ zorder, bool isVGPipe) {
+ int flags = 0;
+
+ if(false == waitForVsync)
+ flags |= MDP_OV_PLAY_NOWAIT;
+ else
+ flags &= ~MDP_OV_PLAY_NOWAIT;
+
+ if(isVGPipe)
+ flags |= MDP_OV_PIPE_SHARE;
+ else
+ flags &= ~MDP_OV_PIPE_SHARE;
+
+ if (turnOFFVSync())
+ flags |= MDP_OV_PLAY_NOWAIT;
+
+ mParamsChanged |= (mFBNum ^ fbNum) ||
+ (mOvInfo.is_fg ^ isFg) ||
+ (mOvInfo.flags ^ flags) ||
+ (mOvInfo.z_order ^ zorder);
+
+ mFBNum = fbNum;
+ mOvInfo.is_fg = isFg;
+ mOvInfo.flags = flags;
+ mOvInfo.z_order = zorder;
+
+ mobjDisplay.openDisplay(mFBNum);
+}
+
+void OverlayUI::setPosition(int x, int y, int w, int h) {
+ mParamsChanged |= (mOvInfo.dst_rect.x ^ x) ||
+ (mOvInfo.dst_rect.y ^ y) ||
+ (mOvInfo.dst_rect.w ^ w) ||
+ (mOvInfo.dst_rect.h ^ h);
+
+ mOvInfo.dst_rect.x = x;
+ mOvInfo.dst_rect.y = y;
+ mOvInfo.dst_rect.w = w;
+ mOvInfo.dst_rect.h = h;
+}
+
+void OverlayUI::setCrop(int x, int y, int w, int h) {
+ mParamsChanged |= (mOvInfo.src_rect.x ^ x) ||
+ (mOvInfo.src_rect.y ^ y) ||
+ (mOvInfo.src_rect.w ^ w) ||
+ (mOvInfo.src_rect.h ^ h);
+
+ mOvInfo.src_rect.x = x;
+ mOvInfo.src_rect.y = y;
+ mOvInfo.src_rect.w = w;
+ mOvInfo.src_rect.h = h;
+}
+
+void OverlayUI::setupOvRotInfo() {
+ int w = mSource.width;
+ int h = mSource.height;
+ int format = mSource.format;
+ int srcw = (w + 31) & ~31;
+ int srch = (h + 31) & ~31;
+ mOvInfo.src.width = srcw;
+ mOvInfo.src.height = srch;
+ mOvInfo.src.format = format;
+ mOvInfo.src_rect.w = w;
+ mOvInfo.src_rect.h = h;
+ mOvInfo.alpha = 0xff;
+ mOvInfo.transp_mask = 0xffffffff;
+ mRotInfo.src.format = format;
+ mRotInfo.dst.format = format;
+ mRotInfo.src.width = srcw;
+ mRotInfo.src.height = srch;
+ mRotInfo.src_rect.w = srcw;
+ mRotInfo.src_rect.h = srch;
+ mRotInfo.dst.width = srcw;
+ mRotInfo.dst.height = srch;
+
+ int rot = mOrientation;
+ switch(rot) {
+ case 0:
+ case HAL_TRANSFORM_FLIP_H:
+ case HAL_TRANSFORM_FLIP_V:
+ rot = 0;
+ 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 = mOvInfo.src_rect.x;
+ mOvInfo.src_rect.x = mOvInfo.src.height -
+ (mOvInfo.src_rect.y + mOvInfo.src_rect.h);
+ mOvInfo.src_rect.y = tmp;
+ swapOVRotWidthHeight(mRotInfo, mOvInfo);
+ rot = HAL_TRANSFORM_ROT_90;
+ break;
+ }
+ case HAL_TRANSFORM_ROT_180:
+ break;
+ case HAL_TRANSFORM_ROT_270: {
+ int tmp = mOvInfo.src_rect.y;
+ mOvInfo.src_rect.y = mOvInfo.src.width -
+ (mOvInfo.src_rect.x + mOvInfo.src_rect.w);
+ mOvInfo.src_rect.x = tmp;
+ swapOVRotWidthHeight(mRotInfo, mOvInfo);
+ break;
+ }
+ default:
+ break;
+ }
+ int mdp_rotation = overlay::get_mdp_orientation(rot);
+ if (mdp_rotation < 0)
+ mdp_rotation = 0;
+ mOvInfo.user_data[0] = mdp_rotation;
+ mRotInfo.rotations = mOvInfo.user_data[0];
+ if (mdp_rotation)
+ mRotInfo.enable = 1;
+}
+
+status_t OverlayUI::commit() {
+ status_t ret = BAD_VALUE;
+ if(mChannelState != UP)
+ mOvInfo.id = MSMFB_NEW_REQUEST;
+ ret = startOVSession();
+ if (ret == NO_ERROR && mOrientation) {
+ ret = mobjRotator.startRotSession(mRotInfo, mSource.size);
+ }
+ if (ret == NO_ERROR) {
+ mChannelState = UP;
+ } else {
+ LOGE("start channel failed.");
+ }
+ return ret;
+}
+
+status_t OverlayUI::closeChannel() {
+ if( mChannelState != UP ) {
+ return NO_ERROR;
+ }
+ if(NO_ERROR != closeOVSession()) {
+ LOGE("%s: closeOVSession() failed.", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ if(NO_ERROR != mobjRotator.closeRotSession()) {
+ LOGE("%s: closeRotSession() failed.", __FUNCTION__);
+ return BAD_VALUE;
+ }
+ mChannelState = CLOSED;
+ mParamsChanged = false;
+ memset(&mOvInfo, 0, sizeof(mOvInfo));
+ memset(&mRotInfo, 0, sizeof(mRotInfo));
+ return NO_ERROR;
+}
+
+status_t OverlayUI::startOVSession() {
+ status_t ret = NO_INIT;
+ ret = mobjDisplay.openDisplay(mFBNum);
+
+ if (ret != NO_ERROR)
+ return ret;
+
+ if(mParamsChanged) {
+ mParamsChanged = false;
+ mdp_overlay ovInfo = mOvInfo;
+ if (ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_SET, &ovInfo)) {
+ LOGE("Overlay set failed..");
+ ret = BAD_VALUE;
+ } else {
+ mSessionID = ovInfo.id;
+ mOvInfo = ovInfo;
+ ret = NO_ERROR;
+ }
+ }
+ return ret;
+}
+
+status_t OverlayUI::closeOVSession() {
+ status_t ret = NO_ERROR;
+ int err = 0;
+ if(err = ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_UNSET, &mSessionID)) {
+ LOGE("%s: MSMFB_OVERLAY_UNSET failed. (%d)", __FUNCTION__, err);
+ ret = BAD_VALUE;
+ } else {
+ mobjDisplay.closeDisplay();
+ mSessionID = NO_INIT;
+ }
+ 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;
+ }
+ ovData.id = mSessionID;
+ if (ioctl(mobjDisplay.getFD(), MSMFB_OVERLAY_PLAY, &ovData)) {
+ LOGE("Queuebuffer failed ");
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+};