diff options
author | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-04-04 15:16:50 +0100 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2013-04-06 00:34:54 +0100 |
commit | c962bf8b8fa4d9a6400811296fb270f47db68cf4 (patch) | |
tree | f5e651935cbbf54e6d1488bbe19a6e2a4599a070 | |
parent | 7a8a513ac8a2b9a76b36cf1341d45b00d88ed45c (diff) | |
parent | 6445344dbaf08ec4d8fbf6aeeffdf29faed64e78 (diff) | |
download | android_hardware_qcom_display-cm-10.1.tar.gz android_hardware_qcom_display-cm-10.1.tar.bz2 android_hardware_qcom_display-cm-10.1.zip |
Merge remote-tracking branch 'aosp/jb-mr1.1-release' into cm-10.1cm-10.1.3-RC2cm-10.1.3-RC1cm-10.1.3cm-10.1.2cm-10.1.1cm-10.1.0-RC5cm-10.1.0-RC4cm-10.1.0-RC3cm-10.1.0-RC2cm-10.1.0-RC1cm-10.1.0cm-10.1-M3cm-10.1
Change-Id: I44a10eaa285d0521669781a4fafb7641df209186
48 files changed, 1573 insertions, 4325 deletions
@@ -21,6 +21,12 @@ common_libs := liblog libutils libcutils libhardware common_flags := -DDEBUG_CALC_FPS -Wno-missing-field-initializers common_flags += -Werror +#TODO +#ifeq ($(call is-vendor-board-platform,QCOM),true) +ifeq ($(TARGET_BOARD_PLATFORM), msm8960) + common_flags += -DUSE_FENCE_SYNC +endif + ifeq ($(ARCH_ARM_HAVE_NEON),true) common_flags += -D__ARM_HAVE_NEON endif diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp index d6c6c3bd4..365be5f3d 100644 --- a/libcopybit/copybit_c2d.cpp +++ b/libcopybit/copybit_c2d.cpp @@ -1170,14 +1170,7 @@ static int stretch_copybit_internal( src_image.handle = src_hnd; // Copy the source. - status = copy_image((private_handle_t *)src->handle, &src_image, - CONVERT_TO_C2D_FORMAT); - if (status == COPYBIT_FAILURE) { - ALOGE("%s:copy_image failed in temp source",__FUNCTION__); - delete_handle(dst_hnd); - delete_handle(src_hnd); - return status; - } + copy_image((private_handle_t *)src->handle, &src_image, CONVERT_TO_C2D_FORMAT); // Flush the cache IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags); @@ -1249,13 +1242,7 @@ static int stretch_copybit_internal( trg_mapped); if (needTempDestination) { // copy the temp. destination without the alignment to the actual destination. - status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT); - if (status == COPYBIT_FAILURE) { - ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__); - delete_handle(dst_hnd); - delete_handle(src_hnd); - return status; - } + copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT); // Invalidate the cache. IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags); memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size, diff --git a/libexternal/external.cpp b/libexternal/external.cpp index f00d551d7..26485606a 100644 --- a/libexternal/external.cpp +++ b/libexternal/external.cpp @@ -445,13 +445,18 @@ bool ExternalDisplay::writeHPDOption(int userOption) const */ bool ExternalDisplay::post() { - if(mFd == -1) { + if(mFd == -1) return false; - } else if(ioctl(mFd, MSMFB_OVERLAY_COMMIT, &mExternalDisplay) == -1) { - ALOGE("%s: MSMFB_OVERLAY_COMMIT failed, str: %s", __FUNCTION__, - strerror(errno)); + + struct mdp_display_commit ext_commit; + memset(&ext_commit, 0, sizeof(ext_commit)); + ext_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY; + if (ioctl(mFd, MSMFB_DISPLAY_COMMIT, &ext_commit) == -1) { + ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s", + __FUNCTION__, strerror(errno)); return false; } + return true; } diff --git a/libgenlock/Android.mk b/libgenlock/Android.mk index 92ac22792..72dc6c515 100644 --- a/libgenlock/Android.mk +++ b/libgenlock/Android.mk @@ -7,6 +7,9 @@ LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := $(common_includes) LOCAL_SHARED_LIBRARIES := liblog libcutils LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"libgenlock\" +ifneq ($(TARGET_BOARD_PLATFORM), msm8960) + LOCAL_CFLAGS += -DUSE_GENLOCK +endif LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := genlock.cpp include $(BUILD_SHARED_LIBRARY) diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp index e4d1d689d..6bc23de25 100644 --- a/libgralloc/alloc_controller.cpp +++ b/libgralloc/alloc_controller.cpp @@ -29,7 +29,7 @@ #include <cutils/log.h> #include <fcntl.h> -#include "gralloc_priv.h" +#include <gralloc_priv.h> #include "alloc_controller.h" #include "memalloc.h" #include "ionalloc.h" diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp index 8e400224a..948cf1961 100644 --- a/libgralloc/framebuffer.cpp +++ b/libgralloc/framebuffer.cpp @@ -36,7 +36,7 @@ #include <GLES/gl.h> -#include "gralloc_priv.h" +#include <gralloc_priv.h> #include "fb_priv.h" #include "gr.h" #include <genlock.h> @@ -108,10 +108,11 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) private_module_t* m = reinterpret_cast<private_module_t*>(dev->common.module); - if (hnd && hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { + if (hnd) { m->info.activate = FB_ACTIVATE_VBL | FB_ACTIVATE_FORCE; m->info.yoffset = hnd->offset / m->finfo.line_length; m->commit.var = m->info; + m->commit.flags |= MDP_DISPLAY_COMMIT_OVERLAY; if (ioctl(m->framebuffer->fd, MSMFB_DISPLAY_COMMIT, &m->commit) == -1) { ALOGE("%s: MSMFB_DISPLAY_COMMIT ioctl failed, err: %s", __FUNCTION__, strerror(errno)); @@ -124,6 +125,7 @@ static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) static int fb_compositionComplete(struct framebuffer_device_t* dev) { // TODO: Properly implement composition complete callback + glFinish(); return 0; } diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp index ed4394aa3..c2382649c 100644 --- a/libgralloc/gpu.cpp +++ b/libgralloc/gpu.cpp @@ -229,16 +229,9 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage, (usage & GRALLOC_USAGE_PRIVATE_CP_BUFFER)) { bufferType = BUFFER_TYPE_VIDEO; } - int err; - private_module_t* m = reinterpret_cast<private_module_t*>(common.module); - uint32_t bufferMask = m->bufferMask; - uint32_t numBuffers = m->numBuffers; - if (usage & GRALLOC_USAGE_HW_FB && (bufferMask < ((1LU << numBuffers) - 1))) { - err = gralloc_alloc_framebuffer(size, usage, pHandle); - } else { - err = gralloc_alloc_buffer(size, usage, pHandle, bufferType, - grallocFormat, alignedw, alignedh); - } + + int err = gralloc_alloc_buffer(size, usage, pHandle, bufferType, + grallocFormat, alignedw, alignedh); if (err < 0) { return err; diff --git a/libgralloc/gpu.h b/libgralloc/gpu.h index 2920d5f5e..e4180f93b 100644 --- a/libgralloc/gpu.h +++ b/libgralloc/gpu.h @@ -26,7 +26,7 @@ #include <cutils/log.h> #include <cutils/ashmem.h> -#include "gralloc_priv.h" +#include <gralloc_priv.h> #include <fb_priv.h> namespace gralloc { diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp index e01e3dfd7..76db49e8c 100644 --- a/libgralloc/ionalloc.cpp +++ b/libgralloc/ionalloc.cpp @@ -34,7 +34,7 @@ #include <fcntl.h> #include <cutils/log.h> #include <errno.h> -#include "gralloc_priv.h" +#include <gralloc_priv.h> #include "ionalloc.h" using gralloc::IonAlloc; @@ -126,8 +126,6 @@ int IonAlloc::alloc_buffer(alloc_data& data) ALOGE("%s: Failed to map the allocated memory: %s", __FUNCTION__, strerror(errno)); ioctl(mIonFd, ION_IOC_FREE, &handle_data); - if(ionSyncFd >= 0) - close(ionSyncFd); ionSyncFd = FD_INIT; return err; } diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp index 3088ecc72..4e33d86dd 100644 --- a/libgralloc/mapper.cpp +++ b/libgralloc/mapper.cpp @@ -38,7 +38,7 @@ #include <linux/android_pmem.h> -#include "gralloc_priv.h" +#include <gralloc_priv.h> #include "gr.h" #include "alloc_controller.h" #include "memalloc.h" diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk index 08347d8e0..24fd2d454 100644 --- a/libhwcomposer/Android.mk +++ b/libhwcomposer/Android.mk @@ -7,7 +7,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes) LOCAL_SHARED_LIBRARIES := $(common_libs) libEGL liboverlay libgenlock \ libexternal libqdutils libhardware_legacy \ - libdl libmemalloc libqservice libGLESv1_CM + libdl libmemalloc libqservice LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"hwcomposer\" LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) @@ -16,7 +16,7 @@ LOCAL_SRC_FILES := hwc.cpp \ hwc_utils.cpp \ hwc_uevents.cpp \ hwc_vsync.cpp \ + hwc_fbupdate.cpp \ hwc_mdpcomp.cpp \ - hwc_uimirror.cpp \ include $(BUILD_SHARED_LIBRARY) diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp index 62cf16d7e..830c067c4 100644 --- a/libhwcomposer/hwc.cpp +++ b/libhwcomposer/hwc.cpp @@ -27,12 +27,12 @@ #include <mdp_version.h> #include "hwc_utils.h" #include "hwc_video.h" -#include "hwc_uimirror.h" -#include "external.h" +#include "hwc_fbupdate.h" #include "hwc_mdpcomp.h" +#include "external.h" -#define VSYNC_DEBUG 0 using namespace qhwc; +#define VSYNC_DEBUG 0 static int hwc_device_open(const struct hw_module_t* module, const char* name, @@ -77,11 +77,38 @@ static void hwc_registerProcs(struct hwc_composer_device_1* dev, } //Helper -static void reset(hwc_context_t *ctx, int numDisplays) { +static void reset(hwc_context_t *ctx, int numDisplays, + hwc_display_contents_1_t** displays) { memset(ctx->listStats, 0, sizeof(ctx->listStats)); for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){ - ctx->overlayInUse[i] = false; ctx->listStats[i].yuvIndex = -1; + hwc_display_contents_1_t *list = displays[i]; + // XXX:SurfaceFlinger no longer guarantees that this + // value is reset on every prepare. However, for the layer + // cache we need to reset it. + // We can probably rethink that later on + if (LIKELY(list && list->numHwLayers > 1)) { + for(uint32_t j = 0; j < list->numHwLayers; j++) { + if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET) + list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; + } + } + } + VideoOverlay::reset(); + FBUpdate::reset(); +} + +//clear prev layer prop flags and realloc for current frame +static void reset_layer_prop(hwc_context_t* ctx, int dpy) { + int layer_count = ctx->listStats[dpy].numAppLayers; + + if(ctx->layerProp[dpy]) { + delete[] ctx->layerProp[dpy]; + ctx->layerProp[dpy] = NULL; + } + + if(layer_count) { + ctx->layerProp[dpy] = new LayerProp[layer_count]; } } @@ -96,13 +123,12 @@ static int hwc_prepare_primary(hwc_composer_device_1 *dev, hwc_layer_1_t *fbLayer = &list->hwLayers[last]; if(fbLayer->handle) { setListStats(ctx, list, HWC_DISPLAY_PRIMARY); - if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY)) { - ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true; - } else if(MDPComp::configure(ctx, list)) { - ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true; - } else { - ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = false; + reset_layer_prop(ctx, HWC_DISPLAY_PRIMARY); + if(!MDPComp::configure(ctx, list)) { + VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY); + FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_PRIMARY); } + ctx->mLayerCache[HWC_DISPLAY_PRIMARY]->updateLayerCache(list); } } return 0; @@ -116,21 +142,15 @@ static int hwc_prepare_external(hwc_composer_device_1 *dev, ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive && ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) { - setListStats(ctx, list, HWC_DISPLAY_EXTERNAL); - uint32_t last = list->numHwLayers - 1; hwc_layer_1_t *fbLayer = &list->hwLayers[last]; if(fbLayer->handle) { - if(UIMirrorOverlay::prepare(ctx, fbLayer)) { - ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true; - } + setListStats(ctx, list, HWC_DISPLAY_EXTERNAL); + reset_layer_prop(ctx, HWC_DISPLAY_EXTERNAL); - if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL)) { - ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true; - } else { - ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->setState( - ovutils::OV_UI_MIRROR); - } + VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL); + FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL); + ctx->mLayerCache[HWC_DISPLAY_EXTERNAL]->updateLayerCache(list); } } return 0; @@ -141,29 +161,27 @@ static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, { int ret = 0; hwc_context_t* ctx = (hwc_context_t*)(dev); - reset(ctx, numDisplays); + Locker::Autolock _l(ctx->mBlankLock); + reset(ctx, numDisplays, displays); - //If securing of h/w in progress skip comp using overlay. - if(ctx->mSecuring == true) return 0; + ctx->mOverlay->configBegin(); - for (uint32_t i = 0; i < numDisplays; i++) { + for (int32_t i = numDisplays - 1; i >= 0; i--) { hwc_display_contents_1_t *list = displays[i]; - if(list && list->numHwLayers) { - uint32_t last = list->numHwLayers - 1; - if(list->hwLayers[last].handle != NULL) { - switch(i) { - case HWC_DISPLAY_PRIMARY: - ret = hwc_prepare_primary(dev, list); - break; - case HWC_DISPLAY_EXTERNAL: - ret = hwc_prepare_external(dev, list); - break; - default: - ret = -EINVAL; - } - } + switch(i) { + case HWC_DISPLAY_PRIMARY: + ret = hwc_prepare_primary(dev, list); + break; + case HWC_DISPLAY_EXTERNAL: + + ret = hwc_prepare_external(dev, list); + break; + default: + ret = -EINVAL; } } + ctx->mOverlay->configDone(); + return ret; } @@ -197,13 +215,14 @@ static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank) hwc_context_t* ctx = (hwc_context_t*)(dev); private_module_t* m = reinterpret_cast<private_module_t*>( ctx->mFbDev->common.module); + Locker::Autolock _l(ctx->mBlankLock); int ret = 0; ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank); switch(dpy) { case HWC_DISPLAY_PRIMARY: if(blank) { - Locker::Autolock _l(ctx->mBlankLock); - ctx->mOverlay[dpy]->setState(ovutils::OV_CLOSED); + ctx->mOverlay->configBegin(); + ctx->mOverlay->configDone(); ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN); } else { ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK); @@ -267,18 +286,25 @@ static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { hwc_layer_1_t *fbLayer = &list->hwLayers[last]; hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY); - if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) { ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__); ret = -1; } - if (MDPComp::draw(ctx, list)) { + if (!MDPComp::draw(ctx, list)) { ALOGE("%s: MDPComp::draw fail!", __FUNCTION__); ret = -1; } + //TODO We dont check for SKIP flag on this layer because we need PAN //always. Last layer is always FB - if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET) { + private_handle_t *hnd = (private_handle_t *)fbLayer->handle; + if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) { + if(!(fbLayer->flags & HWC_SKIP_LAYER)) { + if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_PRIMARY)) { + ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); + ret = -1; + } + } if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) { ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__); return -1; @@ -309,8 +335,8 @@ static int hwc_set_external(hwc_context_t *ctx, private_handle_t *hnd = (private_handle_t *)fbLayer->handle; if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && !(fbLayer->flags & HWC_SKIP_LAYER) && hnd) { - if (!UIMirrorOverlay::draw(ctx, fbLayer)) { - ALOGE("%s: UIMirrorOverlay::draw fail!", __FUNCTION__); + if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_EXTERNAL)) { + ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); ret = -1; } } @@ -330,11 +356,6 @@ static int hwc_set(hwc_composer_device_1 *dev, hwc_context_t* ctx = (hwc_context_t*)(dev); Locker::Autolock _l(ctx->mBlankLock); - for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) { - if(!ctx->overlayInUse[i]) - ctx->mOverlay[i]->setState(ovutils::OV_CLOSED); - } - for (uint32_t i = 0; i < numDisplays; i++) { hwc_display_contents_1_t* list = displays[i]; switch(i) { diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp index 04db814d8..1249e842a 100644 --- a/libhwcomposer/hwc_copybit.cpp +++ b/libhwcomposer/hwc_copybit.cpp @@ -21,10 +21,9 @@ #define DEBUG_COPYBIT 0 #include <copybit.h> #include <genlock.h> -#include <GLES/gl.h> +#include "hwc_copybit.h" #include "hwc_copybit.h" #include "comptype.h" -#include "egl_handles.h" namespace qhwc { @@ -66,11 +65,46 @@ private: mutable range r; }; +// Initialize CopyBit Class Static Mmembers. +functype_eglGetRenderBufferANDROID CopyBit::LINK_eglGetRenderBufferANDROID + = NULL; +functype_eglGetCurrentSurface CopyBit::LINK_eglGetCurrentSurface = NULL; int CopyBit::sYuvCount = 0; int CopyBit::sYuvLayerIndex = -1; bool CopyBit::sIsModeOn = false; bool CopyBit::sIsLayerSkip = false; -bool CopyBit::sCopyBitDraw = false; +void* CopyBit::egl_lib = NULL; + +void CopyBit::openEglLibAndGethandle() +{ + egl_lib = ::dlopen("libEGL_adreno200.so", RTLD_GLOBAL | RTLD_LAZY); + if (!egl_lib) { + return; + } + updateEglHandles(egl_lib); +} +void CopyBit::closeEglLib() +{ + if(egl_lib) + ::dlclose(egl_lib); + + egl_lib = NULL; + updateEglHandles(NULL); +} + +void CopyBit::updateEglHandles(void* egl_lib) +{ + if(egl_lib != NULL) { + *(void **)&CopyBit::LINK_eglGetRenderBufferANDROID = + ::dlsym(egl_lib, "eglGetRenderBufferANDROID"); + *(void **)&CopyBit::LINK_eglGetCurrentSurface = + ::dlsym(egl_lib, "eglGetCurrentSurface"); + }else { + LINK_eglGetCurrentSurface = NULL; + LINK_eglGetCurrentSurface = NULL; + } +} + bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) { // return true for non-overlay targets if(ctx->mMDP.hasOverlay) { @@ -83,7 +117,8 @@ bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx, hwc_display_contents_1_t * int compositionType = qdutils::QCCompositionType::getInstance().getCompositionType(); - if (compositionType & qdutils::COMPOSITION_TYPE_C2D){ + if ((compositionType & qdutils::COMPOSITION_TYPE_C2D) || + (compositionType & qdutils::COMPOSITION_TYPE_DYN)) { if (sYuvCount) { //Overlay up & running. Dont use COPYBIT for RGB layers. // TODO need to implement blending with C2D @@ -153,7 +188,7 @@ bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) { ALOGE("%s:Invalid Params", __FUNCTION__); return false; } - sCopyBitDraw = false; + for (int i=list->numHwLayers-1; i >= 0 ; i--) { private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle; @@ -163,13 +198,11 @@ bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) { //YUV layer, check, if copybit can be used if (useCopybitForYUV) { list->hwLayers[i].compositionType = HWC_USE_COPYBIT; - sCopyBitDraw = true; } } else if (hnd->bufferType == BUFFER_TYPE_UI) { //RGB layer, check, if copybit can be used if (useCopybitForRGB) { list->hwLayers[i].compositionType = HWC_USE_COPYBIT; - sCopyBitDraw = true; } } } @@ -180,24 +213,6 @@ bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, EGLDispla EGLSurface sur){ // draw layers marked for COPYBIT int retVal = true; - - if(sCopyBitDraw == false) // there is no any layer marked for copybit - return true ; - - android_native_buffer_t *renderBuffer = - qdutils::eglHandles::getInstance().getAndroidNativeRenderBuffer(dpy); - if (!renderBuffer) { - ALOGE("%s: eglGetRenderBufferANDROID returned NULL buffer", - __FUNCTION__); - return -1; - } - - // Invoke a glFinish if we are rendering any layers using copybit. - // We call glFinish instead of locking the renderBuffer because the - // GPU could take longer than the genlock timeout value to complete - // rendering - glFinish(); - for (size_t i=0; i<list->numHwLayers; i++) { if (list->hwLayers[i].compositionType == HWC_USE_COPYBIT) { retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]), @@ -469,6 +484,13 @@ bool CopyBit::validateParams(hwc_context_t *ctx, const hwc_display_contents_1_t ALOGE("%s:Invalid FB device", __FUNCTION__); return false; } + + if (LINK_eglGetRenderBufferANDROID == NULL || + LINK_eglGetCurrentSurface == NULL) { + ALOGE("%s:Not able to link to ADRENO", __FUNCTION__); + return false; + } + return true; } diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h index f371abb49..ae82b6c13 100644 --- a/libhwcomposer/hwc_copybit.h +++ b/libhwcomposer/hwc_copybit.h @@ -30,6 +30,11 @@ #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) namespace qhwc { +//Feature for using Copybit to display RGB layers. +typedef EGLClientBuffer (*functype_eglGetRenderBufferANDROID) ( + EGLDisplay dpy, + EGLSurface draw); +typedef EGLSurface (*functype_eglGetCurrentSurface)(EGLint readdraw); class CopyBit { public: @@ -67,8 +72,11 @@ private: static bool sIsLayerSkip; //Flags if this feature is on. static bool sIsModeOn; - // flag that indicates whether CopyBit is enabled or not - static bool sCopyBitDraw; + //handle for adreno lib + static void* egl_lib; + + static functype_eglGetRenderBufferANDROID LINK_eglGetRenderBufferANDROID; + static functype_eglGetCurrentSurface LINK_eglGetCurrentSurface; static unsigned int getRGBRenderingArea (const hwc_display_contents_1_t *list); diff --git a/libhwcomposer/hwc_extonly.cpp b/libhwcomposer/hwc_extonly.cpp deleted file mode 100644 index 3be9d81d2..000000000 --- a/libhwcomposer/hwc_extonly.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * Copyright (C) 2012, The Linux Foundation. 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 "hwc_extonly.h" -#include "external.h" - -namespace qhwc { - -#define EXTONLY_DEBUG 0 - -//Static Members -ovutils::eOverlayState ExtOnly::sState = ovutils::OV_CLOSED; -int ExtOnly::sExtCount = 0; -int ExtOnly::sExtIndex = -1; -bool ExtOnly::sIsExtBlock = false; -bool ExtOnly::sIsModeOn = false; - -//Cache stats, figure out the state, config overlay -bool ExtOnly::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) { - sIsModeOn = false; - if(!ctx->mMDP.hasOverlay) { - ALOGD_IF(EXTONLY_DEBUG,"%s, this hw doesnt support overlay", - __FUNCTION__); - return false; - } - if(sExtIndex == -1) { - return false; - } - chooseState(ctx); - //if the state chosen above is CLOSED, skip this block. - if(sState != ovutils::OV_CLOSED) { - hwc_layer_1_t *extLayer = &list->hwLayers[sExtIndex]; - if(configure(ctx, extLayer)) { - markFlags(extLayer); - sIsModeOn = true; - } - } - - ALOGD_IF(EXTONLY_DEBUG, "%s: stats: extCount = %d, extIndex = %d," - "IsExtBlock = %d, IsModeOn = %d", - __func__, sExtCount, sExtIndex, - sIsExtBlock, sIsModeOn); - - return sIsModeOn; -} - -void ExtOnly::chooseState(hwc_context_t *ctx) { - ALOGD_IF(EXTONLY_DEBUG, "%s: old state = %s", __FUNCTION__, - ovutils::getStateString(sState)); - - ovutils::eOverlayState newState = ovutils::OV_CLOSED; - - if(sExtCount > 0 && - ctx->mExtDisplay->getExternalDisplay()) { - newState = ovutils::OV_DUAL_DISP; - } - - sState = newState; - ALOGD_IF(EXTONLY_DEBUG, "%s: new chosen state = %s", __FUNCTION__, - ovutils::getStateString(sState)); -} - -void ExtOnly::markFlags(hwc_layer_1_t *layer) { - switch(sState) { - case ovutils::OV_DUAL_DISP: - layer->compositionType = HWC_OVERLAY; - break; - default: - break; - } -} - -bool ExtOnly::configure(hwc_context_t *ctx, hwc_layer_1_t *layer) { - - overlay::Overlay& ov = *(ctx->mOverlay); - ov.setState(sState); - private_handle_t *hnd = (private_handle_t *)layer->handle; - ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); - ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF; - ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; - ovutils::PipeArgs parg(mdpFlags, - info, - ovutils::ZORDER_0, - isFgFlag, - ovutils::ROT_FLAG_DISABLED); - ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; - ov.setSource(pargs, ovutils::OV_PIPE0); - - hwc_rect_t sourceCrop = layer->sourceCrop; - // x,y,w,h - ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, - sourceCrop.right - sourceCrop.left, - sourceCrop.bottom - sourceCrop.top); - ov.setCrop(dcrop, ovutils::OV_PIPE0); - - ov.setTransform(0, ovutils::OV_PIPE0); - - //Setting position same as crop - //FIXME stretch to full screen - ov.setPosition(dcrop, ovutils::OV_PIPE0); - - if (!ov.commit(ovutils::OV_PIPE0)) { - ALOGE("%s: commit fails", __FUNCTION__); - return false; - } - return true; -} - -bool ExtOnly::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) -{ - if(!sIsModeOn || sExtIndex == -1) { - return true; - } - - private_handle_t *hnd = (private_handle_t *) - list->hwLayers[sExtIndex].handle; - - bool ret = true; - overlay::Overlay& ov = *(ctx->mOverlay); - ovutils::eOverlayState state = ov.getState(); - - switch (state) { - case ovutils::OV_DUAL_DISP: - // Play external - if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) { - ALOGE("%s: queueBuffer failed for external", __FUNCTION__); - ret = false; - } - break; - default: - ALOGE("%s Unused state %s", __FUNCTION__, - ovutils::getStateString(state)); - break; - } - - return ret; -} - -}; //namespace qhwc diff --git a/libhwcomposer/hwc_extonly.h b/libhwcomposer/hwc_extonly.h deleted file mode 100644 index dccd0652c..000000000 --- a/libhwcomposer/hwc_extonly.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * Copyright (C) 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. - */ -#ifndef HWC_EXTONLY_H -#define HWC_EXTONLY_H - -#include <overlay.h> -#include "hwc_utils.h" - -#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) -#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) - -namespace qhwc { -//Feature for using overlay to display external-only layers on HDTV -class ExtOnly { -public: - //Sets up members and prepares overlay if conditions are met - static bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list); - //Draws layer if this feature is on - static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list); - //Receives data from hwc - static void setStats(int extCount, int extIndex, bool isExtBlock); - //resets values - static void reset(); -private: - //Choose an appropriate overlay state based on conditions - static void chooseState(hwc_context_t *ctx); - //Configures overlay - static bool configure(hwc_context_t *ctx, hwc_layer_1_t *layer); - //Marks layer flags if this feature is used - static void markFlags(hwc_layer_1_t *layer); - //returns ext-only count - static int getExtCount(); - - //The chosen overlay state. - static ovutils::eOverlayState sState; - //Number of ext-only layers in this drawing round. Used for stats/debugging. - //This does not reflect the closed caption layer count even though its - //ext-only. - static int sExtCount; - //Index of ext-only layer. If there are 2 such layers with 1 marked as BLOCK - //then this will hold the index of BLOCK layer. - static int sExtIndex; - //Flags if ext-only layer is BLOCK, which means only this layer (sExtIndex) - //is displayed even if other ext-only layers are present to block their - //content. This is used for stats / debugging only. - static bool sIsExtBlock; - //Flags if this feature is on. - static bool sIsModeOn; -}; - -inline void ExtOnly::setStats(int extCount, int extIndex, bool isExtBlock) { - sExtCount = extCount; - sExtIndex = extIndex; - sIsExtBlock = isExtBlock; -} - -inline int ExtOnly::getExtCount() { return sExtCount; } -inline void ExtOnly::reset() { - sExtCount = 0; - sExtIndex = -1; - sIsExtBlock = false; - sIsModeOn = false; - sState = ovutils::OV_CLOSED; -} - -}; //namespace qhwc - -#endif //HWC_EXTONLY_H diff --git a/libhwcomposer/hwc_uimirror.cpp b/libhwcomposer/hwc_fbupdate.cpp index dd96efe39..0d0787ec5 100644 --- a/libhwcomposer/hwc_uimirror.cpp +++ b/libhwcomposer/hwc_fbupdate.cpp @@ -18,58 +18,58 @@ * limitations under the License. */ -#define HWC_UI_MIRROR 0 +#define HWC_FB_UPDATE 0 #include <gralloc_priv.h> #include <fb_priv.h> -#include "hwc_uimirror.h" +#include "hwc_fbupdate.h" #include "external.h" namespace qhwc { -//Static Members -ovutils::eOverlayState UIMirrorOverlay::sState = ovutils::OV_CLOSED; -bool UIMirrorOverlay::sIsUiMirroringOn = false; +namespace ovutils = overlay::utils; -void UIMirrorOverlay::reset() { - sIsUiMirroringOn = false; - sState = ovutils::OV_CLOSED; +//Static Members +bool FBUpdate::sModeOn[] = {false}; +ovutils::eDest FBUpdate::sDest[] = {ovutils::OV_INVALID}; + +void FBUpdate::reset() { + sModeOn[HWC_DISPLAY_PRIMARY] = false; + sModeOn[HWC_DISPLAY_EXTERNAL] = false; + sDest[HWC_DISPLAY_PRIMARY] = ovutils::OV_INVALID; + sDest[HWC_DISPLAY_EXTERNAL] = ovutils::OV_INVALID; } -//Prepare the overlay for the UI mirroring -bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) { - reset(); - +bool FBUpdate::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy) { if(!ctx->mMDP.hasOverlay) { - ALOGD_IF(HWC_UI_MIRROR, "%s, this hw doesnt support mirroring", + ALOGD_IF(HWC_FB_UPDATE, "%s, this hw doesnt support mirroring", __FUNCTION__); return false; } - sState = ovutils::OV_UI_MIRROR; - ovutils::eOverlayState newState = ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->getState(); - if(newState == ovutils::OV_UI_VIDEO_TV) { - sState = newState; - } + return (sModeOn[dpy] = configure(ctx, fblayer, dpy)); - configure(ctx, fblayer); - return sIsUiMirroringOn; } // Configure -bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *layer) +bool FBUpdate::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy) { - if (LIKELY(ctx->mOverlay[HWC_DISPLAY_EXTERNAL])) { - overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]); - // Set overlay state - ov.setState(sState); + bool ret = false; + if (LIKELY(ctx->mOverlay)) { + overlay::Overlay& ov = *(ctx->mOverlay); private_handle_t *hnd = (private_handle_t *)layer->handle; if (!hnd) { ALOGE("%s:NULL private handle for layer!", __FUNCTION__); return false; } ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); - // Determine the RGB pipe for UI depending on the state - ovutils::eDest dest = ovutils::OV_PIPE0; + + //Request an RGB pipe + ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy); + if(dest == ovutils::OV_INVALID) { //None available + return false; + } + + sDest[dpy] = dest; ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; if(ctx->mSecureMode) { @@ -80,10 +80,9 @@ bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *layer) ovutils::PipeArgs parg(mdpFlags, info, ovutils::ZORDER_0, - ovutils::IS_FG_OFF, + ovutils::IS_FG_SET, ovutils::ROT_FLAG_DISABLED); - ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; - ov.setSource(pargs, dest); + ov.setSource(parg, dest); hwc_rect_t sourceCrop = layer->sourceCrop; // x,y,w,h @@ -104,36 +103,27 @@ bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *layer) displayFrame.bottom - displayFrame.top); ov.setPosition(dpos, dest); + ret = true; if (!ov.commit(dest)) { ALOGE("%s: commit fails", __FUNCTION__); - sIsUiMirroringOn = false; - return false; + ret = false; } - sIsUiMirroringOn = true; } - return sIsUiMirroringOn; + return ret; } -bool UIMirrorOverlay::draw(hwc_context_t *ctx, hwc_layer_1_t *layer) +bool FBUpdate::draw(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy) { - if(!sIsUiMirroringOn) { + if(!sModeOn[dpy]) { return true; } bool ret = true; - overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]); - ovutils::eOverlayState state = ov.getState(); - ovutils::eDest dest = ovutils::OV_PIPE0; + overlay::Overlay& ov = *(ctx->mOverlay); + ovutils::eDest dest = sDest[dpy]; private_handle_t *hnd = (private_handle_t *)layer->handle; - switch (state) { - case ovutils::OV_UI_MIRROR: - case ovutils::OV_UI_VIDEO_TV: - if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) { - ALOGE("%s: queueBuffer failed for external", __FUNCTION__); - ret = false; - } - break; - default: - break; + if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) { + ALOGE("%s: queueBuffer failed for external", __FUNCTION__); + ret = false; } return ret; } diff --git a/libhwcomposer/hwc_uimirror.h b/libhwcomposer/hwc_fbupdate.h index c164d424f..708eb6f9c 100644 --- a/libhwcomposer/hwc_uimirror.h +++ b/libhwcomposer/hwc_fbupdate.h @@ -17,8 +17,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef HWC_UIMIRROR_H -#define HWC_UIMIRROR_H +#ifndef HWC_FBUPDATE_H +#define HWC_FBUPDATE_H #include "hwc_utils.h" #include "overlay.h" @@ -26,24 +26,26 @@ #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) namespace qhwc { -//Feature for Mirroring UI on the External display -class UIMirrorOverlay { +namespace ovutils = overlay::utils; + +//Framebuffer update +class FBUpdate { public: // Sets up members and prepares overlay if conditions are met - static bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer); + static bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy); // Draws layer if this feature is on - static bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer); + static bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy); //Reset values static void reset(); private: //Configures overlay - static bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer); - //The chosen overlay state. - static ovutils::eOverlayState sState; + static bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer, + int dpy); //Flags if this feature is on. - static bool sIsUiMirroringOn; + static bool sModeOn[HWC_NUM_DISPLAY_TYPES]; + static ovutils::eDest sDest[HWC_NUM_DISPLAY_TYPES]; }; }; //namespace qhwc -#endif //HWC_UIMIRROR_H +#endif //HWC_FBUPDATE_H diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp index d3c8776f8..f9279aa90 100644 --- a/libhwcomposer/hwc_mdpcomp.cpp +++ b/libhwcomposer/hwc_mdpcomp.cpp @@ -17,95 +17,34 @@ */ #include "hwc_mdpcomp.h" +#include <sys/ioctl.h> #include "external.h" -#include "mdp_version.h" - -#define SUPPORT_4LAYER 0 namespace qhwc { -/****** Class PipeMgr ***********/ - -void inline PipeMgr::reset() { - mVGPipes = MAX_VG; - mVGUsed = 0; - mVGIndex = 0; - mRGBPipes = MAX_RGB; - mRGBUsed = 0; - mRGBIndex = MAX_VG; - mTotalAvail = mVGPipes + mRGBPipes; - memset(&mStatus, 0x0 , sizeof(int)*mTotalAvail); -} - -int PipeMgr::req_for_pipe(int pipe_req) { - - switch(pipe_req) { - case PIPE_REQ_VG: //VG - if(mVGPipes){ - mVGPipes--; - mVGUsed++; - mTotalAvail--; - return PIPE_REQ_VG; - } - case PIPE_REQ_RGB: // RGB - if(mRGBPipes) { - mRGBPipes--; - mRGBUsed++; - mTotalAvail--; - return PIPE_REQ_RGB; - } - return PIPE_NONE; - case PIPE_REQ_FB: //FB - if(mRGBPipes) { - mRGBPipes--; - mRGBUsed++; - mTotalAvail--; - mStatus[VAR_INDEX] = PIPE_IN_FB_MODE; - return PIPE_REQ_FB; - } - default: - break; - }; - return PIPE_NONE; -} - -int PipeMgr::assign_pipe(int pipe_pref) { - switch(pipe_pref) { - case PIPE_REQ_VG: //VG - if(mVGUsed) { - mVGUsed--; - mStatus[mVGIndex] = PIPE_IN_COMP_MODE; - return mVGIndex++; - } - case PIPE_REQ_RGB: //RGB - if(mRGBUsed) { - mRGBUsed--; - mStatus[mRGBIndex] = PIPE_IN_COMP_MODE; - return mRGBIndex++; - } - default: - ALOGE("%s: PipeMgr:invalid case in pipe_mgr_assign", - __FUNCTION__); - return -1; - }; -} - +namespace ovutils = overlay::utils; /****** Class MDPComp ***********/ -MDPComp::State MDPComp::sMDPCompState = MDPCOMP_OFF; -struct MDPComp::frame_info MDPComp::sCurrentFrame; -PipeMgr MDPComp::sPipeMgr; +MDPComp::eState MDPComp::sMDPCompState = MDPCOMP_OFF; +struct MDPComp::FrameInfo MDPComp::sCurrentFrame; IdleInvalidator *MDPComp::idleInvalidator = NULL; bool MDPComp::sIdleFallBack = false; bool MDPComp::sDebugLogs = false; -bool MDPComp::sPreRotation = true; -int MDPComp::sSkipCount = 0; -int MDPComp::sMaxLayers = 0; +bool MDPComp::sEnabled = false; +int MDPComp::sActiveMax = 0; +bool MDPComp::sSecuredVid = false; bool MDPComp::deinit() { //XXX: Tear down MDP comp state return true; } +bool MDPComp::isSkipPresent (hwc_context_t *ctx) { + return ctx->listStats[HWC_DISPLAY_PRIMARY].skipCount; +}; + +bool MDPComp::isYuvPresent (hwc_context_t *ctx) { + return ctx->listStats[HWC_DISPLAY_PRIMARY].yuvCount; +}; void MDPComp::timeout_handler(void *udata) { struct hwc_context_t* ctx = (struct hwc_context_t*)(udata); @@ -127,42 +66,13 @@ void MDPComp::timeout_handler(void *udata) { void MDPComp::reset(hwc_context_t *ctx, hwc_display_contents_1_t* list ) { //Reset flags and states unsetMDPCompLayerFlags(ctx, list); - if(sMDPCompState == MDPCOMP_ON) { - sMDPCompState = MDPCOMP_OFF_PENDING; - } - sCurrentFrame.count = 0; - if(sCurrentFrame.pipe_layer) { - free(sCurrentFrame.pipe_layer); - sCurrentFrame.pipe_layer = NULL; + if(sCurrentFrame.pipeLayer) { + free(sCurrentFrame.pipeLayer); + sCurrentFrame.pipeLayer = NULL; } - - //Reset MDP pipes - sPipeMgr.reset(); - sPipeMgr.setStatus(VAR_INDEX, PIPE_IN_FB_MODE); - -#if SUPPORT_4LAYER - configure_var_pipe(ctx); -#endif -} - -void MDPComp::setLayerIndex(hwc_layer_1_t* layer, const int pipe_index) -{ - layer->flags &= ~HWC_MDPCOMP_INDEX_MASK; - layer->flags |= pipe_index << MDPCOMP_INDEX_OFFSET; } -int MDPComp::getLayerIndex(hwc_layer_1_t* layer) -{ - int byp_index = -1; - - if(layer->flags & HWC_MDPCOMP) { - byp_index = ((layer->flags & HWC_MDPCOMP_INDEX_MASK) >> - MDPCOMP_INDEX_OFFSET); - byp_index = (byp_index < sMaxLayers ? byp_index : -1 ); - } - return byp_index; -} void MDPComp::print_info(hwc_layer_1_t* layer) { hwc_rect_t sourceCrop = layer->sourceCrop; @@ -183,11 +93,21 @@ void MDPComp::print_info(hwc_layer_1_t* layer) s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t), d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t)); } + +void MDPComp::setVidInfo(hwc_layer_1_t *layer, ovutils::eMdpFlags &mdpFlags) { + private_handle_t *hnd = (private_handle_t *)layer->handle; + + if(isSecureBuffer(hnd)) { + ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION); + sSecuredVid = true; + } +} + /* * Configures pipe(s) for MDP composition */ int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer, - mdp_pipe_info& mdp_info) { + MdpPipeInfo& mdp_info) { int nPipeIndex = mdp_info.index; @@ -195,17 +115,15 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer, private_handle_t *hnd = (private_handle_t *)layer->handle; - overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]); + overlay::Overlay& ov = *ctx->mOverlay; if(!hnd) { ALOGE("%s: layer handle is NULL", __FUNCTION__); return -1; } - - int hw_w = ctx->mFbDev->width; - int hw_h = ctx->mFbDev->height; - + int hw_w = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres; + int hw_h = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres; hwc_rect_t sourceCrop = layer->sourceCrop; hwc_rect_t displayFrame = layer->displayFrame; @@ -221,18 +139,10 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer, int dst_w = dst.right - dst.left; int dst_h = dst.bottom - dst.top; - //REDUNDANT ?? - if(hnd != NULL && - (hnd->flags & private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM )) { - ALOGE("%s: failed due to non-pmem memory",__FUNCTION__); - return -1; - } - if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) { ALOGD_IF(isDebug(),"%s: Destination has negative coordinates", __FUNCTION__); - qhwc::calculate_crop_rects(crop, dst, hw_w, hw_h, 0); //Update calulated width and height @@ -251,23 +161,18 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer, } // Determine pipe to set based on pipe index - ovutils::eDest dest = ovutils::OV_PIPE_ALL; - if (nPipeIndex == 0) { - dest = ovutils::OV_PIPE0; - } else if (nPipeIndex == 1) { - dest = ovutils::OV_PIPE1; - } else if (nPipeIndex == 2) { - dest = ovutils::OV_PIPE2; - } + ovutils::eDest dest = (ovutils::eDest)mdp_info.index; ovutils::eZorder zOrder = ovutils::ZORDER_0; - if(mdp_info.z_order == 0 ) { + if(mdp_info.zOrder == 0 ) { zOrder = ovutils::ZORDER_0; - } else if(mdp_info.z_order == 1 ) { + } else if(mdp_info.zOrder == 1 ) { zOrder = ovutils::ZORDER_1; - } else if(mdp_info.z_order == 2 ) { + } else if(mdp_info.zOrder == 2 ) { zOrder = ovutils::ZORDER_2; + } else if(mdp_info.zOrder == 3) { + zOrder = ovutils::ZORDER_3; } // Order order order @@ -279,64 +184,53 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer, // queueBuffer - not here, happens when draw is called ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); - ovutils::eMdpFlags mdpFlags = mdp_info.isVG ? ovutils::OV_MDP_PIPE_SHARE - : ovutils::OV_MDP_FLAGS_NONE; + + ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; + + if(isYuvBuffer(hnd)) + setVidInfo(layer, mdpFlags); + ovutils::setMdpFlags(mdpFlags,ovutils::OV_MDP_BACKEND_COMPOSITION); - ovutils::eIsFg isFG = mdp_info.isFG ? ovutils::IS_FG_SET - : ovutils::IS_FG_OFF; if(layer->blending == HWC_BLENDING_PREMULT) { ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_BLEND_FG_PREMULT); } - if (sPreRotation) { - if(layer->transform & HAL_TRANSFORM_FLIP_H) { - ovutils::setMdpFlags(mdpFlags, - ovutils::OV_MDP_FLIP_H); - } + ovutils::eTransform orient = overlay::utils::OVERLAY_TRANSFORM_0 ; - if(layer->transform & HAL_TRANSFORM_FLIP_V) { - ovutils::setMdpFlags(mdpFlags, - ovutils::OV_MDP_FLIP_V); + if(!(layer->transform & HWC_TRANSFORM_ROT_90)) { + if(layer->transform & HWC_TRANSFORM_FLIP_H) { + ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H); } - ov.setTransform(0, dest); + if(layer->transform & HWC_TRANSFORM_FLIP_V) { + ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V); + } } else { - ovutils::eTransform orient = - static_cast<ovutils::eTransform>(layer->transform); - - ov.setTransform(orient, dest); + orient = static_cast<ovutils::eTransform>(layer->transform); } ovutils::PipeArgs parg(mdpFlags, info, zOrder, - isFG, + ovutils::IS_FG_OFF, ovutils::ROT_FLAG_DISABLED); - ovutils::PipeArgs pargs[MAX_PIPES] = { parg, parg, parg }; - if (!ov.setSource(pargs, dest)) { - ALOGE("%s: setSource failed", __FUNCTION__); - return -1; - } + ov.setSource(parg, dest); + + ov.setTransform(orient, dest); ovutils::Dim dcrop(crop.left, crop.top, crop_w, crop_h); - if (!ov.setCrop(dcrop, dest)) { - ALOGE("%s: setCrop failed", __FUNCTION__); - return -1; - } + ov.setCrop(dcrop, dest); ovutils::Dim dim(dst.left, dst.top, dst_w, dst_h); - if (!ov.setPosition(dim, dest)) { - ALOGE("%s: setPosition failed", __FUNCTION__); - return -1; - } + ov.setPosition(dim, dest); ALOGD_IF(isDebug(),"%s: MDP set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] \ - nPipe: %d isFG: %d zorder: %d",__FUNCTION__, dcrop.x, + nPipe: %d zorder: %d",__FUNCTION__, dcrop.x, dcrop.y,dcrop.w, dcrop.h, dim.x, dim.y, dim.w, dim.h, - nPipeIndex,mdp_info.isFG, mdp_info.z_order); + mdp_info.index, mdp_info.zOrder); if (!ov.commit(dest)) { ALOGE("%s: commit failed", __FUNCTION__); @@ -356,22 +250,37 @@ int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer, * 5. Overlay in use */ -bool MDPComp::is_doable(hwc_context_t *ctx, hwc_display_contents_1_t* list) { +bool MDPComp::isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list) { //Number of layers int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; - if(numAppLayers < 1 || numAppLayers > sMaxLayers) { + + if(numAppLayers < 1 || numAppLayers > sActiveMax) { ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__); return false; } - //Disable MDPComp when ext display connected - if(isExternalActive(ctx)) { - ALOGD_IF(isDebug(), "%s: External display connected.", __FUNCTION__); + if(isSecuring(ctx)) { + ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__); + return false; + } + + if(ctx->mSecureMode) + return false; + + //Check for skip layers + if(isSkipPresent(ctx)) { + ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__); + return false; + } + + if(ctx->listStats[HWC_DISPLAY_PRIMARY].needsAlphaScale) { + ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__); return false; } //FB composition on idle timeout if(sIdleFallBack) { + sIdleFallBack = false; ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__); return false; } @@ -380,248 +289,110 @@ bool MDPComp::is_doable(hwc_context_t *ctx, hwc_display_contents_1_t* list) { for(int i = 0; i < numAppLayers; ++i) { // As MDP h/w supports flip operation, use MDP comp only for // 180 transforms. Fail for any transform involving 90 (90, 270). - if(sPreRotation ? - (list->hwLayers[i].transform & HWC_TRANSFORM_ROT_90) : - (list->hwLayers[i].transform) ) { - ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__); - return false; + hwc_layer_1_t* layer = &list->hwLayers[i]; + private_handle_t *hnd = (private_handle_t *)layer->handle; + if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) { + ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__); + return false; } } - return true; } -void MDPComp::setMDPCompLayerFlags(hwc_display_contents_1_t* list) { - - for(int index = 0 ; index < sCurrentFrame.count; index++ ) - { - int layer_index = sCurrentFrame.pipe_layer[index].layer_index; - if(layer_index >= 0) { - hwc_layer_1_t* layer = &(list->hwLayers[layer_index]); - - layer->flags |= HWC_MDPCOMP; - layer->compositionType = HWC_OVERLAY; - layer->hints |= HWC_HINT_CLEAR_FB; - } - } -} - -void MDPComp::get_layer_info(hwc_layer_1_t* layer, int& flags) { - - private_handle_t* hnd = (private_handle_t*)layer->handle; - - if(layer->flags & HWC_SKIP_LAYER) { - flags |= MDPCOMP_LAYER_SKIP; - } else if(hnd != NULL && - (hnd->flags & private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM )) { - flags |= MDPCOMP_LAYER_UNSUPPORTED_MEM; - } - - if(layer->blending != HWC_BLENDING_NONE) - flags |= MDPCOMP_LAYER_BLEND; - - int dst_w, dst_h; - getLayerResolution(layer, dst_w, dst_h); +void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx, + hwc_display_contents_1_t* list) { + LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY]; - hwc_rect_t sourceCrop = layer->sourceCrop; - const int src_w = sourceCrop.right - sourceCrop.left; - const int src_h = sourceCrop.bottom - sourceCrop.top; - if(((src_w > dst_w) || (src_h > dst_h))) { - flags |= MDPCOMP_LAYER_DOWNSCALE; + for(int index = 0 ; index < sCurrentFrame.count; index++ ) { + hwc_layer_1_t* layer = &(list->hwLayers[index]); + layerProp[index].mFlags |= HWC_MDPCOMP; + layer->compositionType = HWC_OVERLAY; + layer->hints |= HWC_HINT_CLEAR_FB; } } -int MDPComp::mark_layers(hwc_context_t *ctx, - hwc_display_contents_1_t* list, layer_mdp_info* layer_info, - frame_info& current_frame) { - - int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; +int MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type){ + overlay::Overlay& ov = *ctx->mOverlay; + int mdp_pipe = -1; - if(layer_count > sMaxLayers) { - if(!sPipeMgr.req_for_pipe(PIPE_REQ_FB)) { - ALOGE("%s: binding var pipe to FB failed!!", __FUNCTION__); - return 0; + switch(type) { + case MDPCOMP_OV_ANY: + case MDPCOMP_OV_RGB: + mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, HWC_DISPLAY_PRIMARY); + if(mdp_pipe != ovutils::OV_INVALID) { + return mdp_pipe; } - } - //Parse layers from higher z-order - for(int index = layer_count - 1 ; index >= 0; index-- ) { - hwc_layer_1_t* layer = &list->hwLayers[index]; - - int layer_prop = 0; - get_layer_info(layer, layer_prop); - - ALOGD_IF(isDebug(),"%s: prop for layer [%d]: %x", __FUNCTION__, - index, layer_prop); - - //Both in cases of NON-CONTIGUOUS memory or SKIP layer, - //current version of mdp composition falls back completely to FB - //composition. - //TO DO: Support dual mode composition - - if(layer_prop & MDPCOMP_LAYER_UNSUPPORTED_MEM) { - ALOGD_IF(isDebug(), "%s: Non contigous memory",__FUNCTION__); - return MDPCOMP_ABORT; - } - - if(layer_prop & MDPCOMP_LAYER_SKIP) { - ALOGD_IF(isDebug(), "%s:skip layer",__FUNCTION__); - return MDPCOMP_ABORT; + if(type == MDPCOMP_OV_RGB) { + //Requested only for RGB pipe + return -1; } - - //Request for MDP pipes - int pipe_pref = PIPE_REQ_VG; - - if((layer_prop & MDPCOMP_LAYER_DOWNSCALE) && - (layer_prop & MDPCOMP_LAYER_BLEND)) { - if (qdutils::MDPVersion::getInstance().getMDPVersion() >= - qdutils::MDP_V4_2) { - pipe_pref = PIPE_REQ_RGB; - } else { - return MDPCOMP_ABORT; - } - } - - int allocated_pipe = sPipeMgr.req_for_pipe( pipe_pref); - if(allocated_pipe) { - layer_info[index].can_use_mdp = true; - layer_info[index].pipe_pref = allocated_pipe; - current_frame.count++; - }else { - ALOGE("%s: pipe marking in mark layer fails for : %d", - __FUNCTION__, allocated_pipe); - return MDPCOMP_FAILURE; + case MDPCOMP_OV_VG: + mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, HWC_DISPLAY_PRIMARY); + if(mdp_pipe != ovutils::OV_INVALID) { + return mdp_pipe; } - } - return MDPCOMP_SUCCESS; -} - -void MDPComp::reset_layer_mdp_info(layer_mdp_info* layer_info, int count) { - for(int i = 0 ; i < count; i++ ) { - layer_info[i].can_use_mdp = false; - layer_info[i].pipe_pref = PIPE_NONE; - } + return -1; + default: + ALOGE("%s: Invalid pipe type",__FUNCTION__); + return -1; + }; } -bool MDPComp::alloc_layer_pipes(hwc_context_t *ctx, +bool MDPComp::allocLayerPipes(hwc_context_t *ctx, hwc_display_contents_1_t* list, - layer_mdp_info* layer_info, frame_info& current_frame) { + FrameInfo& currentFrame) { + + overlay::Overlay& ov = *ctx->mOverlay; int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; - int mdp_count = current_frame.count; - int fallback_count = layer_count - mdp_count; - int frame_pipe_count = 0; - ALOGD_IF(isDebug(), "%s: dual mode: %d total count: %d \ - mdp count: %d fallback count: %d", - __FUNCTION__, (layer_count != mdp_count), - layer_count, mdp_count, fallback_count); + currentFrame.count = layer_count; - for(int index = 0 ; index < layer_count ; index++ ) { - hwc_layer_1_t* layer = &list->hwLayers[index]; + currentFrame.pipeLayer = (PipeLayerPair*) + malloc(sizeof(PipeLayerPair) * currentFrame.count); - if(layer_info[index].can_use_mdp) { - pipe_layer_pair& info = current_frame.pipe_layer[frame_pipe_count]; - mdp_pipe_info& pipe_info = info.pipe_index; - - pipe_info.index = sPipeMgr.assign_pipe(layer_info[index].pipe_pref); - pipe_info.isVG = (layer_info[index].pipe_pref == PIPE_REQ_VG); - pipe_info.isFG = (frame_pipe_count == 0); - /* if VAR pipe is attached to FB, FB will be updated with - VSYNC WAIT flag, so no need to set VSYNC WAIT for any - bypass pipes. if not, set VSYNC WAIT to the last updating pipe*/ - pipe_info.vsync_wait = - (sPipeMgr.getStatus(VAR_INDEX) == PIPE_IN_FB_MODE) ? false: - (frame_pipe_count == (mdp_count - 1)); - /* All the layers composed on FB will have MDP zorder 0, so start - assigning from 1*/ - pipe_info.z_order = index - - (fallback_count ? fallback_count - 1 : fallback_count); - - info.layer_index = index; - frame_pipe_count++; + if(isYuvPresent(ctx)) { + int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex; + hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; + PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex]; + MdpPipeInfo& pipe_info = info.pipeIndex; + pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG); + if(pipe_info.index < 0) { + ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos", + __FUNCTION__); + return false; } + pipe_info.zOrder = nYuvIndex; } - return 1; -} - -//returns array of layers and their allocated pipes -bool MDPComp::parse_and_allocate(hwc_context_t* ctx, - hwc_display_contents_1_t* list, frame_info& current_frame ) { - - int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; - - /* clear pipe status */ - sPipeMgr.reset(); - - layer_mdp_info* bp_layer_info = (layer_mdp_info*) - malloc(sizeof(layer_mdp_info)* layer_count); - reset_layer_mdp_info(bp_layer_info, layer_count); + for(int index = 0 ; index < layer_count ; index++ ) { + if(index == ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex ) + continue; - /* iterate through layer list to mark candidate */ - if(mark_layers(ctx, list, bp_layer_info, current_frame) == MDPCOMP_ABORT) { - free(bp_layer_info); - current_frame.count = 0; - ALOGE_IF(isDebug(), "%s:mark_layers failed!!", __FUNCTION__); - return false; + hwc_layer_1_t* layer = &list->hwLayers[index]; + PipeLayerPair& info = currentFrame.pipeLayer[index]; + MdpPipeInfo& pipe_info = info.pipeIndex; + pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY); + if(pipe_info.index < 0) { + ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__); + return false; + } + pipe_info.zOrder = index; } - current_frame.pipe_layer = (pipe_layer_pair*) - malloc(sizeof(pipe_layer_pair) * current_frame.count); - - /* allocate MDP pipes for marked layers */ - alloc_layer_pipes(ctx, list, bp_layer_info, current_frame); - - free(bp_layer_info); return true; } -#if SUPPORT_4LAYER -int MDPComp::configure_var_pipe(hwc_context_t* ctx) { - - if(!ctx) { - ALOGE("%s: invalid context", __FUNCTION__); - return -1; - } - - framebuffer_device_t *fbDev = ctx->fbDev; - if (!fbDev) { - ALOGE("%s: fbDev is NULL", __FUNCTION__); - return -1; - } - - int new_mode = -1, cur_mode; - fbDev->perform(fbDev,EVENT_GET_VAR_PIPE_MODE, (void*)&cur_mode); - - if(sPipeMgr.getStatus(VAR_INDEX) == PIPE_IN_FB_MODE) { - new_mode = VAR_PIPE_FB_ATTACH; - } else if(sPipeMgr.getStatus(VAR_INDEX) == PIPE_IN_BYP_MODE) { - new_mode = VAR_PIPE_FB_DETACH; - fbDev->perform(fbDev,EVENT_WAIT_POSTBUFFER,NULL); - } - - ALOGD_IF(isDebug(),"%s: old_mode: %d new_mode: %d", __FUNCTION__, - cur_mode, new_mode); - - if((new_mode != cur_mode) && (new_mode >= 0)) { - if(fbDev->perform(fbDev,EVENT_SET_VAR_PIPE_MODE,(void*)&new_mode) < 0) { - ALOGE("%s: Setting var pipe mode failed", __FUNCTION__); - } - } - - return 0; -} -#endif bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) { int nPipeIndex, vsync_wait, isFG; int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; - frame_info ¤t_frame = sCurrentFrame; - current_frame.count = 0; + FrameInfo ¤tFrame = sCurrentFrame; + currentFrame.count = 0; - if(current_frame.pipe_layer) { - free(current_frame.pipe_layer); - current_frame.pipe_layer = NULL; + if(currentFrame.pipeLayer) { + free(currentFrame.pipeLayer); + currentFrame.pipeLayer = NULL; } if(!ctx) { @@ -629,125 +400,94 @@ bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) { return -1; } - framebuffer_device_t *fbDev = ctx->mFbDev; - if (!fbDev) { - ALOGE("%s: fbDev is NULL", __FUNCTION__); - return -1; - } - - if(!parse_and_allocate(ctx, list, current_frame)) { -#if SUPPORT_4LAYER - int mode = VAR_PIPE_FB_ATTACH; - if(fbDev->perform(fbDev,EVENT_SET_VAR_PIPE_MODE,(void*)&mode) < 0 ) { - ALOGE("%s: setting var pipe mode failed", __FUNCTION__); - } -#endif - ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__); - return false; - } -#if SUPPORT_4LAYER - configure_var_pipe(ctx); -#endif - - overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]); - ovutils::eOverlayState state = ov.getState(); - - if (current_frame.count == 1) { - state = ovutils::OV_BYPASS_1_LAYER; - } else if (current_frame.count == 2) { - state = ovutils::OV_BYPASS_2_LAYER; - } else if (current_frame.count == 3) { - state = ovutils::OV_BYPASS_3_LAYER; - } + if(!allocLayerPipes(ctx, list, currentFrame)) { + //clean current frame data + currentFrame.count = 0; - ov.setState(state); + if(currentFrame.pipeLayer) { + free(currentFrame.pipeLayer); + currentFrame.pipeLayer = NULL; + } + ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__); + return false; + } - for (int index = 0 ; index < current_frame.count; index++) { - int layer_index = current_frame.pipe_layer[index].layer_index; - hwc_layer_1_t* layer = &list->hwLayers[layer_index]; - mdp_pipe_info& cur_pipe = current_frame.pipe_layer[index].pipe_index; + for (int index = 0 ; index < currentFrame.count; index++) { + hwc_layer_1_t* layer = &list->hwLayers[index]; + MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex; if( prepare(ctx, layer, cur_pipe) != 0 ) { ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \ layer %d with pipe index:%d",__FUNCTION__, index, cur_pipe.index); return false; - } else { - setLayerIndex(layer, index); } } return true; } -void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx, hwc_display_contents_1_t* list) +void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx, + hwc_display_contents_1_t* list) { - for (int index = 0 ; index < sCurrentFrame.count; index++) { - int l_index = sCurrentFrame.pipe_layer[index].layer_index; - if(list->hwLayers[l_index].flags & HWC_MDPCOMP) { - list->hwLayers[l_index].flags &= ~HWC_MDPCOMP; + LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY]; + + for (int index = 0 ; + index < ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; index++) { + if(layerProp[index].mFlags & HWC_MDPCOMP) { + layerProp[index].mFlags &= ~HWC_MDPCOMP; } - if(list->hwLayers[l_index].compositionType == HWC_OVERLAY) { - list->hwLayers[l_index].compositionType = HWC_FRAMEBUFFER; + if(list->hwLayers[index].compositionType == HWC_OVERLAY) { + list->hwLayers[index].compositionType = HWC_FRAMEBUFFER; } } } -int MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { +bool MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { - if(!isEnabled()) { - ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled",__FUNCTION__); - return 0; + if(!isEnabled() || !isUsed()) { + ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__); + return true; } if(!ctx || !list) { ALOGE("%s: invalid contxt or list",__FUNCTION__); - return -1; + return false; } - overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]); + /* reset Invalidator */ + if(idleInvalidator) + idleInvalidator->markForSleep(); + + overlay::Overlay& ov = *ctx->mOverlay; + LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY]; int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers; for(int i = 0; i < numHwLayers; i++ ) { hwc_layer_1_t *layer = &list->hwLayers[i]; - if(!(layer->flags & HWC_MDPCOMP)) { - ALOGD_IF(isDebug(), "%s: Layer Not flagged for MDP comp", - __FUNCTION__); + if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { continue; } - int data_index = getLayerIndex(layer); - mdp_pipe_info& pipe_info = - sCurrentFrame.pipe_layer[data_index].pipe_index; + MdpPipeInfo& pipe_info = + sCurrentFrame.pipeLayer[i].pipeIndex; int index = pipe_info.index; if(index < 0) { ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index); - return -1; + return false; } - /* reset Invalidator */ - if(idleInvalidator) - idleInvalidator->markForSleep(); - - ovutils::eDest dest; - - if (index == 0) { - dest = ovutils::OV_PIPE0; - } else if (index == 1) { - dest = ovutils::OV_PIPE1; - } else if (index == 2) { - dest = ovutils::OV_PIPE2; - } + ovutils::eDest dest = (ovutils::eDest)index; if (ctx ) { private_handle_t *hnd = (private_handle_t *)layer->handle; if(!hnd) { ALOGE("%s handle null", __FUNCTION__); - return -1; + return false; } ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ @@ -756,45 +496,75 @@ int MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) { ALOGE("%s: queueBuffer failed for external", __FUNCTION__); - return -1; + return false; } } - layer->flags &= ~HWC_MDPCOMP; - layer->flags |= HWC_MDPCOMP_INDEX_MASK; + + layerProp[i].mFlags &= ~HWC_MDPCOMP; } - return 0; + return true; } -bool MDPComp::init(hwc_context_t *dev) { +/* + * Sets up BORDERFILL as default base pipe and detaches RGB0. + * Framebuffer is always updated using PLAY ioctl. + */ + +bool MDPComp::setupBasePipe(hwc_context_t *ctx) { + + int fb_stride = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride; + int fb_width = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres; + int fb_height = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres; + int fb_fd = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd; + + mdp_overlay ovInfo; + msmfb_overlay_data ovData; + memset(&ovInfo, 0, sizeof(mdp_overlay)); + memset(&ovData, 0, sizeof(msmfb_overlay_data)); + + ovInfo.src.format = MDP_RGB_BORDERFILL; + ovInfo.src.width = fb_width; + ovInfo.src.height = fb_height; + ovInfo.src_rect.w = fb_width; + ovInfo.src_rect.h = fb_height; + ovInfo.dst_rect.w = fb_width; + ovInfo.dst_rect.h = fb_height; + ovInfo.id = MSMFB_NEW_REQUEST; + + if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) { + ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s", + strerror(errno)); + return false; + } - if(!dev) { - ALOGE("%s: Invalid hwc context!!",__FUNCTION__); + ovData.id = ovInfo.id; + if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) { + ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s", + strerror(errno)); return false; } + return true; +} -#if SUPPORT_4LAYER - if(MAX_MDPCOMP_LAYERS > MAX_STATIC_PIPES) { - framebuffer_device_t *fbDev = dev->fbDevice; - if(fbDev == NULL) { - ALOGE("%s: FATAL: framebuffer device is NULL", __FUNCTION__); - return false; - } +bool MDPComp::init(hwc_context_t *ctx) { - //Receive VAR pipe object from framebuffer - if(fbDev->perform(fbDev,EVENT_GET_VAR_PIPE,(void*)&ov) < 0) { - ALOGE("%s: FATAL: getVariablePipe failed!!", __FUNCTION__); - return false; - } + if(!ctx) { + ALOGE("%s: Invalid hwc context!!",__FUNCTION__); + return false; + } - sPipeMgr.setStatus(VAR_INDEX, PIPE_IN_FB_MODE); + if(!setupBasePipe(ctx)) { + ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__); + return false; } -#endif + char property[PROPERTY_VALUE_MAX]; - sMaxLayers = 0; - if(property_get("debug.mdpcomp.maxlayer", property, NULL) > 0) { - if(atoi(property) != 0) - sMaxLayers = atoi(property); + sEnabled = false; + if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) && + (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || + (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { + sEnabled = true; } sDebugLogs = false; @@ -809,37 +579,35 @@ bool MDPComp::init(hwc_context_t *dev) { idle_timeout = atoi(property); } - sPreRotation = true; - if(property_get("debug.prerotation.disable", property, NULL) > 0) { - if(atoi(property) != 0) - sPreRotation = false; - } - //create Idle Invalidator idleInvalidator = IdleInvalidator::getInstance(); if(idleInvalidator == NULL) { ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__); } else { - idleInvalidator->init(timeout_handler, dev, idle_timeout); + idleInvalidator->init(timeout_handler, ctx, idle_timeout); } return true; } -bool MDPComp::configure(hwc_context_t *ctx, hwc_display_contents_1_t* list) { +bool MDPComp::configure(hwc_context_t *ctx, + hwc_display_contents_1_t* list) { if(!isEnabled()) { - ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__); + ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__); return false; } + overlay::Overlay& ov = *ctx->mOverlay; + + sActiveMax = ov.availablePipes(); + bool isMDPCompUsed = true; - bool doable = is_doable(ctx, list); + bool doable = isDoable(ctx, list); if(doable) { if(setup(ctx, list)) { - setMDPCompLayerFlags(list); - sMDPCompState = MDPCOMP_ON; + setMDPCompLayerFlags(ctx, list); } else { ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__); isMDPCompUsed = false; @@ -856,7 +624,7 @@ bool MDPComp::configure(hwc_context_t *ctx, hwc_display_contents_1_t* list) { reset(ctx, list); } - sIdleFallBack = false; + sMDPCompState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF; return isMDPCompUsed; } diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h index 0ad67ff1d..2821f0701 100644 --- a/libhwcomposer/hwc_mdpcomp.h +++ b/libhwcomposer/hwc_mdpcomp.h @@ -24,127 +24,47 @@ #include <cutils/properties.h> #include <overlay.h> -#define MAX_STATIC_PIPES 3 -#define MDPCOMP_INDEX_OFFSET 4 #define DEFAULT_IDLE_TIME 2000 -#define MAX_VG 2 -#define MAX_RGB 2 -#define VAR_INDEX 3 -#define MAX_PIPES (MAX_VG + MAX_RGB) -#define HWC_MDPCOMP_INDEX_MASK 0x00000030 - - -//struct hwc_context_t; - namespace qhwc { - -// pipe status -enum { - PIPE_UNASSIGNED = 0, - PIPE_IN_FB_MODE, - PIPE_IN_COMP_MODE, -}; - -// pipe request -enum { - PIPE_NONE = 0, - PIPE_REQ_VG, - PIPE_REQ_RGB, - PIPE_REQ_FB, -}; - -// MDP Comp Status -enum { - MDPCOMP_SUCCESS = 0, - MDPCOMP_FAILURE, - MDPCOMP_ABORT, -}; - -//This class manages the status of 4 MDP pipes and keeps -//track of Variable pipe mode. -class PipeMgr { - -public: - PipeMgr() { reset();} - //reset pipemgr params - void reset(); - - //Based on the preference received, pipe mgr - //allocates the best available pipe to handle - //the case - int req_for_pipe(int pipe_req); - - //Allocate requested pipe and update availablity - int assign_pipe(int pipe_pref); - - // Get/Set pipe status - void setStatus(int pipe_index, int pipe_status) { - mStatus[pipe_index] = pipe_status; - } - int getStatus(int pipe_index) { - return mStatus[pipe_index]; - } -private: - int mVGPipes; - int mVGUsed; - int mVGIndex; - int mRGBPipes; - int mRGBUsed; - int mRGBIndex; - int mTotalAvail; - int mStatus[MAX_PIPES]; -}; - +namespace ovutils = overlay::utils; class MDPComp { - enum State { + enum eState { MDPCOMP_ON = 0, MDPCOMP_OFF, - MDPCOMP_OFF_PENDING, }; - enum { - MDPCOMP_LAYER_BLEND = 1, - MDPCOMP_LAYER_DOWNSCALE = 2, - MDPCOMP_LAYER_SKIP = 4, - MDPCOMP_LAYER_UNSUPPORTED_MEM = 8, + enum ePipeType { + MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB, + MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG, + MDPCOMP_OV_ANY, }; - struct mdp_pipe_info { + struct MdpPipeInfo { int index; - int z_order; - bool isVG; - bool isFG; - bool vsync_wait; + int zOrder; }; - struct pipe_layer_pair { - int layer_index; - mdp_pipe_info pipe_index; + struct PipeLayerPair { + MdpPipeInfo pipeIndex; native_handle_t* handle; }; - struct frame_info { + struct FrameInfo { int count; - struct pipe_layer_pair* pipe_layer; + struct PipeLayerPair* pipeLayer; }; - struct layer_mdp_info { - bool can_use_mdp; - int pipe_pref; - }; - - static State sMDPCompState; + static eState sMDPCompState; static IdleInvalidator *idleInvalidator; - static struct frame_info sCurrentFrame; - static PipeMgr sPipeMgr; - static int sSkipCount; - static int sMaxLayers; + static struct FrameInfo sCurrentFrame; + static bool sEnabled; static bool sDebugLogs; static bool sIdleFallBack; - static bool sPreRotation; + static int sActiveMax; + static bool sSecuredVid; public: /* Handler to invoke frame redraw on Idle Timer expiry */ @@ -153,24 +73,19 @@ public: /* configure/tear-down MDPComp params*/ static bool init(hwc_context_t *ctx); static bool deinit(); + static bool isUsed() { return (sMDPCompState == MDPCOMP_ON); }; /*sets up mdp comp for the current frame */ - static bool configure(hwc_context_t *ctx, hwc_display_contents_1_t* list); + static bool configure(hwc_context_t *ctx, + hwc_display_contents_1_t* list); /* draw */ - static int draw(hwc_context_t *ctx, hwc_display_contents_1_t *list); - - /* store frame stats */ - static void setStats(int skipCt) { sSkipCount = skipCt;}; + static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list); private: - - /* get/set pipe index associated with overlay layers */ - static void setLayerIndex(hwc_layer_1_t* layer, const int pipe_index); - static int getLayerIndex(hwc_layer_1_t* layer); - /* set/reset flags for MDPComp */ - static void setMDPCompLayerFlags(hwc_display_contents_1_t* list); + static void setMDPCompLayerFlags(hwc_context_t *ctx, + hwc_display_contents_1_t* list); static void unsetMDPCompLayerFlags(hwc_context_t* ctx, hwc_display_contents_1_t* list); @@ -178,45 +93,42 @@ private: /* configure's overlay pipes for the frame */ static int prepare(hwc_context_t *ctx, hwc_layer_1_t *layer, - mdp_pipe_info& mdp_info); + MdpPipeInfo& mdp_info); /* checks for conditions where mdpcomp is not possible */ - static bool is_doable(hwc_context_t *ctx, hwc_display_contents_1_t* list); + static bool isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list); static bool setup(hwc_context_t* ctx, hwc_display_contents_1_t* list); - /* parses layer for properties affecting mdp comp */ - static void get_layer_info(hwc_layer_1_t* layer, int& flags); - - /* iterates through layer list to choose candidate to use overlay */ - static int mark_layers(hwc_context_t *ctx, hwc_display_contents_1_t* list, - layer_mdp_info* layer_info, frame_info& current_frame); - - static bool parse_and_allocate(hwc_context_t* ctx, hwc_display_contents_1_t* list, - frame_info& current_frame ); - - /* clears layer info struct */ - static void reset_layer_mdp_info(layer_mdp_info* layer_mdp_info,int count); - /* allocates pipes to selected candidates */ - static bool alloc_layer_pipes(hwc_context_t *ctx, + static bool allocLayerPipes(hwc_context_t *ctx, hwc_display_contents_1_t* list, - layer_mdp_info* layer_info, - frame_info& current_frame); - /* updates variable pipe mode for the current frame */ - static int configure_var_pipe(hwc_context_t* ctx); + FrameInfo& current_frame); /* get/set states */ - static State get_state() { return sMDPCompState; }; - static void set_state(State state) { sMDPCompState = state; }; + static eState getState() { return sMDPCompState; }; /* reset state */ static void reset( hwc_context_t *ctx, hwc_display_contents_1_t* list ); /* Is feature enabled */ - static bool isEnabled() { return sMaxLayers ? true : false; }; + static bool isEnabled() { return sEnabled; }; + /* Is debug enabled */ static bool isDebug() { return sDebugLogs ? true : false; }; + + /* check layer state */ + static bool isSkipPresent (hwc_context_t *ctx); + static bool isYuvPresent (hwc_context_t *ctx); + + /* configure MDP flags for video buffers */ + static void setVidInfo(hwc_layer_1_t *layer, ovutils::eMdpFlags &mdpFlags); + + /* set up Border fill as Base pipe */ + static bool setupBasePipe(hwc_context_t*); + + /* allocate MDP pipes from overlay */ + static int getMdpPipe(hwc_context_t *ctx, ePipeType type); }; }; //namespace #endif diff --git a/libhwcomposer/hwc_qbuf.h b/libhwcomposer/hwc_qbuf.h deleted file mode 100644 index 90f7143fd..000000000 --- a/libhwcomposer/hwc_qbuf.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * Copyright (C) 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 <gralloc_priv.h> - -#ifndef USE_FENCE_SYNC -#include <genlock.h> -#endif - -// ----------------------------------------------------------------------------- -// QueuedBufferStore -//This class holds currently and previously queued buffers. -//Provides utilities to store, lock, remove, unlock. - -namespace qhwc{ -static const int MAX_QUEUED_BUFS = 4; -class QueuedBufferStore { - public: - QueuedBufferStore() { - clearCurrent(); - clearPrevious(); - } - ~QueuedBufferStore() {} - void lockAndAdd(private_handle_t*); - //Unlocks only previous and makes the current as previous - void unlockAllPrevious(); - //Unlocks previous as well as current, useful in suspend case - void unlockAll(); - - private: - QueuedBufferStore& operator=(const QueuedBufferStore&); - QueuedBufferStore(const QueuedBufferStore&); - bool lockBuffer(private_handle_t *hnd); - void unlockBuffer(private_handle_t *hnd); - void clearCurrent(); - void clearPrevious(); - void mvCurrToPrev(); - - //members - private_handle_t *current[MAX_QUEUED_BUFS]; //holds buf being queued - private_handle_t *previous[MAX_QUEUED_BUFS]; //holds bufs queued in prev round - int curCount; - int prevCount; -}; - -//Store and lock current drawing round buffers -inline void QueuedBufferStore::lockAndAdd(private_handle_t *hnd) { -#ifndef USE_FENCE_SYNC - if(lockBuffer(hnd)) - current[curCount++] = hnd; -#endif -} - -//Unlock all previous drawing round buffers -inline void QueuedBufferStore::unlockAllPrevious() { -#ifndef USE_FENCE_SYNC - //Unlock - for(int i = 0; i < prevCount; i++) { - unlockBuffer(previous[i]); - previous[i] = NULL; - } - //Move current hnd to previous - mvCurrToPrev(); - //Clear current - clearCurrent(); -#endif -} - -inline void QueuedBufferStore::unlockAll() { -#ifndef USE_FENCE_SYNC - //Unlocks prev and moves current to prev - unlockAllPrevious(); - //Unlocks the newly populated prev if any. - unlockAllPrevious(); -#endif -} - -//Clear currentbuf store -inline void QueuedBufferStore::clearCurrent() { -#ifndef USE_FENCE_SYNC - for(int i = 0; i < MAX_QUEUED_BUFS; i++) - current[i] = NULL; - curCount = 0; -#endif -} - -//Clear previousbuf store -inline void QueuedBufferStore::clearPrevious() { -#ifndef USE_FENCE_SYNC - for(int i = 0; i < MAX_QUEUED_BUFS; i++) - previous[i] = NULL; - prevCount = 0; -#endif -} - -//Copy from current to previous -inline void QueuedBufferStore::mvCurrToPrev() { -#ifndef USE_FENCE_SYNC - for(int i = 0; i < curCount; i++) - previous[i] = current[i]; - prevCount = curCount; -#endif -} - -inline bool QueuedBufferStore::lockBuffer(private_handle_t *hnd) { -#ifndef USE_FENCE_SYNC - if (GENLOCK_FAILURE == genlock_lock_buffer(hnd, GENLOCK_READ_LOCK, - GENLOCK_MAX_TIMEOUT)) { - ALOGE("%s: genlock_lock_buffer(READ) failed", __func__); - return false; - } -#endif - return true; -} - -inline void QueuedBufferStore::unlockBuffer(private_handle_t *hnd) { -#ifndef USE_FENCE_SYNC - //Check if buffer is still around - if(private_handle_t::validate(hnd) != 0) { - ALOGE("%s Invalid Handle", __func__); - return; - } - //Actually try to unlock - if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) { - ALOGE("%s: genlock_unlock_buffer failed", __func__); - return; - } -#endif -} -// ----------------------------------------------------------------------------- -};//namespace - diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp index 1ebbd52ae..c26f31f13 100644 --- a/libhwcomposer/hwc_utils.cpp +++ b/libhwcomposer/hwc_utils.cpp @@ -15,16 +15,16 @@ * limitations under the License. */ +#include <sys/ioctl.h> #include <EGL/egl.h> -#include <overlay.h> #include <cutils/properties.h> #include <gralloc_priv.h> #include <fb_priv.h> +#include <overlay.h> #include "hwc_utils.h" +#include "hwc_mdpcomp.h" #include "mdp_version.h" -#include "hwc_video.h" #include "external.h" -#include "hwc_mdpcomp.h" #include "QService.h" namespace qhwc { @@ -38,6 +38,8 @@ static void openFramebufferDevice(hwc_context_t *ctx) private_module_t* m = reinterpret_cast<private_module_t*>( ctx->mFbDev->common.module); //xres, yres may not be 32 aligned + ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride = m->finfo.line_length / + (m->info.xres/8); ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = m->info.xres; ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = m->info.yres; ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = ctx->mFbDev->xdpi; @@ -52,14 +54,14 @@ void initContext(hwc_context_t *ctx) { openFramebufferDevice(ctx); overlay::Overlay::initOverlay(); - for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) { - ctx->mOverlay[i] = overlay::Overlay::getInstance(i); - } + ctx->mOverlay = overlay::Overlay::getInstance(); ctx->mQService = qService::QService::getInstance(ctx); ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion(); ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay(); ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType(); ctx->mExtDisplay = new ExternalDisplay(ctx); + for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) + ctx->mLayerCache[i] = new LayerCache(); MDPComp::init(ctx); pthread_mutex_init(&(ctx->vstate.lock), NULL); @@ -72,11 +74,9 @@ void initContext(hwc_context_t *ctx) void closeContext(hwc_context_t *ctx) { - for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) { - if(ctx->mOverlay[i]) { - delete ctx->mOverlay[i]; - ctx->mOverlay[i] = NULL; - } + if(ctx->mOverlay) { + delete ctx->mOverlay; + ctx->mOverlay = NULL; } if(ctx->mFbDev) { @@ -111,6 +111,25 @@ void dumpLayer(hwc_layer_1_t const* l) l->displayFrame.bottom); } +static inline bool isAlphaScaled(hwc_layer_1_t const* layer) { + int dst_w, dst_h, src_w, src_h; + + hwc_rect_t displayFrame = layer->displayFrame; + hwc_rect_t sourceCrop = layer->sourceCrop; + + dst_w = displayFrame.right - displayFrame.left; + dst_h = displayFrame.bottom - displayFrame.top; + + src_w = sourceCrop.right - sourceCrop.left; + src_h = sourceCrop.bottom - sourceCrop.top; + + if(((src_w != dst_w) || (src_h != dst_h))) { + if(layer->blending != HWC_BLENDING_NONE) + return true; + } + return false; +} + void setListStats(hwc_context_t *ctx, const hwc_display_contents_1_t *list, int dpy) { @@ -119,10 +138,11 @@ void setListStats(hwc_context_t *ctx, ctx->listStats[dpy].yuvCount = 0; ctx->listStats[dpy].yuvIndex = -1; ctx->listStats[dpy].skipCount = 0; + ctx->listStats[dpy].needsAlphaScale = false; for (size_t i = 0; i < list->numHwLayers; i++) { - private_handle_t *hnd = - (private_handle_t *)list->hwLayers[i].handle; + hwc_layer_1_t const* layer = &list->hwLayers[i]; + private_handle_t *hnd = (private_handle_t *)layer->handle; if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { continue; @@ -131,6 +151,9 @@ void setListStats(hwc_context_t *ctx, ctx->listStats[dpy].skipCount++; } + if(!ctx->listStats[dpy].needsAlphaScale) + ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer); + if (UNLIKELY(isYuvBuffer(hnd))) { ctx->listStats[dpy].yuvCount++; ctx->listStats[dpy].yuvIndex = i; @@ -138,6 +161,7 @@ void setListStats(hwc_context_t *ctx, } } + static inline void calc_cut(float& leftCutRatio, float& topCutRatio, float& rightCutRatio, float& bottomCutRatio, int orient) { if(orient & HAL_TRANSFORM_FLIP_H) { @@ -156,6 +180,16 @@ static inline void calc_cut(float& leftCutRatio, float& topCutRatio, } } +bool isSecuring(hwc_context_t* ctx) { + if((ctx->mMDP.version < qdutils::MDSS_V5) && + (ctx->mMDP.version > qdutils::MDP_V3_0) && + ctx->mSecuring) { + return true; + } + return false; +} + + //Crops source buffer against destination and FB boundaries void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, const int fbWidth, const int fbHeight, int orient) { @@ -206,8 +240,9 @@ bool isExternalActive(hwc_context_t* ctx) { int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy) { int ret = 0; +#ifdef USE_FENCE_SYNC struct mdp_buf_sync data; - int acquireFd[4]; + int acquireFd[MAX_NUM_LAYERS]; int count = 0; int releaseFd = -1; int fbFd = -1; @@ -218,7 +253,7 @@ int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy) { for(uint32_t i = 0; i < list->numHwLayers; i++) { if((list->hwLayers[i].compositionType == HWC_OVERLAY || list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) && - list->hwLayers[i].acquireFenceFd != -1) { + list->hwLayers[i].acquireFenceFd != -1 ){ acquireFd[count++] = list->hwLayers[i].acquireFenceFd; } } @@ -246,7 +281,75 @@ int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy) { } } list->retireFenceFd = releaseFd; +#endif return ret; } +void LayerCache::resetLayerCache(int num) { + for(uint32_t i = 0; i < MAX_NUM_LAYERS; i++) { + hnd[i] = NULL; + } + numHwLayers = num; +} + +void LayerCache::updateLayerCache(hwc_display_contents_1_t* list) { + + int numFbLayers = 0; + int numCacheableLayers = 0; + + canUseLayerCache = false; + //Bail if geometry changed or num of layers changed + if(list->flags & HWC_GEOMETRY_CHANGED || + list->numHwLayers != numHwLayers ) { + resetLayerCache(list->numHwLayers); + return; + } + + for(uint32_t i = 0; i < list->numHwLayers; i++) { + //Bail on skip layers + if(list->hwLayers[i].flags & HWC_SKIP_LAYER) { + resetLayerCache(list->numHwLayers); + return; + } + + if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER) { + numFbLayers++; + if(hnd[i] == NULL) { + hnd[i] = list->hwLayers[i].handle; + } else if (hnd[i] == + list->hwLayers[i].handle) { + numCacheableLayers++; + } else { + hnd[i] = NULL; + return; + } + } else { + hnd[i] = NULL; + } + } + if(numFbLayers == numCacheableLayers) + canUseLayerCache = true; + + //XXX: The marking part is separate, if MDP comp wants + // to use it in the future. Right now getting MDP comp + // to use this is more trouble than it is worth. + markCachedLayersAsOverlay(list); +} + +void LayerCache::markCachedLayersAsOverlay(hwc_display_contents_1_t* list) { + //This optimization only works if ALL the layer handles + //that were on the framebuffer didn't change. + if(canUseLayerCache){ + for(uint32_t i = 0; i < list->numHwLayers; i++) { + if (list->hwLayers[i].handle && + list->hwLayers[i].handle == hnd[i] && + list->hwLayers[i].compositionType != HWC_FRAMEBUFFER_TARGET) + { + list->hwLayers[i].compositionType = HWC_OVERLAY; + } + } + } + +} + };//namespace diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h index ced542e98..866073c90 100644 --- a/libhwcomposer/hwc_utils.h +++ b/libhwcomposer/hwc_utils.h @@ -29,6 +29,7 @@ #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) #define FINAL_TRANSFORM_MASK 0x000F #define MAX_NUM_DISPLAYS 4 //Yes, this is ambitious +#define MAX_NUM_LAYERS 32 //Fwrd decls struct hwc_context_t; @@ -57,6 +58,7 @@ struct DisplayAttributes { uint32_t vsync_period; //nanos uint32_t xres; uint32_t yres; + uint32_t stride; float xdpi; float ydpi; int fd; @@ -73,15 +75,43 @@ struct ListStats { //Video specific int yuvCount; int yuvIndex; + bool needsAlphaScale; }; + +struct LayerProp { + uint32_t mFlags; //qcom specific layer flags + LayerProp():mFlags(0) {}; +}; + +// LayerProp::flag values enum { - HWC_MDPCOMP = 0x00000002, - HWC_LAYER_RESERVED_0 = 0x00000004, - HWC_LAYER_RESERVED_1 = 0x00000008 + HWC_MDPCOMP = 0x00000001, +}; + +class LayerCache { + public: + LayerCache() { + canUseLayerCache = false; + numHwLayers = 0; + for(uint32_t i = 0; i < MAX_NUM_LAYERS; i++) { + hnd[i] = NULL; + } + } + //LayerCache optimization + void updateLayerCache(hwc_display_contents_1_t* list); + void resetLayerCache(int num); + void markCachedLayersAsOverlay(hwc_display_contents_1_t* list); + private: + uint32_t numHwLayers; + bool canUseLayerCache; + buffer_handle_t hnd[MAX_NUM_LAYERS]; + }; + + // ----------------------------------------------------------------------------- // Utility functions - implemented in hwc_utils.cpp void dumpLayer(hwc_layer_1_t const* l); @@ -92,7 +122,7 @@ void closeContext(hwc_context_t *ctx); //Crops source buffer against destination and FB boundaries void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, const int fbWidth, const int fbHeight, int orient); - +bool isSecuring(hwc_context_t* ctx); bool isExternalActive(hwc_context_t* ctx); //Sync point impl. @@ -175,33 +205,24 @@ struct vsync_state { struct hwc_context_t { hwc_composer_device_1_t device; const hwc_procs_t* proc; - - int overlayInUse[HWC_NUM_DISPLAY_TYPES]; - //Framebuffer device framebuffer_device_t *mFbDev; - //Overlay object - NULL for non overlay devices - overlay::Overlay *mOverlay[HWC_NUM_DISPLAY_TYPES]; - + overlay::Overlay *mOverlay; //QService object qService::QService *mQService; - // External display related information qhwc::ExternalDisplay *mExtDisplay; - qhwc::MDPInfo mMDP; - qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES]; - qhwc::ListStats listStats[HWC_NUM_DISPLAY_TYPES]; + qhwc::LayerCache *mLayerCache[HWC_NUM_DISPLAY_TYPES]; + qhwc::LayerProp *layerProp[HWC_NUM_DISPLAY_TYPES]; //Securing in progress indicator bool mSecuring; - //Display in secure mode indicator bool mSecureMode; - //Lock to prevent set from being called while blanking mutable Locker mBlankLock; //Lock to protect set when detaching external disp diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp index aad29394a..48cb165e0 100644 --- a/libhwcomposer/hwc_video.cpp +++ b/libhwcomposer/hwc_video.cpp @@ -22,11 +22,11 @@ namespace qhwc { -#define FINAL_TRANSFORM_MASK 0x000F +namespace ovutils = overlay::utils; //Static Members -ovutils::eOverlayState VideoOverlay::sState[] = {ovutils::OV_CLOSED}; bool VideoOverlay::sIsModeOn[] = {false}; +ovutils::eDest VideoOverlay::sDest[] = {ovutils::OV_INVALID}; //Cache stats, figure out the state, config overlay bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list, @@ -40,14 +40,19 @@ bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list, return false; } + if(isSecuring(ctx)) { + ALOGD_IF(VIDEO_DEBUG,"%s: MDP Secure is active", __FUNCTION__); + return false; + } + if(yuvIndex == -1 || ctx->listStats[dpy].yuvCount != 1) { return false; } //index guaranteed to be not -1 at this point - hwc_layer_1_t *yuvLayer = &list->hwLayers[yuvIndex]; + hwc_layer_1_t *layer = &list->hwLayers[yuvIndex]; - private_handle_t *hnd = (private_handle_t *)yuvLayer->handle; + private_handle_t *hnd = (private_handle_t *)layer->handle; if(ctx->mSecureMode) { if (! isSecureBuffer(hnd)) { ALOGD_IF(VIDEO_DEBUG, "%s: Handle non-secure video layer" @@ -61,135 +66,34 @@ bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list, return false; } } - chooseState(ctx, dpy, yuvLayer); - if(configure(ctx, dpy, yuvLayer)) { - markFlags(yuvLayer); + if(configure(ctx, dpy, layer)) { + markFlags(layer); sIsModeOn[dpy] = true; } return sIsModeOn[dpy]; } -void VideoOverlay::chooseState(hwc_context_t *ctx, int dpy, - hwc_layer_1_t *yuvLayer) { - ALOGD_IF(VIDEO_DEBUG, "%s: old state = %s", __FUNCTION__, - ovutils::getStateString(sState[dpy])); - - private_handle_t *hnd = NULL; - if(yuvLayer) { - hnd = (private_handle_t *)yuvLayer->handle; - } - ovutils::eOverlayState newState = ovutils::OV_CLOSED; - switch(dpy) { - case HWC_DISPLAY_PRIMARY: - if(ctx->listStats[dpy].yuvCount == 1) { - newState = ovutils::OV_2D_VIDEO_ON_PANEL; - if(isSkipLayer(yuvLayer) && !isSecureBuffer(hnd)) { - newState = ovutils::OV_CLOSED; - } - } - break; - case HWC_DISPLAY_EXTERNAL: - newState = ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->getState(); //If we are here, external is active - if(ctx->listStats[dpy].yuvCount == 1) { - if(!isSkipLayer(yuvLayer) || isSecureBuffer(hnd)) { - newState = ovutils::OV_UI_VIDEO_TV; - } - } - break; - default: - break; +void VideoOverlay::markFlags(hwc_layer_1_t *layer) { + if(layer) { + layer->compositionType = HWC_OVERLAY; + layer->hints |= HWC_HINT_CLEAR_FB; } - - sState[dpy] = newState; - ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__, - ovutils::getStateString(sState[dpy])); } -void VideoOverlay::markFlags(hwc_layer_1_t *yuvLayer) { - if(yuvLayer) { - yuvLayer->compositionType = HWC_OVERLAY; - yuvLayer->hints |= HWC_HINT_CLEAR_FB; - } -} - -/* Helpers */ -bool configPrimVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { - overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]); +bool VideoOverlay::configure(hwc_context_t *ctx, int dpy, + hwc_layer_1_t *layer) { + overlay::Overlay& ov = *(ctx->mOverlay); private_handle_t *hnd = (private_handle_t *)layer->handle; ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); - ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; - if (isSecureBuffer(hnd)) { - ovutils::setMdpFlags(mdpFlags, - ovutils::OV_MDP_SECURE_OVERLAY_SESSION); - } - - if(layer->blending == HWC_BLENDING_PREMULT) { - ovutils::setMdpFlags(mdpFlags, - ovutils::OV_MDP_BLEND_FG_PREMULT); - } - - ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF; - if (ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers == 1) { - isFgFlag = ovutils::IS_FG_SET; - } - - ovutils::PipeArgs parg(mdpFlags, - info, - ovutils::ZORDER_0, - isFgFlag, - ovutils::ROT_FLAG_DISABLED); - ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; - ov.setSource(pargs, ovutils::OV_PIPE0); - - int transform = layer->transform & FINAL_TRANSFORM_MASK; - ovutils::eTransform orient = - static_cast<ovutils::eTransform>(transform); - - hwc_rect_t sourceCrop = layer->sourceCrop; - hwc_rect_t displayFrame = layer->displayFrame; - - //Calculate the rect for primary based on whether the supplied position - //is within or outside bounds. - const int fbWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres; - const int fbHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres; - - if( displayFrame.left < 0 || - displayFrame.top < 0 || - displayFrame.right > fbWidth || - displayFrame.bottom > fbHeight) { - calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight, - transform); - } - - // source crop x,y,w,h - ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, - sourceCrop.right - sourceCrop.left, - sourceCrop.bottom - sourceCrop.top); - //Only for Primary - ov.setCrop(dcrop, ovutils::OV_PIPE0); - - ov.setTransform(orient, ovutils::OV_PIPE0); - - // position x,y,w,h - ovutils::Dim dpos(displayFrame.left, - displayFrame.top, - displayFrame.right - displayFrame.left, - displayFrame.bottom - displayFrame.top); - ov.setPosition(dpos, ovutils::OV_PIPE0); - - if (!ov.commit(ovutils::OV_PIPE0)) { - ALOGE("%s: commit fails", __FUNCTION__); + //Request a VG pipe + ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy); + if(dest == ovutils::OV_INVALID) { //None available return false; } - return true; -} -bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { - overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]); - private_handle_t *hnd = (private_handle_t *)layer->handle; - ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); + sDest[dpy] = dest; ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; if (isSecureBuffer(hnd)) { @@ -203,7 +107,7 @@ bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { } ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF; - if (ctx->listStats[HWC_DISPLAY_EXTERNAL].numAppLayers == 1) { + if (ctx->listStats[dpy].numAppLayers == 1) { isFgFlag = ovutils::IS_FG_SET; } @@ -212,8 +116,8 @@ bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { ovutils::ZORDER_1, isFgFlag, ovutils::ROT_FLAG_DISABLED); - ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; - ov.setSource(pargs, ovutils::OV_PIPE1); + + ov.setSource(parg, dest); int transform = layer->transform; ovutils::eTransform orient = @@ -224,8 +128,8 @@ bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { //Calculate the rect for primary based on whether the supplied position //is within or outside bounds. - const int fbWidth = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres; - const int fbHeight = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].yres; + const int fbWidth = ctx->dpyAttr[dpy].xres; + const int fbHeight = ctx->dpyAttr[dpy].yres; if( displayFrame.left < 0 || displayFrame.top < 0 || @@ -235,60 +139,29 @@ bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) { transform); } - // x,y,w,h + // source crop x,y,w,h ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, sourceCrop.right - sourceCrop.left, sourceCrop.bottom - sourceCrop.top); - //Only for External - ov.setCrop(dcrop, ovutils::OV_PIPE1); + //Only for Primary + ov.setCrop(dcrop, dest); - ov.setTransform(orient, ovutils::OV_PIPE1); + ov.setTransform(orient, dest); + // position x,y,w,h ovutils::Dim dpos(displayFrame.left, displayFrame.top, - (displayFrame.right - displayFrame.left), - (displayFrame.bottom - displayFrame.top)); - - //Only for External - ov.setPosition(dpos, ovutils::OV_PIPE1); + displayFrame.right - displayFrame.left, + displayFrame.bottom - displayFrame.top); + ov.setPosition(dpos, dest); - if (!ov.commit(ovutils::OV_PIPE1)) { + if (!ov.commit(dest)) { ALOGE("%s: commit fails", __FUNCTION__); return false; } return true; } -bool VideoOverlay::configure(hwc_context_t *ctx, int dpy, - hwc_layer_1_t *yuvLayer) { - bool ret = true; - overlay::Overlay& ov = *(ctx->mOverlay[dpy]); - switch(dpy) { - case HWC_DISPLAY_PRIMARY: - // Set overlay state - ov.setState(sState[dpy]); - switch(sState[dpy]) { - case ovutils::OV_2D_VIDEO_ON_PANEL: - ret &= configPrimVid(ctx, yuvLayer); - break; - default: - return false; - } - break; - case HWC_DISPLAY_EXTERNAL: - ov.setState(sState[dpy]); - switch(sState[dpy]) { - case ovutils::OV_UI_VIDEO_TV: - ret = configExtVid(ctx, yuvLayer); - break; - default: - return false; - } - break; - } - return ret; -} - bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, int dpy) { @@ -305,39 +178,14 @@ bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, list->hwLayers[yuvIndex].handle; bool ret = true; - overlay::Overlay& ov = *(ctx->mOverlay[dpy]); - ovutils::eOverlayState state = ov.getState(); - - switch(dpy) { - case HWC_DISPLAY_PRIMARY: - switch (state) { - case ovutils::OV_2D_VIDEO_ON_PANEL: - // Play primary - if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) { - ALOGE("%s: queueBuffer failed for primary", __FUNCTION__); - ret = false; - } - break; - default: - ret = false; - break; - } - break; - case HWC_DISPLAY_EXTERNAL: - switch(state) { - case ovutils::OV_UI_VIDEO_TV: - // Play external - if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) { - ALOGE("%s: queueBuffer failed for external", __FUNCTION__); - ret = false; - } - break; - default: - ret = false; - break; - } - break; + overlay::Overlay& ov = *(ctx->mOverlay); + + if (!ov.queueBuffer(hnd->fd, hnd->offset, + sDest[dpy])) { + ALOGE("%s: queueBuffer failed for dpy=%d", __FUNCTION__, dpy); + ret = false; } + return ret; } diff --git a/libhwcomposer/hwc_video.h b/libhwcomposer/hwc_video.h index dbfc23688..09b24cc4d 100644 --- a/libhwcomposer/hwc_video.h +++ b/libhwcomposer/hwc_video.h @@ -16,12 +16,16 @@ */ #ifndef HWC_VIDEO_H #define HWC_VIDEO_H + #include "hwc_utils.h" +#include "overlayUtils.h" #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) namespace qhwc { +namespace ovutils = overlay::utils; + //Feature for using overlay to display videos. class VideoOverlay { public: @@ -34,24 +38,21 @@ public: //resets values static void reset(); private: - //Choose an appropriate overlay state based on conditions - static void chooseState(hwc_context_t *ctx, int dpy, - hwc_layer_1_t *yuvLayer); //Configures overlay for video prim and ext static bool configure(hwc_context_t *ctx, int dpy, hwc_layer_1_t *yuvlayer); + //Marks layer flags if this feature is used static void markFlags(hwc_layer_1_t *yuvLayer); - //The chosen overlay state. - static ovutils::eOverlayState sState[HWC_NUM_DISPLAY_TYPES]; //Flags if this feature is on. static bool sIsModeOn[HWC_NUM_DISPLAY_TYPES]; + static ovutils::eDest sDest[HWC_NUM_DISPLAY_TYPES]; }; inline void VideoOverlay::reset() { for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) { sIsModeOn[i] = false; - sState[i] = ovutils::OV_CLOSED; + sDest[i] = ovutils::OV_INVALID; } } }; //namespace qhwc diff --git a/libhwcomposer/hwc_vsync.cpp b/libhwcomposer/hwc_vsync.cpp index a3becfa59..ee6af2856 100644 --- a/libhwcomposer/hwc_vsync.cpp +++ b/libhwcomposer/hwc_vsync.cpp @@ -21,6 +21,7 @@ // WARNING : Excessive logging, if VSYNC_DEBUG enabled #define VSYNC_DEBUG 0 +#include <cutils/properties.h> #include <utils/Log.h> #include <fcntl.h> #include <sys/ioctl.h> @@ -59,16 +60,23 @@ static void *vsync_loop(void *param) int ret = 0; bool fb1_vsync = false; bool enabled = false; + bool fakevsync = false; + + char property[PROPERTY_VALUE_MAX]; + if(property_get("debug.hwc.fakevsync", property, NULL) > 0) { + if(atoi(property) == 1) + fakevsync = true; + } /* Currently read vsync timestamp from drivers e.g. VSYNC=41800875994 - */ + */ fd_timestamp = open(vsync_timestamp_fb0, O_RDONLY); if (fd_timestamp < 0) { ALOGE ("FATAL:%s:not able to open file:%s, %s", __FUNCTION__, (fb1_vsync) ? vsync_timestamp_fb1 : vsync_timestamp_fb0, strerror(errno)); - return NULL; + fakevsync = true; } do { @@ -76,7 +84,8 @@ static void *vsync_loop(void *param) while (ctx->vstate.enable == false) { if(enabled) { int e = 0; - if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, + if(!fakevsync && + ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, &e) < 0) { ALOGE("%s: vsync control failed. Dpy=%d, enabled=%d : %s", __FUNCTION__, dpy, enabled, strerror(errno)); @@ -90,8 +99,9 @@ static void *vsync_loop(void *param) if (!enabled) { int e = 1; - if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, - &e) < 0) { + if(!fakevsync && + ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, + &e) < 0) { ALOGE("%s: vsync control failed. Dpy=%d, enabled=%d : %s", __FUNCTION__, dpy, enabled, strerror(errno)); ret = -errno; @@ -99,37 +109,44 @@ static void *vsync_loop(void *param) enabled = true; } - for(int i = 0; i < MAX_RETRY_COUNT; i++) { - len = pread(fd_timestamp, vdata, MAX_DATA, 0); - if(len < 0 && (errno == EAGAIN || errno == EINTR)) { - ALOGW("%s: vsync read: EAGAIN, retry (%d/%d).", - __FUNCTION__, i, MAX_RETRY_COUNT); - continue; - } else { - break; - } - } - - if (len < 0) { - ALOGE ("FATAL:%s:not able to read file:%s, %s", __FUNCTION__, - vsync_timestamp_fb0, strerror(errno)); - //XXX: Need to continue here since SF needs vsync signal to compose - continue; - } - - // extract timestamp - const char *str = vdata; - if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) { - cur_timestamp = strtoull(str + strlen("VSYNC="), NULL, 0); - } else { - ALOGE ("FATAL: %s: vsync timestamp not in correct format: [%s]", - __FUNCTION__, - str); - } - // send timestamp to HAL - ALOGD_IF (VSYNC_DEBUG, "%s: timestamp %llu sent to HWC for %s", - __FUNCTION__, cur_timestamp, "fb0"); - ctx->proc->vsync(ctx->proc, dpy, cur_timestamp); + if(!fakevsync) { + for(int i = 0; i < MAX_RETRY_COUNT; i++) { + len = pread(fd_timestamp, vdata, MAX_DATA, 0); + if(len < 0 && (errno == EAGAIN || errno == EINTR)) { + ALOGW("%s: vsync read: EAGAIN, retry (%d/%d).", + __FUNCTION__, i, MAX_RETRY_COUNT); + continue; + } else { + break; + } + } + + if (len < 0) { + ALOGE ("FATAL:%s:not able to read file:%s, %s", __FUNCTION__, + vsync_timestamp_fb0, strerror(errno)); + close (fd_timestamp); + fakevsync = true; + } + + // extract timestamp + const char *str = vdata; + if (!strncmp(str, "VSYNC=", strlen("VSYNC="))) { + cur_timestamp = strtoull(str + strlen("VSYNC="), NULL, 0); + } else { + ALOGE ("FATAL: %s: vsync timestamp not in correct format: [%s]", + __FUNCTION__, + str); + fakevsync = true; + } + + } else { + usleep(16000); + cur_timestamp = systemTime(); + } + // send timestamp to HAL + ALOGD_IF (VSYNC_DEBUG, "%s: timestamp %llu sent to HWC for %s", + __FUNCTION__, cur_timestamp, "fb0"); + ctx->proc->vsync(ctx->proc, dpy, cur_timestamp); } while (true); if(fd_timestamp >= 0) @@ -146,7 +163,7 @@ void init_vsync_thread(hwc_context_t* ctx) ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx); if (ret) { ALOGE("%s: failed to create %s: %s", __FUNCTION__, - HWC_VSYNC_THREAD_NAME, strerror(ret)); + HWC_VSYNC_THREAD_NAME, strerror(ret)); } } diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk index 3c1057d3b..39244fd7b 100644 --- a/liboverlay/Android.mk +++ b/liboverlay/Android.mk @@ -14,7 +14,8 @@ LOCAL_SRC_FILES := \ overlayUtils.cpp \ overlayMdp.cpp \ overlayRotator.cpp \ - mdpRotator.cpp \ - mdssRotator.cpp + overlayMdpRot.cpp \ + overlayMdssRot.cpp \ + pipes/overlayGenPipe.cpp include $(BUILD_SHARED_LIBRARY) diff --git a/liboverlay/mdpWrapper.h b/liboverlay/mdpWrapper.h index b1eb76cb6..255ffd7f4 100644 --- a/liboverlay/mdpWrapper.h +++ b/liboverlay/mdpWrapper.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011, Code Aurora Forum. All rights reserved. +* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -152,7 +152,7 @@ inline bool setOverlay(int fd, mdp_overlay& ov) { return true; } -inline bool endRotator(int fd, int sessionId) { +inline bool endRotator(int fd, uint32_t sessionId) { if (ioctl(fd, MSM_ROTATOR_IOCTL_FINISH, &sessionId) < 0) { ALOGE("Failed to call ioctl MSM_ROTATOR_IOCTL_FINISH err=%s", strerror(errno)); @@ -214,8 +214,12 @@ inline void dump(const char* const s, const mdp_overlay& ov) { dump("src", ov.src); dump("src_rect", ov.src_rect); dump("dst_rect", ov.dst_rect); + /* + Commented off to prevent verbose logging, since user_data could have 8 or so + fields which are mostly 0 dump("user_data", ov.user_data, sizeof(ov.user_data)/sizeof(ov.user_data[0])); + */ } inline void dump(const char* const s, const msmfb_img& ov) { ALOGE("%s msmfb_img w=%d h=%d format=%d %s", @@ -239,7 +243,7 @@ inline void dump(const char* const s, const uint32_t u[], uint32_t cnt) { } } inline void dump(const char* const s, const msm_rotator_img_info& rot) { - ALOGE("%s msm_rotator_img_info sessid=%d dstx=%d dsty=%d rot=%d, ena=%d", + ALOGE("%s msm_rotator_img_info sessid=%u dstx=%d dsty=%d rot=%d, ena=%d", s, rot.session_id, rot.dst_x, rot.dst_y, rot.rotations, rot.enable); dump("src", rot.src); @@ -247,7 +251,7 @@ inline void dump(const char* const s, const msm_rotator_img_info& rot) { dump("src_rect", rot.src_rect); } inline void dump(const char* const s, const msm_rotator_data_info& rot) { - ALOGE("%s msm_rotator_data_info sessid=%d verkey=%d", + ALOGE("%s msm_rotator_data_info sessid=%u verkey=%d", s, rot.session_id, rot.version_key); dump("src", rot.src); dump("dst", rot.dst); diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp index 170b8a940..7b7719c74 100644 --- a/liboverlay/overlay.cpp +++ b/liboverlay/overlay.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. +* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -27,180 +27,202 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "overlayUtils.h" -#include "overlayImpl.h" #include "overlay.h" +#include "pipes/overlayGenPipe.h" +#include "mdp_version.h" -#include "overlayMdp.h" -#include "overlayCtrlData.h" +#define PIPE_DEBUG 0 namespace overlay { +using namespace utils; -//Helper -bool isStateValid(const utils::eOverlayState& st) { - switch (st) { - case utils::OV_CLOSED: - ALOGE("Overlay %s failed, state is OV_CLOSED; set state first", - __FUNCTION__); - return false; - break; - case utils::OV_2D_VIDEO_ON_PANEL: - case utils::OV_2D_VIDEO_ON_PANEL_TV: - case utils::OV_2D_VIDEO_ON_TV: - case utils::OV_3D_VIDEO_ON_2D_PANEL: - case utils::OV_3D_VIDEO_ON_3D_PANEL: - case utils::OV_3D_VIDEO_ON_3D_TV: - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - case utils::OV_UI_MIRROR: - case utils::OV_2D_TRUE_UI_MIRROR: - case utils::OV_UI_VIDEO_TV: - case utils::OV_BYPASS_1_LAYER: - case utils::OV_BYPASS_2_LAYER: - case utils::OV_BYPASS_3_LAYER: - case utils::OV_DUAL_DISP: - break; - default: - OVASSERT(false, "%s Unknown state %d", __FUNCTION__, st); - return false; +Overlay::Overlay() { + int numPipes = 0; + int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); + if (mdpVersion > qdutils::MDP_V3_1) numPipes = 4; + if (mdpVersion >= qdutils::MDSS_V5) numPipes = 6; + + PipeBook::NUM_PIPES = numPipes; + for(int i = 0; i < PipeBook::NUM_PIPES; i++) { + mPipeBook[i].init(); } - return true; -} -Overlay::Overlay(): mOv(0) { + mDumpStr[0] = '\0'; } Overlay::~Overlay() { - mOv = mState.handleEvent(utils::OV_CLOSED, mOv); - delete mOv; - mOv = 0; -} - -bool Overlay::commit(utils::eDest dest) -{ - OVASSERT(mOv, - "%s Overlay and Rotator should be init at this point", - __FUNCTION__); - utils::eOverlayState st = mState.state(); - if(isStateValid(st)) { - if(!mOv->commit(dest)) { - ALOGE("Overlay %s failed", __FUNCTION__); - return false; - } + for(int i = 0; i < PipeBook::NUM_PIPES; i++) { + mPipeBook[i].destroy(); } - return true; } -bool Overlay::queueBuffer(int fd, uint32_t offset, - utils::eDest dest) -{ - OVASSERT(mOv, - "%s Overlay and Rotator should be init at this point", - __FUNCTION__); - utils::eOverlayState st = mState.state(); - if(isStateValid(st)) { - if(!mOv->queueBuffer(fd, offset, dest)) { - ALOGE("Overlay %s failed", __FUNCTION__); - return false; +void Overlay::configBegin() { + for(int i = 0; i < PipeBook::NUM_PIPES; i++) { + //Mark as available for this round. + PipeBook::resetUse(i); + PipeBook::resetAllocation(i); + } + mDumpStr[0] = '\0'; +} + +void Overlay::configDone() { + if(PipeBook::pipeUsageUnchanged()) return; + + for(int i = 0; i < PipeBook::NUM_PIPES; i++) { + if(PipeBook::isNotUsed(i)) { + //Forces UNSET on pipes, flushes rotator memory and session, closes + //fds + if(mPipeBook[i].valid()) { + char str[32]; + sprintf(str, "Unset pipe=%s dpy=%d; ", getDestStr((eDest)i), + mPipeBook[i].mDisplay); + strncat(mDumpStr, str, strlen(str)); + } + mPipeBook[i].destroy(); } } - return true; -} - -bool Overlay::setCrop(const utils::Dim& d, - utils::eDest dest) -{ - OVASSERT(mOv, - "%s Overlay and Rotator should be init at this point", - __FUNCTION__); - utils::eOverlayState st = mState.state(); - if(isStateValid(st)) { - if(!mOv->setCrop(d, dest)) { - ALOGE("Overlay %s failed", __FUNCTION__); - return false; + dump(); + PipeBook::save(); +} + +eDest Overlay::nextPipe(eMdpPipeType type, int dpy) { + eDest dest = OV_INVALID; + + for(int i = 0; i < PipeBook::NUM_PIPES; i++) { + //Match requested pipe type + if(type == OV_MDP_PIPE_ANY || type == getPipeType((eDest)i)) { + //If the pipe is not allocated to any display or used by the + //requesting display already in previous round. + if((mPipeBook[i].mDisplay == PipeBook::DPY_UNUSED || + mPipeBook[i].mDisplay == dpy) && + PipeBook::isNotAllocated(i)) { + dest = (eDest)i; + PipeBook::setAllocation(i); + break; + } } } - return true; -} -bool Overlay::setPosition(const utils::Dim& d, - utils::eDest dest) -{ - OVASSERT(mOv, - "%s Overlay and Rotator should be init at this point", - __FUNCTION__); - utils::eOverlayState st = mState.state(); - if(isStateValid(st)) { - if(!mOv->setPosition(d, dest)) { - ALOGE("Overlay %s failed", __FUNCTION__); - return false; + + if(dest != OV_INVALID) { + int index = (int)dest; + //If the pipe is not registered with any display OR if the pipe is + //requested again by the same display using it, then go ahead. + mPipeBook[index].mDisplay = dpy; + if(not mPipeBook[index].valid()) { + mPipeBook[index].mPipe = new GenericPipe(dpy); + char str[32]; + snprintf(str, 32, "Set pipe=%s dpy=%d; ", getDestStr(dest), dpy); + strncat(mDumpStr, str, strlen(str)); } + } else { + ALOGD_IF(PIPE_DEBUG, "Pipe unavailable type=%d display=%d", + (int)type, dpy); } - return true; + + return dest; } -bool Overlay::setTransform(const int orient, - utils::eDest dest) -{ - utils::eTransform transform = - static_cast<utils::eTransform>(orient); +bool Overlay::commit(utils::eDest dest) { + bool ret = false; + int index = (int)dest; + validate(index); - utils::eOverlayState st = mState.state(); - if(isStateValid(st)) { - if(!mOv->setTransform(transform, dest)) { - ALOGE("Overlay %s failed", __FUNCTION__); - return false; - } + if(mPipeBook[index].mPipe->commit()) { + ret = true; + PipeBook::setUse((int)dest); + } else { + PipeBook::resetUse((int)dest); } - return true; + return ret; } -bool Overlay::setSource(const utils::PipeArgs args[utils::MAX_PIPES], - utils::eDest dest) -{ - utils::PipeArgs margs[utils::MAX_PIPES] = { - args[0], args[1], args[2] }; - utils::eOverlayState st = mState.state(); - - if(isStateValid(st)) { - if (!mOv->setSource(margs, dest)) { - ALOGE("Overlay %s failed", __FUNCTION__); - return false; - } +bool Overlay::queueBuffer(int fd, uint32_t offset, + utils::eDest dest) { + int index = (int)dest; + bool ret = false; + validate(index); + //Queue only if commit() has succeeded (and the bit set) + if(PipeBook::isUsed((int)dest)) { + ret = mPipeBook[index].mPipe->queueBuffer(fd, offset); } - return true; + return ret; } -void Overlay::dump() const -{ - OVASSERT(mOv, - "%s Overlay and Rotator should be init at this point", - __FUNCTION__); - ALOGE("== Dump Overlay start =="); - mState.dump(); - mOv->dump(); - ALOGE("== Dump Overlay end =="); +void Overlay::setCrop(const utils::Dim& d, + utils::eDest dest) { + int index = (int)dest; + validate(index); + mPipeBook[index].mPipe->setCrop(d); } -void Overlay::setState(utils::eOverlayState s) { - mOv = mState.handleEvent(s, mOv); +void Overlay::setPosition(const utils::Dim& d, + utils::eDest dest) { + int index = (int)dest; + validate(index); + mPipeBook[index].mPipe->setPosition(d); } -utils::eOverlayState Overlay::getState() const { - return mState.state(); +void Overlay::setTransform(const int orient, + utils::eDest dest) { + int index = (int)dest; + validate(index); + + utils::eTransform transform = + static_cast<utils::eTransform>(orient); + mPipeBook[index].mPipe->setTransform(transform); + } -Overlay *Overlay::sInstance[] = {0}; +void Overlay::setSource(const utils::PipeArgs args, + utils::eDest dest) { + int index = (int)dest; + validate(index); -Overlay* Overlay::getInstance(int disp) { - if(sInstance[disp] == NULL) { - sInstance[disp] = new Overlay(); + PipeArgs newArgs(args); + if(dest == OV_VG0 || dest == OV_VG1) { + setMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE); + } else { + clearMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE); } - return sInstance[disp]; + mPipeBook[index].mPipe->setSource(newArgs); +} + +Overlay* Overlay::getInstance() { + if(sInstance == NULL) { + sInstance = new Overlay(); + } + return sInstance; } void Overlay::initOverlay() { if(utils::initOverlay() == -1) { - ALOGE("utils::initOverlay() ERROR!!"); + ALOGE("%s failed", __FUNCTION__); + } +} + +void Overlay::dump() const { + if(strlen(mDumpStr)) { //dump only on state change + ALOGD("%s\n", mDumpStr); + } +} + +void Overlay::PipeBook::init() { + mPipe = NULL; + mDisplay = DPY_UNUSED; +} + +void Overlay::PipeBook::destroy() { + if(mPipe) { + delete mPipe; + mPipe = NULL; } + mDisplay = DPY_UNUSED; } -} // overlay +Overlay* Overlay::sInstance = 0; +int Overlay::PipeBook::NUM_PIPES = 0; +int Overlay::PipeBook::sPipeUsageBitmap = 0; +int Overlay::PipeBook::sLastUsageBitmap = 0; +int Overlay::PipeBook::sAllocatedBitmap = 0; + +}; // namespace overlay diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h index f8f9c3495..523e3f78e 100644 --- a/liboverlay/overlay.h +++ b/liboverlay/overlay.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. +* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* * Neither the name of The Linux Foundation. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -31,66 +31,174 @@ #define OVERLAY_H #include "overlayUtils.h" -#include "overlayState.h" -#include "overlayImpl.h" namespace overlay { -/**/ +class GenericPipe; + class Overlay : utils::NoCopy { public: /* dtor close */ ~Overlay(); - /* Overlay related func */ - - /* Following is the same as the pure virt interface in ov impl */ - - bool setSource(const utils::PipeArgs args[utils::MAX_PIPES], - utils::eDest dest = utils::OV_PIPE_ALL); - bool setCrop(const utils::Dim& d, - utils::eDest dest = utils::OV_PIPE_ALL); - bool setTransform(const int orientation, - utils::eDest dest = utils::OV_PIPE_ALL); - bool setPosition(const utils::Dim& dim, - utils::eDest dest = utils::OV_PIPE_ALL); - bool commit(utils::eDest dest = utils::OV_PIPE_ALL); - - bool queueBuffer(int fd, uint32_t offset, - utils::eDest dest = utils::OV_PIPE_ALL); - - void dump() const; - - /* state related functions */ - void setState(utils::eOverlayState s); - - /* expose state */ - utils::eOverlayState getState() const; - - /* Closes open pipes */ + /* Marks the beginning of a drawing round, resets usage bits on pipes + * Should be called when drawing begins before any pipe config is done. + */ + void configBegin(); + + /* Marks the end of config for this drawing round + * Will do garbage collection of pipe objects and thus calling UNSETs, + * closing FDs, removing rotator objects and memory, if allocated. + * Should be called after all pipe configs are done. + */ + void configDone(); + + /* Returns an available pipe based on the type of pipe requested. When ANY + * is requested, the first available VG or RGB is returned. If no pipe is + * available for the display "dpy" then INV is returned. Note: If a pipe is + * assigned to a certain display, then it cannot be assigned to another + * display without being garbage-collected once */ + utils::eDest nextPipe(utils::eMdpPipeType, int dpy); + + void setSource(const utils::PipeArgs args, utils::eDest dest); + void setCrop(const utils::Dim& d, utils::eDest dest); + void setTransform(const int orientation, utils::eDest dest); + void setPosition(const utils::Dim& dim, utils::eDest dest); + bool commit(utils::eDest dest); + bool queueBuffer(int fd, uint32_t offset, utils::eDest dest); + + /* Closes open pipes, called during startup */ static void initOverlay(); - - /* Returns the per-display singleton instance of overlay */ - static Overlay* getInstance(int disp); + /* Returns the singleton instance of overlay */ + static Overlay* getInstance(); + /* Returns total of available ("unallocated") pipes */ + static int availablePipes(); private: /* Ctor setup */ - Overlay(); - - /* reset all pointers */ - void reset(); - - /* Holds the state, state transition logic - * In the meantime, using simple enum rather than - * a class */ - OverlayState mState; - - /* Holds the actual overlay impl, set when changing state*/ - OverlayImplBase *mOv; + explicit Overlay(); + /*Validate index range, abort if invalid */ + void validate(int index); + void dump() const; - /* Per-display Singleton Instance HWC_NUM_DISPLAY_TYPES */ - static Overlay *sInstance[2]; + /* Just like a Facebook for pipes, but much less profile info */ + struct PipeBook { + enum { DPY_PRIMARY, DPY_EXTERNAL, DPY_UNUSED }; + + void init(); + void destroy(); + /* Check if pipe exists and return true, false otherwise */ + bool valid(); + + /* Hardware pipe wrapper */ + GenericPipe *mPipe; + /* Display using this pipe. Refer to enums above */ + int mDisplay; + + /* operations on bitmap */ + static bool pipeUsageUnchanged(); + static void setUse(int index); + static void resetUse(int index); + static bool isUsed(int index); + static bool isNotUsed(int index); + static void save(); + + static void setAllocation(int index); + static void resetAllocation(int index); + static bool isAllocated(int index); + static bool isNotAllocated(int index); + /* Returns total of available ("unallocated") pipes */ + static int availablePipes(); + + static int NUM_PIPES; + + private: + //usage tracks if a successful commit happened. So a pipe could be + //allocated to a display, but it may not end up using it for various + //reasons. If one display actually uses a pipe then it amy not be + //used by another display, without an UNSET in between. + static int sPipeUsageBitmap; + static int sLastUsageBitmap; + //Tracks which pipe objects are allocated. This does not imply that they + //will actually be used. For example, a display might choose to acquire + //3 pipe objects in one shot and proceed with config only if it gets all + //3. The bitmap helps allocate different pipe objects on each request. + static int sAllocatedBitmap; + }; + + PipeBook mPipeBook[utils::OV_INVALID]; //Used as max + + /* Dump string */ + char mDumpStr[256]; + + /* Singleton Instance*/ + static Overlay *sInstance; }; -} // overlay +inline void Overlay::validate(int index) { + OVASSERT(index >=0 && index < PipeBook::NUM_PIPES, \ + "%s, Index out of bounds: %d", __FUNCTION__, index); + OVASSERT(mPipeBook[index].valid(), "Pipe does not exist %s", + utils::getDestStr((utils::eDest)index)); +} + +inline int Overlay::availablePipes() { + return PipeBook::availablePipes(); +} + +inline int Overlay::PipeBook::availablePipes() { + int used = 0; + int bmp = sAllocatedBitmap; + for(; bmp; used++) { + //clearing from lsb + bmp = bmp & (bmp - 1); + } + return NUM_PIPES - used; +} + +inline bool Overlay::PipeBook::valid() { + return (mPipe != NULL); +} + +inline bool Overlay::PipeBook::pipeUsageUnchanged() { + return (sPipeUsageBitmap == sLastUsageBitmap); +} + +inline void Overlay::PipeBook::setUse(int index) { + sPipeUsageBitmap |= (1 << index); +} + +inline void Overlay::PipeBook::resetUse(int index) { + sPipeUsageBitmap &= ~(1 << index); +} + +inline bool Overlay::PipeBook::isUsed(int index) { + return sPipeUsageBitmap & (1 << index); +} + +inline bool Overlay::PipeBook::isNotUsed(int index) { + return !isUsed(index); +} + +inline void Overlay::PipeBook::save() { + sLastUsageBitmap = sPipeUsageBitmap; +} + +inline void Overlay::PipeBook::setAllocation(int index) { + sAllocatedBitmap |= (1 << index); +} + +inline void Overlay::PipeBook::resetAllocation(int index) { + sAllocatedBitmap &= ~(1 << index); +} + +inline bool Overlay::PipeBook::isAllocated(int index) { + return sAllocatedBitmap & (1 << index); +} + +inline bool Overlay::PipeBook::isNotAllocated(int index) { + return !isAllocated(index); +} + +}; // overlay #endif // OVERLAY_H diff --git a/liboverlay/overlayCtrl.cpp b/liboverlay/overlayCtrl.cpp index 9047f3eaa..ac4a2965b 100644 --- a/liboverlay/overlayCtrl.cpp +++ b/liboverlay/overlayCtrl.cpp @@ -77,129 +77,8 @@ bool Ctrl::setCrop(const utils::Dim& d) utils::ActionSafe* utils::ActionSafe::sActionSafe = NULL; -utils::Dim Ctrl::getAspectRatio(const utils::Whf& whf) const -{ - utils::Whf inWhf(whf.w, whf.h, mMdp.getSrcWhf().format); - utils::Whf tmpwhf(inWhf); - uint32_t fbWidth = mInfo.mFBWidth; - uint32_t fbHeight = mInfo.mFBHeight; - - /* Calculate the width and height if it is YUV TILE format*/ - if (inWhf.format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) { - tmpwhf.w = whf.w - (utils::alignup(whf.w, 64) - whf.w); - tmpwhf.h = whf.h - (utils::alignup(whf.h, 32) - whf.h); - } - if (inWhf.w * fbHeight > fbWidth * inWhf.h) { - inWhf.h = fbWidth * inWhf.h / inWhf.w; - inWhf.w = fbWidth; - } else if (inWhf.w * fbHeight < fbWidth * inWhf.h) { - inWhf.w = fbHeight * inWhf.w / inWhf.h; - inWhf.h = fbHeight; - } else { - inWhf.w = fbWidth; - inWhf.h = fbHeight; - } - /* Scaling of upto a max of 8 times supported */ - if (inWhf.w > (tmpwhf.w * utils::HW_OV_MAGNIFICATION_LIMIT)){ - inWhf.w = utils::HW_OV_MAGNIFICATION_LIMIT * tmpwhf.w; - } - if(inWhf.h > (tmpwhf.h * utils::HW_OV_MAGNIFICATION_LIMIT)) { - inWhf.h = utils::HW_OV_MAGNIFICATION_LIMIT * tmpwhf.h; - } - if (inWhf.w > fbWidth) inWhf.w = fbWidth; - if (inWhf.h > fbHeight) inWhf.h = fbHeight; - - float asWidth = utils::ActionSafe::getInstance()->getHeight(); - float asHeight = utils::ActionSafe::getInstance()->getWidth(); - - inWhf.w = inWhf.w * (1.0f - asWidth / 100.0f); - inWhf.h = inWhf.h * (1.0f - asHeight / 100.0f); - - uint32_t x = (fbWidth - inWhf.w) / 2.0; - uint32_t y = (fbHeight - inWhf.h) / 2.0; - return utils::Dim(x, y, inWhf.w, inWhf.h); -} - utils::FrameBufferInfo* utils::FrameBufferInfo::sFBInfoInstance = 0; -// This function gets the destination position for external display -// based on the position and aspect ratio of the primary -utils::Dim Ctrl::getAspectRatio(const utils::Dim& dim) const { - float priWidth = utils::FrameBufferInfo::getInstance()->getWidth(); - float priHeight = utils::FrameBufferInfo::getInstance()->getHeight(); - float fbWidth = mInfo.mFBWidth; - float fbHeight = mInfo.mFBHeight; - float wRatio = 1.0; - float hRatio = 1.0; - float xRatio = 1.0; - float yRatio = 1.0; - utils::Dim inDim(dim); - - int xPos = 0; - int yPos = 0; - int tmp = 0; - utils::Dim tmpDim; - switch(inDim.o) { - case MDP_ROT_NOP: - case MDP_ROT_180: - { - utils::Whf whf((uint32_t) priWidth, (uint32_t) priHeight, 0); - tmpDim = getAspectRatio(whf); - xPos = tmpDim.x; - yPos = tmpDim.y; - fbWidth = tmpDim.w; - fbHeight = tmpDim.h; - - if (inDim.o == MDP_ROT_180) { - inDim.x = priWidth - (inDim.x + inDim.w); - inDim.y = priHeight - (inDim.y + inDim.h); - } - break; - } - case MDP_ROT_90: - case MDP_ROT_270: - { - if(inDim.o == MDP_ROT_90) { - tmp = inDim.y; - inDim.y = priWidth - (inDim.x + inDim.w); - inDim.x = tmp; - } - else if (inDim.o == MDP_ROT_270) { - tmp = inDim.x; - inDim.x = priHeight - (inDim.y + inDim.h); - inDim.y = tmp; - } - - // Swap the destination width/height - utils::swapWidthHeight(inDim.w, inDim.h); - // Swap width/height for primary - utils::swapWidthHeight(priWidth, priHeight); - utils::Whf whf((uint32_t) priWidth, (uint32_t) priHeight, 0); - tmpDim = getAspectRatio(whf); - xPos = tmpDim.x; - yPos = tmpDim.y; - fbWidth = tmpDim.w; - fbHeight = tmpDim.h; - break; - } - default: - ALOGE("%s: Unknown Orientation", __FUNCTION__); - break; - } - - // Calculate the position - xRatio = inDim.x/priWidth; - yRatio = inDim.y/priHeight; - wRatio = inDim.w/priWidth; - hRatio = inDim.h/priHeight; - - return utils::Dim((xRatio * fbWidth) + xPos, // x - (yRatio * fbHeight) + yPos, // y - (wRatio * fbWidth), // width - (hRatio * fbHeight), // height - inDim.o); // orientation -} - void Ctrl::dump() const { ALOGE("== Dump Ctrl start =="); mInfo.dump("mInfo"); diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h index 3c7eb42ec..f4c95f9d1 100644 --- a/liboverlay/overlayCtrlData.h +++ b/liboverlay/overlayCtrlData.h @@ -72,8 +72,6 @@ public: int getPipeId() const; /* ctrl fd */ int getFd() const; - utils::Dim getAspectRatio(const utils::Whf& whf) const; - utils::Dim getAspectRatio(const utils::Dim& dim) const; /* access for screen info */ utils::ScreenInfo getScreenInfo() const; diff --git a/liboverlay/overlayImpl.h b/liboverlay/overlayImpl.h deleted file mode 100644 index 1d226949d..000000000 --- a/liboverlay/overlayImpl.h +++ /dev/null @@ -1,634 +0,0 @@ -/* -* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following -* disclaimer in the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its -* contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef OVERLAY_IMPL_H -#define OVERLAY_IMPL_H - -#include "overlayUtils.h" -#include "overlayRotator.h" - -namespace overlay { - -// Interface only. No member, no definiton (except ~ which can -// also be =0 with impl in cpp) -class OverlayImplBase { -public: - /* empty dtor. can be =0 with cpp impl*/ - virtual ~OverlayImplBase() {} - - /* Init pipe/rot for one dest */ - virtual bool initPipe(RotatorBase* rot, utils::eDest dest) = 0; - - /* Close pipe/rot for all specified dest */ - virtual bool closePipe(utils::eDest dest) = 0; - - /* Copy specified pipe/rot from ov passed in (used by state machine only) */ - virtual bool copyOvPipe(OverlayImplBase* ov, utils::eDest dest) = 0; - - /* Init all pipes - * To init just one pipe, use initPipe() - * */ - virtual bool init(RotatorBase* rot0, - RotatorBase* rot1, - RotatorBase* rot2) = 0; - - /* Close all pipes - * To close just one pipe, use closePipe() - * */ - virtual bool close() = 0; - - /* - * Commit changes to the overlay - * */ - virtual bool commit(utils::eDest dest = utils::OV_PIPE_ALL) = 0; - - /* Queue buffer with fd from an offset*/ - virtual bool queueBuffer(int fd, uint32_t offset, - utils::eDest dest = utils::OV_PIPE_ALL) = 0; - - /* Crop existing destination using Dim coordinates */ - virtual bool setCrop(const utils::Dim& d, - utils::eDest dest = utils::OV_PIPE_ALL) = 0; - - /* Set new position using Dim */ - virtual bool setPosition(const utils::Dim& dim, - utils::eDest dest = utils::OV_PIPE_ALL) = 0; - - /* Set parameters - usually needed for Rotator, but would - * be passed down the stack as well */ - virtual bool setTransform(const utils::eTransform& param, - utils::eDest dest = utils::OV_PIPE_ALL) = 0; - - /* Set new source including orientation */ - virtual bool setSource(const utils::PipeArgs[utils::MAX_PIPES], - utils::eDest dest = utils::OV_PIPE_ALL) = 0; - - /* Dump underlying state */ - virtual void dump() const = 0; -}; - -class NullPipe { -public: - bool init(RotatorBase* rot) { return true; } - bool close() { return true; } - bool start(const utils::PipeArgs& args) { return true; } - bool commit() { return true; } - bool setCrop(const utils::Dim& d) { return true; } - bool setPosition(const utils::Dim& dim) { return true; } - bool setTransform(const utils::eTransform& param) { return true; } - bool setSource(const utils::PipeArgs& args) { return true; } - bool queueBuffer(int fd, uint32_t offset) { return true; } - void dump() const {} -}; - -/* -* Each pipe is not specific to a display (primary/external). The order in the -* template params, will setup the priorities of the pipes. -* */ -template <class P0, class P1=NullPipe, class P2=NullPipe> -class OverlayImpl : public OverlayImplBase { -public: - typedef P0 pipe0; - typedef P1 pipe1; - typedef P2 pipe2; - - /* ctor */ - OverlayImpl(); - - /* - * Comments of the below functions are the same as the one - * in OverlayImplBase. - * */ - virtual ~OverlayImpl(); - - virtual bool initPipe(RotatorBase* rot, utils::eDest dest); - virtual bool closePipe(utils::eDest dest); - virtual bool copyOvPipe(OverlayImplBase* ov, utils::eDest dest); - - virtual bool init(RotatorBase* rot0, - RotatorBase* rot1, - RotatorBase* rot2); - virtual bool close(); - virtual bool commit(utils::eDest dest = utils::OV_PIPE_ALL); - virtual bool setCrop(const utils::Dim& d, - utils::eDest dest = utils::OV_PIPE_ALL); - virtual bool setPosition(const utils::Dim& dim, - utils::eDest dest = utils::OV_PIPE_ALL); - virtual bool setTransform(const utils::eTransform& param, - utils::eDest dest = utils::OV_PIPE_ALL); - virtual bool setSource(const utils::PipeArgs[utils::MAX_PIPES], - utils::eDest dest = utils::OV_PIPE_ALL); - virtual bool queueBuffer(int fd, uint32_t offset, - utils::eDest dest = utils::OV_PIPE_ALL); - virtual void dump() const; - -private: - P0* mPipe0; - P1* mPipe1; - P2* mPipe2; - // More Px here in the future as needed - - /* */ - - /* Each Px has it's own Rotator here. - * will pass rotator to the lower layer in stack - * but only overlay is allowed to control the lifetime - * of the rotator instace */ - RotatorBase* mRotP0; - RotatorBase* mRotP1; - RotatorBase* mRotP2; -}; - - - -//-----------Inlines and Template defn--------------------------------- - -/**** OverlayImpl ****/ - -template <class P0, class P1, class P2> -OverlayImpl<P0, P1, P2>::OverlayImpl() : - mPipe0(0), mPipe1(0), mPipe2(0), - mRotP0(0), mRotP1(0), mRotP2(0) -{ - //Do not create a pipe here. - //Either initPipe can create a pipe OR - //copyOvPipe can assign a pipe. -} - -template <class P0, class P1, class P2> -OverlayImpl<P0, P1, P2>::~OverlayImpl() -{ - //Do not delete pipes. - //closePipe will close and delete. -} - -/* Init only one pipe/rot pair per call */ -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::initPipe(RotatorBase* rot, utils::eDest dest) -{ - OVASSERT(rot, "%s: OverlayImpl rot is null", __FUNCTION__); - OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d", - __FUNCTION__, dest); - - bool ret = true; - - if (utils::OV_PIPE0 & dest) { - ALOGE_IF(DEBUG_OVERLAY, "init pipe0"); - - mRotP0 = rot; - ret = mRotP0->init(); - if(!ret) { - ALOGE("%s: OverlayImpl rot0 failed to init", __FUNCTION__); - return false; - } - - mPipe0 = new P0(); - OVASSERT(mPipe0, "%s: OverlayImpl pipe0 is null", __FUNCTION__); - ret = mPipe0->init(rot); - if(!ret) { - ALOGE("%s: OverlayImpl pipe0 failed to init", __FUNCTION__); - return false; - } - - return ret; - } - - if (utils::OV_PIPE1 & dest) { - ALOGE_IF(DEBUG_OVERLAY, "init pipe1"); - - mRotP1 = rot; - ret = mRotP1->init(); - if(!ret) { - ALOGE("%s: OverlayImpl rot1 failed to init", __FUNCTION__); - return false; - } - - mPipe1 = new P1(); - OVASSERT(mPipe1, "%s: OverlayImpl pipe1 is null", __FUNCTION__); - ret = mPipe1->init(rot); - if(!ret) { - ALOGE("%s: OverlayImpl pipe1 failed to init", __FUNCTION__); - return false; - } - - return ret; - } - - if (utils::OV_PIPE2 & dest) { - ALOGE_IF(DEBUG_OVERLAY, "init pipe2"); - - mRotP2 = rot; - ret = mRotP2->init(); - if(!ret) { - ALOGE("%s: OverlayImpl rot2 failed to init", __FUNCTION__); - return false; - } - - mPipe2 = new P2(); - OVASSERT(mPipe2, "%s: OverlayImpl pipe2 is null", __FUNCTION__); - ret = mPipe2->init(rot); - if(!ret) { - ALOGE("%s: OverlayImpl pipe2 failed to init", __FUNCTION__); - return false; - } - - return ret; - } - - // Should have returned by here - return false; -} - -/* Close pipe/rot for all specified dest */ -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::closePipe(utils::eDest dest) -{ - OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d", - __FUNCTION__, dest); - - if (utils::OV_PIPE0 & dest) { - // Close pipe0 - OVASSERT(mPipe0, "%s: OverlayImpl pipe0 is null", __FUNCTION__); - ALOGE_IF(DEBUG_OVERLAY, "Close pipe0"); - if (!mPipe0->close()) { - ALOGE("%s: OverlayImpl failed to close pipe0", __FUNCTION__); - return false; - } - delete mPipe0; - mPipe0 = 0; - - // Close the rotator for pipe0 - OVASSERT(mRotP0, "%s: OverlayImpl rot0 is null", __FUNCTION__); - if (!mRotP0->close()) { - ALOGE("%s: OverlayImpl failed to close rot for pipe0", __FUNCTION__); - } - delete mRotP0; - mRotP0 = 0; - } - - if (utils::OV_PIPE1 & dest) { - // Close pipe1 - OVASSERT(mPipe1, "%s: OverlayImpl pipe1 is null", __FUNCTION__); - ALOGE_IF(DEBUG_OVERLAY, "Close pipe1"); - if (!mPipe1->close()) { - ALOGE("%s: OverlayImpl failed to close pipe1", __FUNCTION__); - return false; - } - delete mPipe1; - mPipe1 = 0; - - // Close the rotator for pipe1 - OVASSERT(mRotP1, "%s: OverlayImpl rot1 is null", __FUNCTION__); - if (!mRotP1->close()) { - ALOGE("%s: OverlayImpl failed to close rot for pipe1", __FUNCTION__); - } - delete mRotP1; - mRotP1 = 0; - } - - if (utils::OV_PIPE2 & dest) { - // Close pipe2 - OVASSERT(mPipe2, "%s: OverlayImpl pipe2 is null", __FUNCTION__); - ALOGE_IF(DEBUG_OVERLAY, "Close pipe2"); - if (!mPipe2->close()) { - ALOGE("%s: OverlayImpl failed to close pipe2", __FUNCTION__); - return false; - } - delete mPipe2; - mPipe2 = 0; - - // Close the rotator for pipe2 - OVASSERT(mRotP2, "%s: OverlayImpl rot2 is null", __FUNCTION__); - if (!mRotP2->close()) { - ALOGE("%s: OverlayImpl failed to close rot for pipe2", __FUNCTION__); - } - delete mRotP2; - mRotP2 = 0; - } - - return true; -} - -/* Copy pipe/rot from ov for all specified dest */ -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::copyOvPipe(OverlayImplBase* ov, - utils::eDest dest) -{ - OVASSERT(ov, "%s: OverlayImpl ov is null", __FUNCTION__); - OVASSERT(utils::isValidDest(dest), "%s: OverlayImpl invalid dest=%d", - __FUNCTION__, dest); - - OverlayImpl<P0, P1, P2>* ovimpl = static_cast<OverlayImpl<P0, P1, P2>*>(ov); - - if (utils::OV_PIPE0 & dest) { - mPipe0 = ovimpl->mPipe0; - mRotP0 = ovimpl->mRotP0; - ovimpl->mPipe0 = 0; - ovimpl->mRotP0 = 0; - } - - if (utils::OV_PIPE1 & dest) { - mPipe1 = ovimpl->mPipe1; - mRotP1 = ovimpl->mRotP1; - ovimpl->mPipe1 = 0; - ovimpl->mRotP1 = 0; - } - - if (utils::OV_PIPE2 & dest) { - mPipe2 = ovimpl->mPipe2; - mRotP2 = ovimpl->mRotP2; - ovimpl->mPipe2 = 0; - ovimpl->mRotP2 = 0; - } - - return true; -} - -/* Init all pipes/rot */ -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::init(RotatorBase* rot0, - RotatorBase* rot1, - RotatorBase* rot2) -{ - if (!this->initPipe(rot0, utils::OV_PIPE0)) { - if (!this->close()) { - ALOGE("%s: failed to close at least one pipe", __FUNCTION__); - } - return false; - } - - if (!this->initPipe(rot1, utils::OV_PIPE1)) { - if (!this->close()) { - ALOGE("%s: failed to close at least one pipe", __FUNCTION__); - } - return false; - } - - if (!this->initPipe(rot2, utils::OV_PIPE2)) { - if (!this->close()) { - ALOGE("%s: failed to close at least one pipe", __FUNCTION__); - } - return false; - } - - return true; -} - -/* Close all pipes/rot */ -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::close() -{ - if (!this->closePipe(utils::OV_PIPE_ALL)) { - return false; - } - - return true; -} - -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::commit(utils::eDest dest) -{ - OVASSERT(mPipe0 && mPipe1 && mPipe2, - "%s: Pipes are null p0=%p p1=%p p2=%p", - __FUNCTION__, mPipe0, mPipe1, mPipe2); - - if (utils::OV_PIPE0 & dest) { - if(!mPipe0->commit()) { - ALOGE("OverlayImpl p0 failed to commit"); - return false; - } - } - - if (utils::OV_PIPE1 & dest) { - if(!mPipe1->commit()) { - ALOGE("OverlayImpl p1 failed to commit"); - return false; - } - } - - if (utils::OV_PIPE2 & dest) { - if(!mPipe2->commit()) { - ALOGE("OverlayImpl p2 failed to commit"); - return false; - } - } - - return true; -} - -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::setCrop(const utils::Dim& d, utils::eDest dest) -{ - OVASSERT(mPipe0 && mPipe1 && mPipe2, - "%s: Pipes are null p0=%p p1=%p p2=%p", - __FUNCTION__, mPipe0, mPipe1, mPipe2); - - if (utils::OV_PIPE0 & dest) { - if(!mPipe0->setCrop(d)) { - ALOGE("OverlayImpl p0 failed to crop"); - return false; - } - } - - if (utils::OV_PIPE1 & dest) { - if(!mPipe1->setCrop(d)) { - ALOGE("OverlayImpl p1 failed to crop"); - return false; - } - } - - if (utils::OV_PIPE2 & dest) { - if(!mPipe2->setCrop(d)) { - ALOGE("OverlayImpl p2 failed to crop"); - return false; - } - } - - return true; -} - -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::setPosition(const utils::Dim& d, - utils::eDest dest) -{ - OVASSERT(mPipe0 && mPipe1 && mPipe2, - "%s: Pipes are null p0=%p p1=%p p2=%p", - __FUNCTION__, mPipe0, mPipe1, mPipe2); - - if (utils::OV_PIPE0 & dest) { - if(!mPipe0->setPosition(d)) { - ALOGE("OverlayImpl p0 failed to setpos"); - return false; - } - } - - if (utils::OV_PIPE1 & dest) { - if(!mPipe1->setPosition(d)) { - ALOGE("OverlayImpl p1 failed to setpos"); - return false; - } - } - - if (utils::OV_PIPE2 & dest) { - if(!mPipe2->setPosition(d)) { - ALOGE("OverlayImpl p2 failed to setpos"); - return false; - } - } - - return true; -} - -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::setTransform(const utils::eTransform& param, - utils::eDest dest) -{ - OVASSERT(mPipe0 && mPipe1 && mPipe2, - "%s: Pipes are null p0=%p p1=%p p2=%p", - __FUNCTION__, mPipe0, mPipe1, mPipe2); - - if (utils::OV_PIPE0 & dest) { - if(!mPipe0->setTransform(param)) { - ALOGE("OverlayImpl p0 failed to setparam"); - return false; - } - } - - if (utils::OV_PIPE1 & dest) { - if(!mPipe1->setTransform(param)) { - ALOGE("OverlayImpl p1 failed to setparam"); - return false; - } - } - - if (utils::OV_PIPE2 & dest) { - if(!mPipe2->setTransform(param)) { - ALOGE("OverlayImpl p2 failed to setparam"); - return false; - } - } - - return true; -} - -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::setSource( - const utils::PipeArgs args[utils::MAX_PIPES], - utils::eDest dest) -{ - OVASSERT(mPipe0 && mPipe1 && mPipe2, - "%s: Pipes are null p0=%p p1=%p p2=%p", - __FUNCTION__, mPipe0, mPipe1, mPipe2); - - if (utils::OV_PIPE0 & dest) { - if(!mPipe0->setSource(args[0])) { - ALOGE("OverlayImpl p0 failed to setsrc"); - return false; - } - } - - if (utils::OV_PIPE1 & dest) { - if(!mPipe1->setSource(args[1])) { - ALOGE("OverlayImpl p1 failed to setsrc"); - return false; - } - } - - if (utils::OV_PIPE2 & dest) { - if(!mPipe2->setSource(args[2])) { - ALOGE("OverlayImpl p2 failed to setsrc"); - return false; - } - } - - return true; -} - -template <class P0, class P1, class P2> -bool OverlayImpl<P0, P1, P2>::queueBuffer(int fd, uint32_t offset, - utils::eDest dest) -{ - OVASSERT(mPipe0 && mPipe1 && mPipe2, - "%s: Pipes are null p0=%p p1=%p p2=%p", - __FUNCTION__, mPipe0, mPipe1, mPipe2); - - if (utils::OV_PIPE0 & dest) { - if(!mPipe0->queueBuffer(fd, offset)) { - ALOGE("OverlayImpl p0 failed to queueBuffer"); - return false; - } - } - - if (utils::OV_PIPE1 & dest) { - if(!mPipe1->queueBuffer(fd, offset)) { - ALOGE("OverlayImpl p1 failed to queueBuffer"); - return false; - } - } - - if (utils::OV_PIPE2 & dest) { - if(!mPipe2->queueBuffer(fd, offset)) { - ALOGE("OverlayImpl p2 failed to queueBuffer"); - return false; - } - } - - return true; -} - -template <class P0, class P1, class P2> -void OverlayImpl<P0, P1, P2>::dump() const -{ - OVASSERT(mPipe0 && mPipe1 && mPipe2, - "%s: Pipes are null p0=%p p1=%p p2=%p", - __FUNCTION__, mPipe0, mPipe1, mPipe2); - ALOGE("== Dump OverlayImpl dump start ROT p0 =="); - mRotP0->dump(); - ALOGE("== Dump OverlayImpl dump end ROT p0 =="); - ALOGE("== Dump OverlayImpl dump start ROT p1 =="); - mRotP1->dump(); - ALOGE("== Dump OverlayImpl dump end ROT p1 =="); - ALOGE("== Dump OverlayImpl dump start ROT p2 =="); - mRotP2->dump(); - ALOGE("== Dump OverlayImpl dump end ROT p2 =="); - ALOGE("== Dump OverlayImpl dump start p0 =="); - mPipe0->dump(); - ALOGE("== Dump OverlayImpl dump end p0 =="); - ALOGE("== Dump OverlayImpl dump start p1 =="); - mPipe1->dump(); - ALOGE("== Dump OverlayImpl dump end p1 =="); - ALOGE("== Dump OverlayImpl dump start p2 =="); - mPipe2->dump(); - ALOGE("== Dump OverlayImpl dump end p2 =="); -} - - -} // overlay - -#endif // OVERLAY_IMPL_H diff --git a/liboverlay/mdpRotator.cpp b/liboverlay/overlayMdpRot.cpp index cb18dac80..f96ddb7ca 100644 --- a/liboverlay/mdpRotator.cpp +++ b/liboverlay/overlayMdpRot.cpp @@ -1,18 +1,20 @@ /* -* Copyright (C) 2008 The Android Open Source Project -* Copyright (c) 2010-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. + * Copyright (C) 2008 The Android Open Source Project + * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * Not a Contribution, Apache license notifications and license are retained + * for attribution purposes only. + * + * 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 "overlayUtils.h" @@ -22,6 +24,48 @@ namespace ovutils = overlay::utils; namespace overlay { +MdpRot::MdpRot() { + reset(); + init(); +} + +MdpRot::~MdpRot() { close(); } + +void MdpRot::setEnable() { mRotImgInfo.enable = 1; } + +void MdpRot::setDisable() { mRotImgInfo.enable = 0; } + +bool MdpRot::enabled() const { return mRotImgInfo.enable; } + +void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = r; } + +int MdpRot::getDstMemId() const { + return mRotDataInfo.dst.memory_id; +} + +uint32_t MdpRot::getDstOffset() const { + return mRotDataInfo.dst.offset; +} + +uint32_t MdpRot::getSessId() const { return mRotImgInfo.session_id; } + +void MdpRot::setSrcFB() { + mRotDataInfo.src.flags |= MDP_MEMORY_ID_TYPE_FB; +} + +void MdpRot::save() { + mLSRotImgInfo = mRotImgInfo; +} + +bool MdpRot::rotConfChanged() const { + // 0 means same + if(0 == ::memcmp(&mRotImgInfo, &mLSRotImgInfo, + sizeof (msm_rotator_img_info))) { + return false; + } + return true; +} + bool MdpRot::init() { if(!mFd.open(Res::rotPath, O_RDWR)){ @@ -116,9 +160,9 @@ bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz) bool MdpRot::close() { bool success = true; - if(mFd.valid() && (getSessId() > 0)) { + if(mFd.valid() && (getSessId() != 0)) { if(!mdp_wrapper::endRotator(mFd.getFD(), getSessId())) { - ALOGE("Mdp Rot error endRotator, fd=%d sessId=%d", + ALOGE("Mdp Rot error endRotator, fd=%d sessId=%u", mFd.getFD(), getSessId()); success = false; } diff --git a/liboverlay/mdssRotator.cpp b/liboverlay/overlayMdssRot.cpp index 52d6e678a..355d8712b 100644 --- a/liboverlay/mdssRotator.cpp +++ b/liboverlay/overlayMdssRot.cpp @@ -1,30 +1,56 @@ /* -* Copyright (C) 2008 The Android Open Source Project -* Copyright (c) 2010-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. + * Copyright (C) 2008 The Android Open Source Project + * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * Not a Contribution, Apache license notifications and license are retained + * for attribution purposes only. + * + * 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 "overlayUtils.h" #include "overlayRotator.h" -#ifndef MDSS_MDP_ROT_ONLY -#define MDSS_MDP_ROT_ONLY 0x80 -#endif - namespace ovutils = overlay::utils; namespace overlay { +MdssRot::MdssRot() { + reset(); + init(); +} + +MdssRot::~MdssRot() { close(); } + +void MdssRot::setEnable() { mEnabled = true; } + +void MdssRot::setDisable() { mEnabled = false; } + +bool MdssRot::enabled() const { return mEnabled; } + +void MdssRot::setRotations(uint32_t flags) { mRotInfo.flags |= flags; } + +int MdssRot::getDstMemId() const { + return mRotData.dst_data.memory_id; +} + +uint32_t MdssRot::getDstOffset() const { + return mRotData.dst_data.offset; +} + +uint32_t MdssRot::getSessId() const { return mRotInfo.id; } + +void MdssRot::setSrcFB() { + mRotData.data.flags |= MDP_MEMORY_ID_TYPE_FB; +} bool MdssRot::init() { if(!utils::openDev(mFd, 0, Res::fbPath, O_RDWR)) { @@ -175,7 +201,7 @@ bool MdssRot::close() { ALOGE("MdssRot::close unsetOverlay failed, fd=%d sessId=%d", mFd.getFD(), getSessId()); success = false; - } + } } if (!mFd.close()) { diff --git a/liboverlay/overlayRotator.cpp b/liboverlay/overlayRotator.cpp index 377265f00..956ea2bf7 100644 --- a/liboverlay/overlayRotator.cpp +++ b/liboverlay/overlayRotator.cpp @@ -1,18 +1,20 @@ /* -* Copyright (C) 2008 The Android Open Source Project -* Copyright (c) 2010-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. + * Copyright (C) 2008 The Android Open Source Project + * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + * Not a Contribution, Apache license notifications and license are retained + * for attribution purposes only. + * + * 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 "overlayRotator.h" @@ -23,7 +25,21 @@ namespace ovutils = overlay::utils; namespace overlay { -int IRotatorHw::getRotatorHwType() { +Rotator::~Rotator() {} + +Rotator* Rotator::getRotator() { + int type = getRotatorHwType(); + if(type == TYPE_MDP) { + return new MdpRot(); //will do reset + } else if(type == TYPE_MDSS) { + return new MdssRot(); + } else { + ALOGE("%s Unknown h/w type %d", __FUNCTION__, type); + return NULL; + } +} + +int Rotator::getRotatorHwType() { int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); if (mdpVersion == qdutils::MDSS_V5) return TYPE_MDSS; diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h index 075e46dec..4ef33f3c7 100644 --- a/liboverlay/overlayRotator.h +++ b/liboverlay/overlayRotator.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011, Code Aurora Forum. All rights reserved. +* Copyright (c) 2011, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* * Neither the name of The Linux Foundation. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -38,15 +38,11 @@ namespace overlay { -class IRotatorHw; -/* -* RotatorBase. No members, just interface. -* can also be =0 with empty impl in cpp. -* */ -class RotatorBase { +class Rotator +{ public: - /* Most of the below are No op funcs for RotatorBase */ - virtual ~RotatorBase() {} + enum { TYPE_MDP, TYPE_MDSS }; + virtual ~Rotator(); virtual bool init() = 0; virtual bool close() = 0; virtual void setSource(const utils::Whf& wfh) = 0; @@ -54,123 +50,27 @@ public: virtual void setTransform(const utils::eTransform& rot, const bool& rotUsed) = 0; virtual bool commit() = 0; - virtual bool queueBuffer(int fd, uint32_t offset) = 0; - - virtual void setEnable() = 0; - virtual void setDisable() = 0; virtual void setRotations(uint32_t r) = 0; virtual void setSrcFB() = 0; - - virtual bool enabled() const = 0; - virtual uint32_t getSessId() const = 0; virtual int getDstMemId() const = 0; virtual uint32_t getDstOffset() const = 0; - virtual void dump() const = 0; - -protected: - //Hardware specific rotator impl. - IRotatorHw *mRot; -}; - -/* - * Rotator Hw Interface. Any hardware specific implementation should inherit - * from this. - */ -class IRotatorHw { -public: - /* Most of the below are No op funcs for RotatorBase */ - virtual ~IRotatorHw() {} - /* init fd for rotator. map bufs is defered */ - virtual bool init() = 0; - /* close fd, mem */ - virtual bool close() = 0; - /* set src */ - virtual void setSource(const utils::Whf& wfh) = 0; - /* set mdp flags, will use only stuff necessary for rotator */ - virtual void setFlags(const utils::eMdpFlags& flags) = 0; - /* Set rotation and calculate */ - virtual void setTransform(const utils::eTransform& rot, - const bool& rotUsed) = 0; - /* calls underlying wrappers to start rotator */ - virtual bool commit() = 0; - /* Lazy buffer allocation. queue buffer */ - virtual bool queueBuffer(int fd, uint32_t offset) = 0; - /* set enable/disable flag */ virtual void setEnable() = 0; virtual void setDisable() = 0; - /* set rotator flag*/ - virtual void setRotations(uint32_t r) = 0; - /* Mark src as FB (non-ION) */ - virtual void setSrcFB() = 0; - /* Retusn true if rotator enabled */ - virtual bool enabled() const = 0; - /* returns rotator session id */ + virtual bool enabled () const = 0; virtual uint32_t getSessId() const = 0; - /* get dst (for offset and memory id) non-virt */ - virtual int getDstMemId() const = 0; - virtual uint32_t getDstOffset() const = 0; - /* dump the state of the object */ + virtual bool queueBuffer(int fd, uint32_t offset) = 0; virtual void dump() const = 0; + static Rotator *getRotator(); - enum { TYPE_MDP, TYPE_MDSS }; +protected: + explicit Rotator() {} + +private: /*Returns rotator h/w type */ static int getRotatorHwType(); }; /* -* Actual Rotator impl. -* */ -class Rotator : public RotatorBase -{ -public: - explicit Rotator(); - virtual ~Rotator(); - virtual bool init(); - virtual bool close(); - virtual void setSource(const utils::Whf& wfh); - virtual void setFlags(const utils::eMdpFlags& flags); - virtual void setTransform(const utils::eTransform& rot, - const bool& rotUsed); - virtual bool commit(); - virtual void setRotations(uint32_t r); - virtual void setSrcFB(); - virtual int getDstMemId() const; - virtual uint32_t getDstOffset() const; - virtual void setEnable(); - virtual void setDisable(); - virtual bool enabled () const; - virtual uint32_t getSessId() const; - virtual bool queueBuffer(int fd, uint32_t offset); - virtual void dump() const; -}; - -/* -* Null/Empty impl of RotatorBase -* */ -class NullRotator : public RotatorBase { -public: - /* Most of the below are No op funcs for RotatorBase */ - virtual ~NullRotator(); - virtual bool init(); - virtual bool close(); - virtual void setSource(const utils::Whf& wfh); - virtual void setFlags(const utils::eMdpFlags& flags); - virtual void setTransform(const utils::eTransform& rot, - const bool& rotUsed); - virtual bool commit(); - virtual void setRotations(uint32_t r); - virtual bool queueBuffer(int fd, uint32_t offset); - virtual void setEnable(); - virtual void setDisable(); - virtual bool enabled () const; - virtual void setSrcFB(); - virtual uint32_t getSessId() const; - virtual int getDstMemId() const; - virtual uint32_t getDstOffset() const; - virtual void dump() const; -}; - -/* Manages the case where new rotator memory needs to be allocated, before previous is freed, due to resolution change etc. If we make rotator memory to be always max size, irrespctive of source resolution then @@ -209,29 +109,29 @@ struct RotMem { * MDP rot holds MDP's rotation related structures. * * */ -class MdpRot : public IRotatorHw { +class MdpRot : public Rotator { public: - explicit MdpRot(); - ~MdpRot(); - bool init(); - bool close(); - void setSource(const utils::Whf& whf); + virtual ~MdpRot(); + virtual bool init(); + virtual bool close(); + virtual void setSource(const utils::Whf& wfh); virtual void setFlags(const utils::eMdpFlags& flags); - void setTransform(const utils::eTransform& rot, + virtual void setTransform(const utils::eTransform& rot, const bool& rotUsed); - bool commit(); - bool queueBuffer(int fd, uint32_t offset); - void setEnable(); - void setDisable(); - void setRotations(uint32_t r); - void setSrcFB(); - bool enabled() const; - uint32_t getSessId() const; - int getDstMemId() const; - uint32_t getDstOffset() const; - void dump() const; + virtual bool commit(); + virtual void setRotations(uint32_t r); + virtual void setSrcFB(); + virtual int getDstMemId() const; + virtual uint32_t getDstOffset() const; + virtual void setEnable(); + virtual void setDisable(); + virtual bool enabled () const; + virtual uint32_t getSessId() const; + virtual bool queueBuffer(int fd, uint32_t offset); + virtual void dump() const; private: + explicit MdpRot(); /* remap rot buffers */ bool remap(uint32_t numbufs); bool open_i(uint32_t numbufs, uint32_t bufsz); @@ -261,35 +161,37 @@ private: RotMem mMem; /* Single Rotator buffer size */ uint32_t mBufSize; + + friend Rotator* Rotator::getRotator(); }; /* +* MDSS Rot holds MDSS's rotation related structures. +* +* */ -class MdssRot : public IRotatorHw { +class MdssRot : public Rotator { public: - explicit MdssRot(); - ~MdssRot(); - bool init(); - bool close(); - void setSource(const utils::Whf& whf); + virtual ~MdssRot(); + virtual bool init(); + virtual bool close(); + virtual void setSource(const utils::Whf& wfh); virtual void setFlags(const utils::eMdpFlags& flags); - void setTransform(const utils::eTransform& rot, + virtual void setTransform(const utils::eTransform& rot, const bool& rotUsed); - bool commit(); - bool queueBuffer(int fd, uint32_t offset); - void setEnable(); - void setDisable(); - void setRotations(uint32_t r); - void setSrcFB(); - bool enabled() const; - uint32_t getSessId() const; - int getDstMemId() const; - uint32_t getDstOffset() const; - void dump() const; + virtual bool commit(); + virtual void setRotations(uint32_t r); + virtual void setSrcFB(); + virtual int getDstMemId() const; + virtual uint32_t getDstOffset() const; + virtual void setEnable(); + virtual void setDisable(); + virtual bool enabled () const; + virtual uint32_t getSessId() const; + virtual bool queueBuffer(int fd, uint32_t offset); + virtual void dump() const; private: + explicit MdssRot(); /* remap rot buffers */ bool remap(uint32_t numbufs); bool open_i(uint32_t numbufs, uint32_t bufsz); @@ -312,144 +214,9 @@ private: uint32_t mBufSize; /* Enable/Disable Mdss Rot*/ bool mEnabled; -}; - -//--------------inlines------------------------------------ -///// Rotator ///// -inline Rotator::Rotator() { - int type = IRotatorHw::getRotatorHwType(); - if(type == IRotatorHw::TYPE_MDP) { - mRot = new MdpRot(); //will do reset - } else if(type == IRotatorHw::TYPE_MDSS) { - mRot = new MdssRot(); - } else { - ALOGE("%s Unknown h/w type %d", __FUNCTION__, type); - } -} -inline Rotator::~Rotator() { - delete mRot; //will do close -} -inline bool Rotator::init() { - if(!mRot->init()) { - ALOGE("Rotator::init failed"); - return false; - } - return true; -} -inline bool Rotator::close() { - return mRot->close(); -} -inline void Rotator::setSource(const utils::Whf& whf) { - mRot->setSource(whf); -} -inline void Rotator::setFlags(const utils::eMdpFlags& flags) { - mRot->setFlags(flags); -} -inline void Rotator::setTransform(const utils::eTransform& rot, - const bool& rotUsed) -{ - mRot->setTransform(rot, rotUsed); -} -inline bool Rotator::commit() { - return mRot->commit(); -} -inline void Rotator::setEnable(){ mRot->setEnable(); } -inline void Rotator::setDisable(){ mRot->setDisable(); } -inline bool Rotator::enabled() const { return mRot->enabled(); } -inline void Rotator::setSrcFB() { mRot->setSrcFB(); } -inline int Rotator::getDstMemId() const { - return mRot->getDstMemId(); -} -inline uint32_t Rotator::getDstOffset() const { - return mRot->getDstOffset(); -} -inline void Rotator::setRotations(uint32_t rot) { - mRot->setRotations (rot); -} -inline uint32_t Rotator::getSessId() const { - return mRot->getSessId(); -} -inline void Rotator::dump() const { - ALOGE("== Dump Rotator start =="); - mRot->dump(); - ALOGE("== Dump Rotator end =="); -} -inline bool Rotator::queueBuffer(int fd, uint32_t offset) { - return mRot->queueBuffer(fd, offset); -} - - -///// Null Rotator ///// -inline NullRotator::~NullRotator() {} -inline bool NullRotator::init() { return true; } -inline bool NullRotator::close() { return true; } -inline bool NullRotator::commit() { return true; } -inline void NullRotator::setSource(const utils::Whf& wfh) {} -inline void NullRotator::setFlags(const utils::eMdpFlags& flags) {} -inline void NullRotator::setTransform(const utils::eTransform& rot, const bool&) -{} -inline void NullRotator::setRotations(uint32_t) {} -inline void NullRotator::setEnable() {} -inline void NullRotator::setDisable() {} -inline bool NullRotator::enabled() const { return false; } -inline uint32_t NullRotator::getSessId() const { return 0; } -inline bool NullRotator::queueBuffer(int fd, uint32_t offset) { return true; } -inline void NullRotator::setSrcFB() {} -inline int NullRotator::getDstMemId() const { return -1; } -inline uint32_t NullRotator::getDstOffset() const { return 0;} -inline void NullRotator::dump() const { - ALOGE("== Dump NullRotator dump (null) start/end =="); -} - - -//// MdpRot //// -inline MdpRot::MdpRot() { reset(); } -inline MdpRot::~MdpRot() { close(); } -inline void MdpRot::setEnable() { mRotImgInfo.enable = 1; } -inline void MdpRot::setDisable() { mRotImgInfo.enable = 0; } -inline bool MdpRot::enabled() const { return mRotImgInfo.enable; } -inline void MdpRot::setRotations(uint32_t r) { mRotImgInfo.rotations = r; } -inline int MdpRot::getDstMemId() const { - return mRotDataInfo.dst.memory_id; -} -inline uint32_t MdpRot::getDstOffset() const { - return mRotDataInfo.dst.offset; -} -inline uint32_t MdpRot::getSessId() const { return mRotImgInfo.session_id; } -inline void MdpRot::setSrcFB() { - mRotDataInfo.src.flags |= MDP_MEMORY_ID_TYPE_FB; -} -inline void MdpRot::save() { - mLSRotImgInfo = mRotImgInfo; -} -inline bool MdpRot::rotConfChanged() const { - // 0 means same - if(0 == ::memcmp(&mRotImgInfo, &mLSRotImgInfo, - sizeof (msm_rotator_img_info))) { - return false; - } - return true; -} - - -//// MdssRot //// -inline MdssRot::MdssRot() { reset(); } -inline MdssRot::~MdssRot() { close(); } -inline void MdssRot::setEnable() { mEnabled = true; } -inline void MdssRot::setDisable() { mEnabled = false; } -inline bool MdssRot::enabled() const { return mEnabled; } -inline void MdssRot::setRotations(uint32_t flags) { mRotInfo.flags |= flags; } -inline int MdssRot::getDstMemId() const { - return mRotData.dst_data.memory_id; -} -inline uint32_t MdssRot::getDstOffset() const { - return mRotData.dst_data.offset; -} -inline uint32_t MdssRot::getSessId() const { return mRotInfo.id; } -inline void MdssRot::setSrcFB() { - mRotData.data.flags |= MDP_MEMORY_ID_TYPE_FB; -} + friend Rotator* Rotator::getRotator(); +}; } // overlay diff --git a/liboverlay/overlayState.h b/liboverlay/overlayState.h deleted file mode 100644 index 85d61d5b5..000000000 --- a/liboverlay/overlayState.h +++ /dev/null @@ -1,667 +0,0 @@ -/* -* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following -* disclaimer in the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its -* contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef OVERLAY_STATE_H -#define OVERLAY_STATE_H - -#include "overlayUtils.h" -#include "overlayImpl.h" -#include "overlayRotator.h" -#include "pipes/overlayGenPipe.h" -#include "pipes/overlayVideoExtPipe.h" -#include "pipes/overlayUIMirrorPipe.h" -#include "pipes/overlay3DPipe.h" - -namespace overlay { - -/* -* Used by Overlay class. Invokes each event -* */ - -class OverlayState : utils::NoCopy { -public: - /*ctor*/ - explicit OverlayState(); - - /*dtor*/ - ~OverlayState(); - - /* return current state */ - utils::eOverlayState state() const; - - /* Hard reset to a new state. If the state is the same - * as the current one, it would be a no-op */ - OverlayImplBase* reset(utils::eOverlayState s); - - /* Caller pass the state to the handleEvent function. - * The input is the current OverlayImplBase*, and output is - * a pointer to (possibly new) instance of OverlayImplBase - * The eFormat can be 2D/3D etc. */ - OverlayImplBase* handleEvent(utils::eOverlayState s, - OverlayImplBase* ov); - - /* Dump */ - void dump() const; - -private: - - /* Transitions from a state to a state. Default behavior is to move from an - * old state to CLOSED and from CLOSED to a new state. Any impl wishing to - * copy pipes should specialize this call */ - template<utils::eOverlayState FROM_STATE, utils::eOverlayState TO_STATE> - OverlayImplBase* handle_from_to(OverlayImplBase* ov); - - /* Just a convenient intermediate function to bring down the number of - * combinations arising from multiple states */ - template<utils::eOverlayState FROM_STATE> - OverlayImplBase* handle_from(utils::eOverlayState toState, - OverlayImplBase* ov); - - /* Substitues for partially specialized templated handle functions since the - * standard doesn't allow partial specialization of functions */ - template<utils::eOverlayState FROM_STATE> - OverlayImplBase* handle_xxx_to_CLOSED(OverlayImplBase* ov); - - template<utils::eOverlayState TO_STATE> - OverlayImplBase* handle_CLOSED_to_xxx(OverlayImplBase* ov); - - /* States here */ - utils::eOverlayState mState; -}; - -//------------------------State Traits -------------------------- - -// primary has nothing -template <int STATE> struct StateTraits {}; - -/* - * For 3D_xxx we need channel ID besides the FBx since - * get crop/position 3D need that to determine pos/crop - * info. - * */ - -template <> struct StateTraits<utils::OV_2D_VIDEO_ON_PANEL> -{ - typedef overlay::GenericPipe<utils::PRIMARY> pipe0; //prim video - typedef overlay::NullPipe pipe1; // place holder - typedef overlay::NullPipe pipe2; // place holder - - typedef Rotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_2D_VIDEO_ON_PANEL_TV> -{ - typedef overlay::GenericPipe<utils::PRIMARY> pipe0; //prim video - typedef overlay::VideoExtPipe pipe1; //ext video - typedef overlay::GenericPipe<utils::EXTERNAL> pipe2; //ext subtitle - - typedef Rotator rot0; - typedef Rotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_2D_VIDEO_ON_TV> -{ - typedef overlay::NullPipe pipe0; //nothing on primary with mdp - typedef overlay::VideoExtPipe pipe1; //ext video - typedef overlay::GenericPipe<utils::EXTERNAL> pipe2; //ext subtitle - - typedef NullRotator rot0; - typedef Rotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_UI_VIDEO_TV> -{ - typedef overlay::GenericPipe<utils::EXTERNAL> pipe0; //ext UI - typedef overlay::GenericPipe<utils::EXTERNAL> pipe1; //ext video - typedef overlay::NullPipe pipe2; - - typedef Rotator rot0; - typedef Rotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL> -{ - typedef overlay::M3DPrimaryPipe<utils::OV_PIPE0> pipe0; - typedef overlay::NullPipe pipe1; // place holder - typedef overlay::NullPipe pipe2; // place holder - - typedef Rotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0> ovimpl; -}; - -template <> struct StateTraits<utils::OV_3D_VIDEO_ON_3D_PANEL> -{ - typedef overlay::S3DPrimaryPipe<utils::OV_PIPE0> pipe0; - typedef overlay::S3DPrimaryPipe<utils::OV_PIPE1> pipe1; - typedef overlay::NullPipe pipe2; // place holder - - typedef Rotator rot0; - typedef Rotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl; -}; - -template <> struct StateTraits<utils::OV_3D_VIDEO_ON_3D_TV> -{ - typedef overlay::S3DExtPipe<utils::OV_PIPE0> pipe0; - typedef overlay::S3DExtPipe<utils::OV_PIPE1> pipe1; - typedef overlay::NullPipe pipe2; // place holder - - typedef NullRotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl; -}; - -template <> struct StateTraits<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV> -{ - typedef overlay::M3DPrimaryPipe<utils::OV_PIPE0> pipe0; - typedef overlay::M3DExtPipe<utils::OV_PIPE1> pipe1; - typedef overlay::NullPipe pipe2; // place holder - - typedef Rotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1> ovimpl; -}; - -template <> struct StateTraits<utils::OV_UI_MIRROR> -{ - typedef overlay::GenericPipe<ovutils::EXTERNAL> pipe0; //Ext UI - typedef overlay::NullPipe pipe1; // place holder - typedef overlay::NullPipe pipe2; // place holder - - typedef Rotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_2D_TRUE_UI_MIRROR> -{ - typedef overlay::GenericPipe<utils::PRIMARY> pipe0; //Vid prim - typedef overlay::VideoExtPipe pipe1; - typedef overlay::GenericPipe<ovutils::EXTERNAL> pipe2; //EXT UI - - typedef Rotator rot0; - typedef Rotator rot1; - typedef Rotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_BYPASS_1_LAYER> -{ - typedef overlay::GenericPipe<utils::PRIMARY> pipe0; - typedef overlay::NullPipe pipe1; // place holder - typedef overlay::NullPipe pipe2; // place holder - - typedef NullRotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_BYPASS_2_LAYER> -{ - typedef overlay::GenericPipe<utils::PRIMARY> pipe0; - typedef overlay::GenericPipe<utils::PRIMARY> pipe1; - typedef overlay::NullPipe pipe2; // place holder - - typedef NullRotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_BYPASS_3_LAYER> -{ - typedef overlay::GenericPipe<utils::PRIMARY> pipe0; - typedef overlay::GenericPipe<utils::PRIMARY> pipe1; - typedef overlay::GenericPipe<utils::PRIMARY> pipe2; - - typedef NullRotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - -template <> struct StateTraits<utils::OV_DUAL_DISP> -{ - typedef overlay::GenericPipe<utils::EXTERNAL> pipe0; - typedef overlay::NullPipe pipe1; - typedef overlay::NullPipe pipe2; - - typedef NullRotator rot0; - typedef NullRotator rot1; - typedef NullRotator rot2; - - typedef overlay::OverlayImpl<pipe0, pipe1, pipe2> ovimpl; -}; - - -//------------------------Inlines -------------------------------- - - -inline OverlayState::OverlayState() : mState(utils::OV_CLOSED){} -inline OverlayState::~OverlayState() {} -inline utils::eOverlayState OverlayState::state() const { return mState; } -inline OverlayImplBase* OverlayState::reset(utils::eOverlayState s) { - return handleEvent(s, 0); -} -inline void OverlayState::dump() const { - ALOGE("== Dump state %d start/end ==", mState); -} - -inline OverlayImplBase* OverlayState::handleEvent(utils::eOverlayState toState, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; // at least, we return the same - if (mState != toState) { - ALOGD_IF(DEBUG_OVERLAY, "%s: state changed %s-->%s", - __FUNCTION__, getStateString(mState), getStateString(toState)); - } else { - ALOGD_IF(DEBUG_OVERLAY, "%s: no state change, state=%s", - __FUNCTION__, getStateString(toState)); - return newov; - } - - switch(mState) - { - case utils::OV_CLOSED: - newov = handle_from<utils::OV_CLOSED>(toState, ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_from<utils::OV_2D_VIDEO_ON_PANEL>(toState, ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_from<utils::OV_2D_VIDEO_ON_PANEL_TV>(toState, ov); - break; - case utils::OV_2D_VIDEO_ON_TV: - newov = handle_from<utils::OV_2D_VIDEO_ON_TV>(toState, ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_from<utils::OV_3D_VIDEO_ON_2D_PANEL>(toState, ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_from<utils::OV_3D_VIDEO_ON_3D_PANEL>(toState, ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_from<utils::OV_3D_VIDEO_ON_3D_TV>(toState, ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_from<utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(toState, - ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_from<utils::OV_UI_MIRROR>(toState, ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_from<utils::OV_2D_TRUE_UI_MIRROR>(toState, ov); - break; - case utils::OV_UI_VIDEO_TV: - newov = handle_from<utils::OV_UI_VIDEO_TV>(toState, ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_from<utils::OV_BYPASS_1_LAYER>(toState, ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_from<utils::OV_BYPASS_2_LAYER>(toState, ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_from<utils::OV_BYPASS_3_LAYER>(toState, ov); - break; - case utils::OV_DUAL_DISP: - newov = handle_from<utils::OV_DUAL_DISP>(toState, ov); - break; - default: - OVASSERT(1 == 0, "%s: unknown state = %d", __FUNCTION__, mState); - - } - return newov; -} - -template <utils::eOverlayState FROM_STATE> -inline OverlayImplBase* OverlayState::handle_from(utils::eOverlayState toState, - OverlayImplBase* ov) { - - switch(toState) - { - case utils::OV_CLOSED: - ov = handle_xxx_to_CLOSED<FROM_STATE>(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - ov = handle_from_to<FROM_STATE, utils::OV_2D_VIDEO_ON_PANEL>(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - ov = handle_from_to<FROM_STATE, utils::OV_2D_VIDEO_ON_PANEL_TV>(ov); - break; - case utils::OV_2D_VIDEO_ON_TV: - ov = handle_from_to<FROM_STATE, utils::OV_2D_VIDEO_ON_TV>(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - ov = handle_from_to<FROM_STATE, utils::OV_3D_VIDEO_ON_2D_PANEL>(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - ov = handle_from_to<FROM_STATE, utils::OV_3D_VIDEO_ON_3D_PANEL>(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - ov = handle_from_to<FROM_STATE, utils::OV_3D_VIDEO_ON_3D_TV>(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - ov = handle_from_to<FROM_STATE, - utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV>(ov); - break; - case utils::OV_UI_MIRROR: - ov = handle_from_to<FROM_STATE, utils::OV_UI_MIRROR>(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - ov = handle_from_to<FROM_STATE, utils::OV_2D_TRUE_UI_MIRROR>(ov); - break; - case utils::OV_UI_VIDEO_TV: - ov = handle_from_to<FROM_STATE, utils::OV_UI_VIDEO_TV>(ov); - break; - case utils::OV_BYPASS_1_LAYER: - ov = handle_from_to<FROM_STATE, utils::OV_BYPASS_1_LAYER>(ov); - break; - case utils::OV_BYPASS_2_LAYER: - ov = handle_from_to<FROM_STATE, utils::OV_BYPASS_2_LAYER>(ov); - break; - case utils::OV_BYPASS_3_LAYER: - ov = handle_from_to<FROM_STATE, utils::OV_BYPASS_3_LAYER>(ov); - break; - case utils::OV_DUAL_DISP: - ov = handle_from_to<FROM_STATE, utils::OV_DUAL_DISP>(ov); - break; - default: - OVASSERT(1 == 0, "%s: unknown state = %d", __FUNCTION__, toState); - } - mState = toState; - return ov; -} - - -/* Transition default from any to any. Does in two steps. - * Moves from OLD to CLOSED and then from CLOSED to NEW - */ -template<utils::eOverlayState FROM_STATE, utils::eOverlayState TO_STATE> -inline OverlayImplBase* OverlayState::handle_from_to(OverlayImplBase* ov) { - handle_xxx_to_CLOSED<FROM_STATE>(ov); - return handle_CLOSED_to_xxx<TO_STATE>(ov); -} - -//---------------Specializations------------- - - -/* Transition from CLOSED to ANY */ -template<utils::eOverlayState TO_STATE> -inline OverlayImplBase* OverlayState::handle_CLOSED_to_xxx( - OverlayImplBase* /*ignored*/) { - //If going from CLOSED to CLOSED, nothing to do. - if(TO_STATE == utils::OV_CLOSED) return NULL; - ALOGD("FROM_STATE = %s TO_STATE = %s", - utils::getStateString(utils::OV_CLOSED), - utils::getStateString(TO_STATE)); - OverlayImplBase* ov = new typename StateTraits<TO_STATE>::ovimpl; - RotatorBase* rot0 = new typename StateTraits<TO_STATE>::rot0; - RotatorBase* rot1 = new typename StateTraits<TO_STATE>::rot1; - RotatorBase* rot2 = new typename StateTraits<TO_STATE>::rot2; - if(!ov->init(rot0, rot1, rot2)) { - ALOGE("Overlay failed to init in state %d", TO_STATE); - return 0; - } - return ov; -} - -/* Transition from ANY to CLOSED */ -template<utils::eOverlayState FROM_STATE> -inline OverlayImplBase* OverlayState::handle_xxx_to_CLOSED(OverlayImplBase* ov) -{ - //If going from CLOSED to CLOSED, nothing to do. - if(FROM_STATE == utils::OV_CLOSED) return NULL; - ALOGD("FROM_STATE = %s TO_STATE = %s", - utils::getStateString(FROM_STATE), - utils::getStateString(utils::OV_CLOSED)); - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - if(!ov->close()) { - ALOGE("%s: Failed to ov close", __FUNCTION__); - } - delete ov; - ov = 0; - return 0; -} - -/* Transition from 2D_VIDEO_ON_PANEL to 2D_VIDEO_ON_PANEL_TV */ -template<> -inline OverlayImplBase* OverlayState::handle_from_to< - utils::OV_2D_VIDEO_ON_PANEL, - utils::OV_2D_VIDEO_ON_PANEL_TV>( - OverlayImplBase* ov) { - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGD("FROM_STATE = %s TO_STATE = %s", - utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL), - utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL_TV)); - // Create new ovimpl based on new state - typedef StateTraits<utils::OV_2D_VIDEO_ON_PANEL_TV> NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //copy pipe0/rot0 (primary video) - newov->copyOvPipe(ov, utils::OV_PIPE0); - //close old pipe1, create new pipe1 - ov->closePipe(utils::OV_PIPE1); - RotatorBase* rot1 = new NewState::rot1; - newov->initPipe(rot1, utils::OV_PIPE1); - //close old pipe2, create new pipe2 - ov->closePipe(utils::OV_PIPE2); - RotatorBase* rot2 = new NewState::rot2; - newov->initPipe(rot2, utils::OV_PIPE2); - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - return newov; -} - -/* Transition from 2D_VIDEO_ON_PANEL_TV to 2D_VIDEO_ON_PANEL */ -template<> -inline OverlayImplBase* OverlayState::handle_from_to< - utils::OV_2D_VIDEO_ON_PANEL_TV, - utils::OV_2D_VIDEO_ON_PANEL>( - OverlayImplBase* ov) { - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGD("FROM_STATE = %s TO_STATE = %s", - utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL_TV), - utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL)); - - // Create new ovimpl based on new state - typedef StateTraits<utils::OV_2D_VIDEO_ON_PANEL> NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //copy pipe0/rot0 (primary video) - newov->copyOvPipe(ov, utils::OV_PIPE0); - //close old pipe1, create new pipe1 - ov->closePipe(utils::OV_PIPE1); - RotatorBase* rot1 = new NewState::rot1; - newov->initPipe(rot1, utils::OV_PIPE1); - //close old pipe2, create new pipe2 - ov->closePipe(utils::OV_PIPE2); - RotatorBase* rot2 = new NewState::rot2; - newov->initPipe(rot2, utils::OV_PIPE2); - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - return newov; -} - -/* Transition from 2D_VIDEO_ON_PANEL_TV to 2D_VIDEO_ON_TV */ -template<> -inline OverlayImplBase* OverlayState::handle_from_to< - utils::OV_2D_VIDEO_ON_PANEL_TV, - utils::OV_2D_VIDEO_ON_TV>( - OverlayImplBase* ov) { - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGD("FROM_STATE = %s TO_STATE = %s", - utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL_TV), - utils::getStateString(utils::OV_2D_VIDEO_ON_TV)); - - // Create new ovimpl based on new state - typedef StateTraits<utils::OV_2D_VIDEO_ON_TV> NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //close old pipe0, create new pipe0 - ov->closePipe(utils::OV_PIPE0); - RotatorBase* rot0 = new NewState::rot0; - newov->initPipe(rot0, utils::OV_PIPE0); - //copy pipe1/rot1 (ext video) - newov->copyOvPipe(ov, utils::OV_PIPE1); - //copy pipe2/rot2 (ext cc) - newov->copyOvPipe(ov, utils::OV_PIPE2); - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - return newov; -} - -/* Transition from 2D_VIDEO_ON_TV to 2D_VIDEO_ON_PANEL_TV */ -template<> -inline OverlayImplBase* OverlayState::handle_from_to< - utils::OV_2D_VIDEO_ON_TV, - utils::OV_2D_VIDEO_ON_PANEL_TV>( - OverlayImplBase* ov) { - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGD("FROM_STATE = %s TO_STATE = %s", - utils::getStateString(utils::OV_2D_VIDEO_ON_TV), - utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL_TV)); - - // Create new ovimpl based on new state - typedef StateTraits<utils::OV_2D_VIDEO_ON_PANEL_TV> NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //close old pipe0, create new pipe0 - ov->closePipe(utils::OV_PIPE0); - RotatorBase* rot0 = new NewState::rot0; - newov->initPipe(rot0, utils::OV_PIPE0); - //copy pipe1/rot1 (ext video) - newov->copyOvPipe(ov, utils::OV_PIPE1); - //copy pipe2/rot2 (ext cc) - newov->copyOvPipe(ov, utils::OV_PIPE2); - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - return newov; -} - -/* Transition from OV_UI_MIRROR to OV_UI_VIDEO_TV */ -template<> -inline OverlayImplBase* OverlayState::handle_from_to< - utils::OV_UI_MIRROR, - utils::OV_UI_VIDEO_TV>( - OverlayImplBase* ov) { - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGD("FROM_STATE = %s TO_STATE = %s", - utils::getStateString(utils::OV_UI_MIRROR), - utils::getStateString(utils::OV_UI_VIDEO_TV)); - - // Create new ovimpl based on new state - typedef StateTraits<utils::OV_UI_VIDEO_TV> NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //copy pipe0/rot0 (ext video) - newov->copyOvPipe(ov, utils::OV_PIPE0); - - ov->closePipe(utils::OV_PIPE1); - RotatorBase* rot1 = new NewState::rot1; - newov->initPipe(rot1, utils::OV_PIPE1); - - ov->closePipe(utils::OV_PIPE2); - RotatorBase* rot2 = new NewState::rot2; - newov->initPipe(rot2, utils::OV_PIPE2); - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - return newov; -} - -/* Transition from OV_UI_VIDEO_TV to OV_UI_MIRROR */ -template<> -inline OverlayImplBase* OverlayState::handle_from_to< - utils::OV_UI_VIDEO_TV, - utils::OV_UI_MIRROR>( - OverlayImplBase* ov) { - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGD("FROM_STATE = %s TO_STATE = %s", - utils::getStateString(utils::OV_UI_VIDEO_TV), - utils::getStateString(utils::OV_UI_MIRROR)); - - // Create new ovimpl based on new state - typedef StateTraits<utils::OV_UI_MIRROR> NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //copy pipe0/rot0 (ext video) - newov->copyOvPipe(ov, utils::OV_PIPE0); - - ov->closePipe(utils::OV_PIPE1); - RotatorBase* rot1 = new NewState::rot1; - newov->initPipe(rot1, utils::OV_PIPE1); - - ov->closePipe(utils::OV_PIPE2); - RotatorBase* rot2 = new NewState::rot2; - newov->initPipe(rot2, utils::OV_PIPE2); - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - return newov; -} -} // overlay - -#endif // OVERLAY_STATE_H diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp index 1c9c72b3f..207531a09 100644 --- a/liboverlay/overlayUtils.cpp +++ b/liboverlay/overlayUtils.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. +* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -151,13 +151,6 @@ int FrameBufferInfo::getHeight() const { return mFBHeight; } -bool FrameBufferInfo::supportTrueMirroring() const { - char value[PROPERTY_VALUE_MAX] = {0}; - property_get("hw.trueMirrorSupported", value, "0"); - int trueMirroringSupported = atoi(value); - return (trueMirroringSupported && mBorderFillSupported); -} - /* clears any VG pipes allocated to the fb devices */ int initOverlay() { msmfb_mixer_info_req req; @@ -253,20 +246,6 @@ int getMdpFormat(int format) { return -1; } -//Set by client as HDMI/WFD -void setExtType(const int& type) { - if(type != HDMI && type != WFD) { - ALOGE("%s: Unrecognized type %d", __func__, type); - return; - } - sExtType = type; -} - -//Return External panel type set by client. -int getExtType() { - return sExtType; -} - bool is3DTV() { char is3DTV = '0'; IOFile fp(Res::edid3dInfoFile, "r"); diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h index 7432ff89f..f9fcca82a 100644 --- a/liboverlay/overlayUtils.h +++ b/liboverlay/overlayUtils.h @@ -43,6 +43,7 @@ #include <sys/types.h> #include <utils/Log.h> #include "gralloc_priv.h" //for interlace + /* * * Collection of utilities functions/structs/enums etc... @@ -123,9 +124,6 @@ public: /* Gets height of primary framebuffer */ int getHeight() const; - /* Indicates whether true mirroring is supported */ - bool supportTrueMirroring() const; - private: int mFBWidth; int mFBHeight; @@ -266,16 +264,8 @@ enum { MAX_PATH_LEN = 256 }; * Rotator flags: not to be confused with orientation flags. * Ususally, you want to open the rotator to make sure it is * ready for business. - * ROT_FLAG_DISABLED: Rotator would not kick in. (ioctl will emit errors). - * ROT_FLAG_ENABLED: and when rotation is needed. - * (prim video playback) - * (UI mirroring on HDMI w/ 0 degree rotator. - just memcpy) - * In HDMI UI mirroring, rotator is always used. - * Even when w/o orienation change on primary, - * we do 0 rotation on HDMI and using rotator buffers. - * That is because we might see tearing otherwise. so - * we use another buffer (rotator). - * When a simple video playback on HDMI, no rotator is being used.(null r). + * ROT_FLAG_DISABLED: Rotator not used unless required. + * ROT_FLAG_ENABLED: Rotator used even if not required. * */ enum eRotFlags { ROT_FLAG_DISABLED = 0, @@ -313,26 +303,32 @@ enum eZorder { ZORDER_0, ZORDER_1, ZORDER_2, + ZORDER_3, Z_SYSTEM_ALLOC = 0xFFFF }; enum eMdpPipeType { OV_MDP_PIPE_RGB, - OV_MDP_PIPE_VG + OV_MDP_PIPE_VG, + OV_MDP_PIPE_ANY, //Any }; -// Max pipes via overlay (VG0, VG1, RGB1) -enum { MAX_PIPES = 3 }; - -/* Used to identify destination channels and - * also 3D channels e.g. when in 3D mode with 2 - * pipes opened and it is used in get crop/pos 3D - * */ +/* Used to identify destination pipes + */ enum eDest { - OV_PIPE0 = 1 << 0, - OV_PIPE1 = 1 << 1, - OV_PIPE2 = 1 << 2, - OV_PIPE_ALL = (OV_PIPE0 | OV_PIPE1 | OV_PIPE2) + OV_VG0 = 0, + OV_RGB0, + OV_VG1, + OV_RGB1, + OV_VG2, + OV_RGB2, + OV_INVALID, +}; + +/* Used when a buffer is split over 2 pipes and sent to display */ +enum { + OV_LEFT_SPLIT = 0, + OV_RIGHT_SPLIT, }; /* values for copybit_set_parameter(OVERLAY_TRANSFORM) */ @@ -385,38 +381,6 @@ struct PipeArgs { eRotFlags rotFlags; }; -enum eOverlayState{ - /* No pipes from overlay open */ - OV_CLOSED = 0, - - /* 2D Video */ - OV_2D_VIDEO_ON_PANEL, - OV_2D_VIDEO_ON_PANEL_TV, - OV_2D_VIDEO_ON_TV, - - /* 3D Video on one display (panel or TV) */ - OV_3D_VIDEO_ON_2D_PANEL, - OV_3D_VIDEO_ON_3D_PANEL, - OV_3D_VIDEO_ON_3D_TV, - - /* 3D Video on two displays (panel and TV) */ - OV_3D_VIDEO_ON_2D_PANEL_2D_TV, - - /* UI Mirroring */ - OV_UI_MIRROR, - OV_2D_TRUE_UI_MIRROR, - /* Dual display with video */ - OV_UI_VIDEO_TV, - - /* Composition Bypass */ - OV_BYPASS_1_LAYER, - OV_BYPASS_2_LAYER, - OV_BYPASS_3_LAYER, - - /* External only for dual-disp */ - OV_DUAL_DISP, -}; - inline void setMdpFlags(eMdpFlags& f, eMdpFlags v) { f = static_cast<eMdpFlags>(setBit(f, v)); } @@ -431,44 +395,6 @@ enum { FB0, FB1, FB2 }; //Panels could be categorized as primary and external enum { PRIMARY, EXTERNAL }; -//External Panels could use HDMI or WFD -enum { - HDMI = 1, - WFD = 2 -}; - -//TODO Make this a part of some appropriate class -static int sExtType = HDMI; //HDMI or WFD -//Set by client as HDMI/WFD -void setExtType(const int& type); -//Return External panel type set by client. -int getExtType(); - - -//Gets the FB number for the external type. -//As of now, HDMI always has fb1, WFD could use fb1 or fb2 -//Assumes Ext type set by setExtType() from client. -static int getFBForPanel(int panel) { // PRIMARY OR EXTERNAL - switch(panel) { - case PRIMARY: return FB0; - break; - case EXTERNAL: - switch(getExtType()) { - case HDMI: return FB1; - break; - case WFD: return FB2;//Hardcoding fb2 for wfd. Will change. - break; - } - break; - default: - ALOGE("%s: Unrecognized PANEL category %d", __func__, panel); - break; - } - return -1; -} - -// number of rgb pipes bufs (max) - // 2 for rgb0/1 double bufs enum { RGB_PIPE_NUM_BUFS = 2 }; @@ -491,7 +417,6 @@ int getRotOutFmt(uint32_t format); * It returns MDP related enum/define that match rot+flip*/ int getMdpOrient(eTransform rotation); const char* getFormatString(int format); -const char* getStateString(eOverlayState state); // Cannot use HW_OVERLAY_MAGNIFICATION_LIMIT, since at the time // of integration, HW_OVERLAY_MAGNIFICATION_LIMIT was a define @@ -582,16 +507,6 @@ inline bool isRgb(uint32_t format) { return false; } -inline bool isValidDest(eDest dest) -{ - if ((OV_PIPE0 & dest) || - (OV_PIPE1 & dest) || - (OV_PIPE2 & dest)) { - return true; - } - return false; -} - inline const char* getFormatString(int format){ static const char* const formats[] = { "MDP_RGB_565", @@ -631,44 +546,6 @@ inline const char* getFormatString(int format){ return formats[format]; } -inline const char* getStateString(eOverlayState state){ - switch (state) { - case OV_CLOSED: - return "OV_CLOSED"; - case OV_2D_VIDEO_ON_PANEL: - return "OV_2D_VIDEO_ON_PANEL"; - case OV_2D_VIDEO_ON_PANEL_TV: - return "OV_2D_VIDEO_ON_PANEL_TV"; - case OV_2D_VIDEO_ON_TV: - return "OV_2D_VIDEO_ON_TV"; - case OV_3D_VIDEO_ON_2D_PANEL: - return "OV_3D_VIDEO_ON_2D_PANEL"; - case OV_3D_VIDEO_ON_3D_PANEL: - return "OV_3D_VIDEO_ON_3D_PANEL"; - case OV_3D_VIDEO_ON_3D_TV: - return "OV_3D_VIDEO_ON_3D_TV"; - case OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - return "OV_3D_VIDEO_ON_2D_PANEL_2D_TV"; - case OV_UI_MIRROR: - return "OV_UI_MIRROR"; - case OV_2D_TRUE_UI_MIRROR: - return "OV_2D_TRUE_UI_MIRROR"; - case OV_UI_VIDEO_TV: - return "OV_UI_VIDEO_TV"; - case OV_BYPASS_1_LAYER: - return "OV_BYPASS_1_LAYER"; - case OV_BYPASS_2_LAYER: - return "OV_BYPASS_2_LAYER"; - case OV_BYPASS_3_LAYER: - return "OV_BYPASS_3_LAYER"; - case OV_DUAL_DISP: - return "OV_DUAL_DISP"; - default: - return "UNKNOWN_STATE"; - } - return "BAD_STATE"; -} - inline void Whf::dump() const { ALOGE("== Dump WHF w=%d h=%d f=%d s=%d start/end ==", w, h, format, size); @@ -751,7 +628,7 @@ inline Dim getPositionS3DImpl(const Whf& whf) } template <> -inline Dim getPositionS3DImpl<utils::OV_PIPE1>(const Whf& whf) +inline Dim getPositionS3DImpl<utils::OV_RIGHT_SPLIT>(const Whf& whf) { switch (whf.format & OUTPUT_3D_MASK) { @@ -799,7 +676,7 @@ inline Dim getCropS3DImpl(const Dim& in, uint32_t fmt) { } template <> -inline Dim getCropS3DImpl<utils::OV_PIPE1>(const Dim& in, uint32_t fmt) { +inline Dim getCropS3DImpl<utils::OV_RIGHT_SPLIT>(const Dim& in, uint32_t fmt) { switch (fmt & INPUT_3D_MASK) { case HAL_3D_IN_SIDE_BY_SIDE_L_R: @@ -855,6 +732,35 @@ inline void even_floor(T& value) { value--; } +inline const char* getDestStr(eDest dest) { + switch(dest) { + case OV_VG0: return "VG0"; + case OV_RGB0: return "RGB0"; + case OV_VG1: return "VG1"; + case OV_RGB1: return "RGB1"; + case OV_VG2: return "VG2"; + case OV_RGB2: return "RGB2"; + default: return "Invalid"; + } + return "Invalid"; +} + +inline eMdpPipeType getPipeType(eDest dest) { + switch(dest) { + case OV_VG0: + case OV_VG1: + case OV_VG2: + return OV_MDP_PIPE_VG; + case OV_RGB0: + case OV_RGB1: + case OV_RGB2: + return OV_MDP_PIPE_RGB; + default: + return OV_MDP_PIPE_ANY; + } + return OV_MDP_PIPE_ANY; +} + } // namespace utils ends //--------------------Class Res stuff (namespace overlay only) ----------- diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp new file mode 100644 index 000000000..ecb3b1614 --- /dev/null +++ b/liboverlay/pipes/overlayGenPipe.cpp @@ -0,0 +1,222 @@ +/* +* Copyright (c) 2012, The Linux Foundation. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following +* disclaimer in the documentation and/or other materials provided +* with the distribution. +* * Neither the name of The Linux Foundation nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "overlayGenPipe.h" + +namespace overlay { + +GenericPipe::GenericPipe(int dpy) : mFbNum(dpy), mRot(0), mRotUsed(false), + pipeState(CLOSED) { + init(); +} + +GenericPipe::~GenericPipe() { + close(); +} + +bool GenericPipe::init() +{ + ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init"); + mRotUsed = false; + + if(!mCtrlData.ctrl.init(mFbNum)) { + ALOGE("GenericPipe failed to init ctrl"); + return false; + } + + if(!mCtrlData.data.init(mFbNum)) { + ALOGE("GenericPipe failed to init data"); + return false; + } + + //get a new rotator object, take ownership + mRot = Rotator::getRotator(); + + return true; +} + +bool GenericPipe::close() { + bool ret = true; + + if(!mCtrlData.ctrl.close()) { + ALOGE("GenericPipe failed to close ctrl"); + ret = false; + } + if (!mCtrlData.data.close()) { + ALOGE("GenericPipe failed to close data"); + ret = false; + } + + delete mRot; + mRot = 0; + + setClosed(); + return ret; +} + +bool GenericPipe::setSource( + const utils::PipeArgs& args) +{ + utils::PipeArgs newargs(args); + //Interlace video handling. + if(newargs.whf.format & INTERLACE_MASK) { + setMdpFlags(newargs.mdpFlags, utils::OV_MDP_DEINTERLACE); + } + utils::Whf whf(newargs.whf); + //Extract HAL format from lower bytes. Deinterlace if interlaced. + whf.format = utils::getColorFormat(whf.format); + //Get MDP equivalent of HAL format. + whf.format = utils::getMdpFormat(whf.format); + newargs.whf = whf; + + //Cache if user wants 0-rotation + mRotUsed = newargs.rotFlags & utils::ROT_FLAG_ENABLED; + mRot->setSource(newargs.whf); + mRot->setFlags(newargs.mdpFlags); + return mCtrlData.ctrl.setSource(newargs); +} + +bool GenericPipe::setCrop( + const overlay::utils::Dim& d) { + return mCtrlData.ctrl.setCrop(d); +} + +bool GenericPipe::setTransform( + const utils::eTransform& orient) +{ + //Rotation could be enabled by user for zero-rot or the layer could have + //some transform. Mark rotation enabled in either case. + mRotUsed |= (orient != utils::OVERLAY_TRANSFORM_0); + mRot->setTransform(orient, mRotUsed); + + return mCtrlData.ctrl.setTransform(orient, mRotUsed); +} + +bool GenericPipe::setPosition(const utils::Dim& d) +{ + return mCtrlData.ctrl.setPosition(d); +} + +bool GenericPipe::commit() { + bool ret = false; + //If wanting to use rotator, start it. + if(mRotUsed) { + if(!mRot->commit()) { + ALOGE("GenPipe Rotator commit failed"); + //If rot commit fails, flush rotator session, memory, fd and create + //a hollow rotator object + delete mRot; + mRot = Rotator::getRotator(); + pipeState = CLOSED; + return false; + } + } + + ret = mCtrlData.ctrl.commit(); + + //If mdp commit fails, flush rotator session, memory, fd and create a hollow + //rotator object + if(ret == false) { + delete mRot; + mRot = Rotator::getRotator(); + } + + pipeState = ret ? OPEN : CLOSED; + return ret; +} + +bool GenericPipe::queueBuffer(int fd, uint32_t offset) { + //TODO Move pipe-id transfer to CtrlData class. Make ctrl and data private. + OVASSERT(isOpen(), "State is closed, cannot queueBuffer"); + int pipeId = mCtrlData.ctrl.getPipeId(); + OVASSERT(-1 != pipeId, "Ctrl ID should not be -1"); + // set pipe id from ctrl to data + mCtrlData.data.setPipeId(pipeId); + + int finalFd = fd; + uint32_t finalOffset = offset; + //If rotator is to be used, queue to it, so it can ROTATE. + if(mRotUsed) { + if(!mRot->queueBuffer(fd, offset)) { + ALOGE("GenPipe Rotator play failed"); + return false; + } + //Configure MDP's source buffer as the current output buffer of rotator + if(mRot->getDstMemId() != -1) { + finalFd = mRot->getDstMemId(); + finalOffset = mRot->getDstOffset(); + } else { + //Could be -1 for NullRotator, if queue above succeeds. + //Need an actual rotator. Modify overlay State Traits. + //Not fatal, keep queuing to MDP without rotation. + ALOGE("Null rotator in use, where an actual is required"); + } + } + return mCtrlData.data.queueBuffer(finalFd, finalOffset); +} + +int GenericPipe::getCtrlFd() const { + return mCtrlData.ctrl.getFd(); +} + +utils::ScreenInfo GenericPipe::getScreenInfo() const +{ + return mCtrlData.ctrl.getScreenInfo(); +} + +utils::Dim GenericPipe::getCrop() const +{ + return mCtrlData.ctrl.getCrop(); +} + +void GenericPipe::dump() const +{ + ALOGE("== Dump Generic pipe start =="); + ALOGE("pipe state = %d", (int)pipeState); + OVASSERT(mRot, "GenericPipe should have a valid Rot"); + mCtrlData.ctrl.dump(); + mCtrlData.data.dump(); + mRot->dump(); + ALOGE("== Dump Generic pipe end =="); +} + +bool GenericPipe::isClosed() const { + return (pipeState == CLOSED); +} + +bool GenericPipe::isOpen() const { + return (pipeState == OPEN); +} + +bool GenericPipe::setClosed() { + pipeState = CLOSED; + return true; +} + +} //namespace overlay diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h index cbcb05afe..d0bb3a880 100644 --- a/liboverlay/pipes/overlayGenPipe.h +++ b/liboverlay/pipes/overlayGenPipe.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. +* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its +* * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * @@ -36,15 +36,15 @@ namespace overlay { -template <int PANEL> + class GenericPipe : utils::NoCopy { public: /* ctor */ - explicit GenericPipe(); + explicit GenericPipe(int dpy); /* dtor */ ~GenericPipe(); /* CTRL/DATA init. Not owning rotator, will not init it */ - bool init(RotatorBase* rot); + bool init(); /* CTRL/DATA close. Not owning rotator, will not close it */ bool close(); @@ -73,12 +73,6 @@ public: /* retrieve cached crop data */ utils::Dim getCrop() const; - /* return aspect ratio from ctrl data */ - utils::Dim getAspectRatio(const utils::Whf& whf) const; - - /* return aspect ratio from ctrl data for true UI mirroring */ - utils::Dim getAspectRatio(const utils::Dim& dim) const; - /* is closed */ bool isClosed() const; @@ -94,12 +88,12 @@ private: /* set Closed pipe */ bool setClosed(); + int mFbNum; + /* Ctrl/Data aggregator */ CtrlData mCtrlData; - /* rotator mdp base - * Can point to NullRotator or to Rotator*/ - RotatorBase* mRot; + Rotator* mRot; //Whether rotator is used for 0-rot or otherwise bool mRotUsed; @@ -112,223 +106,6 @@ private: ePipeState pipeState; }; -//------------------------Inlines and Templates ---------------------- - -template <int PANEL> -GenericPipe<PANEL>::GenericPipe() : mRot(0), mRotUsed(false), - pipeState(CLOSED) { -} - -template <int PANEL> -GenericPipe<PANEL>::~GenericPipe() { - close(); -} - -template <int PANEL> -bool GenericPipe<PANEL>::init(RotatorBase* rot) -{ - ALOGE_IF(DEBUG_OVERLAY, "GenericPipe init"); - OVASSERT(rot, "rot is null"); - - // init ctrl and data - uint32_t fbnum = utils::getFBForPanel(PANEL); - - if(!mCtrlData.ctrl.init(fbnum)) { - ALOGE("GenericPipe failed to init ctrl"); - return false; - } - - if(!mCtrlData.data.init(fbnum)) { - ALOGE("GenericPipe failed to init data"); - return false; - } - - //Cache the rot ref. Ownership is with OverlayImpl. - mRot = rot; - - mRotUsed = false; - - // NOTE:init() on the rot is called by OverlayImpl - // Pipes only have to worry about using rot, and not init or close. - - return true; -} - -template <int PANEL> -bool GenericPipe<PANEL>::close() { - if(isClosed()) - return true; - - bool ret = true; - - if(!mCtrlData.ctrl.close()) { - ALOGE("GenericPipe failed to close ctrl"); - ret = false; - } - if (!mCtrlData.data.close()) { - ALOGE("GenericPipe failed to close data"); - ret = false; - } - - // NOTE:close() on the rot is called by OverlayImpl - // Pipes only have to worry about using rot, and not init or close. - - setClosed(); - return ret; -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::setSource( - const utils::PipeArgs& args) -{ - utils::PipeArgs newargs(args); - //Interlace video handling. - if(newargs.whf.format & INTERLACE_MASK) { - setMdpFlags(newargs.mdpFlags, utils::OV_MDP_DEINTERLACE); - } - utils::Whf whf(newargs.whf); - //Extract HAL format from lower bytes. Deinterlace if interlaced. - whf.format = utils::getColorFormat(whf.format); - //Get MDP equivalent of HAL format. - whf.format = utils::getMdpFormat(whf.format); - newargs.whf = whf; - - //Cache if user wants 0-rotation - mRotUsed = newargs.rotFlags & utils::ROT_FLAG_ENABLED; - mRot->setSource(newargs.whf); - mRot->setFlags(newargs.mdpFlags); - return mCtrlData.ctrl.setSource(newargs); -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::setCrop( - const overlay::utils::Dim& d) { - return mCtrlData.ctrl.setCrop(d); -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::setTransform( - const utils::eTransform& orient) -{ - //Rotation could be enabled by user for zero-rot or the layer could have - //some transform. Mark rotation enabled in either case. - mRotUsed |= (orient != utils::OVERLAY_TRANSFORM_0); - mRot->setTransform(orient, mRotUsed); - - return mCtrlData.ctrl.setTransform(orient, mRotUsed); -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::setPosition(const utils::Dim& d) -{ - return mCtrlData.ctrl.setPosition(d); -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::commit() { - bool ret = false; - //If wanting to use rotator, start it. - if(mRotUsed) { - if(!mRot->commit()) { - ALOGE("GenPipe Rotator commit failed"); - return false; - } - } - ret = mCtrlData.ctrl.commit(); - pipeState = ret ? OPEN : CLOSED; - return ret; -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::queueBuffer(int fd, uint32_t offset) { - //TODO Move pipe-id transfer to CtrlData class. Make ctrl and data private. - OVASSERT(isOpen(), "State is closed, cannot queueBuffer"); - int pipeId = mCtrlData.ctrl.getPipeId(); - OVASSERT(-1 != pipeId, "Ctrl ID should not be -1"); - // set pipe id from ctrl to data - mCtrlData.data.setPipeId(pipeId); - - int finalFd = fd; - uint32_t finalOffset = offset; - //If rotator is to be used, queue to it, so it can ROTATE. - if(mRotUsed) { - if(!mRot->queueBuffer(fd, offset)) { - ALOGE("GenPipe Rotator play failed"); - return false; - } - //Configure MDP's source buffer as the current output buffer of rotator - if(mRot->getDstMemId() != -1) { - finalFd = mRot->getDstMemId(); - finalOffset = mRot->getDstOffset(); - } else { - //Could be -1 for NullRotator, if queue above succeeds. - //Need an actual rotator. Modify overlay State Traits. - //Not fatal, keep queuing to MDP without rotation. - ALOGE("Null rotator in use, where an actual is required"); - } - } - return mCtrlData.data.queueBuffer(finalFd, finalOffset); -} - -template <int PANEL> -inline int GenericPipe<PANEL>::getCtrlFd() const { - return mCtrlData.ctrl.getFd(); -} - -template <int PANEL> -inline utils::Dim GenericPipe<PANEL>::getAspectRatio( - const utils::Whf& whf) const -{ - return mCtrlData.ctrl.getAspectRatio(whf); -} - -template <int PANEL> -inline utils::Dim GenericPipe<PANEL>::getAspectRatio( - const utils::Dim& dim) const -{ - return mCtrlData.ctrl.getAspectRatio(dim); -} - -template <int PANEL> -inline utils::ScreenInfo GenericPipe<PANEL>::getScreenInfo() const -{ - return mCtrlData.ctrl.getScreenInfo(); -} - -template <int PANEL> -inline utils::Dim GenericPipe<PANEL>::getCrop() const -{ - return mCtrlData.ctrl.getCrop(); -} - -template <int PANEL> -void GenericPipe<PANEL>::dump() const -{ - ALOGE("== Dump Generic pipe start =="); - ALOGE("pipe state = %d", (int)pipeState); - OVASSERT(mRot, "GenericPipe should have a valid Rot"); - mCtrlData.ctrl.dump(); - mCtrlData.data.dump(); - mRot->dump(); - ALOGE("== Dump Generic pipe end =="); -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::isClosed() const { - return (pipeState == CLOSED); -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::isOpen() const { - return (pipeState == OPEN); -} - -template <int PANEL> -inline bool GenericPipe<PANEL>::setClosed() { - pipeState = CLOSED; - return true; -} - } //namespace overlay #endif // OVERLAY_GENERIC_PIPE_H diff --git a/liboverlay/pipes/overlayUIMirrorPipe.h b/liboverlay/pipes/overlayUIMirrorPipe.h deleted file mode 100644 index c2b73bdfa..000000000 --- a/liboverlay/pipes/overlayUIMirrorPipe.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following -* disclaimer in the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its -* contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef OVERLAY_UI_PIPE_H -#define OVERLAY_UI_PIPE_H - -#include "overlayGenPipe.h" -#include "overlayUtils.h" -#include "overlayCtrlData.h" -#include "overlayMdp.h" -#include "overlayRotator.h" - -namespace overlay { - -/* A specific impl of GenericPipe -* Whenever needed to have a pass through - we do it. -* If there is a special need for a different behavior - do it here */ -class UIMirrorPipe : utils::NoCopy { -public: - /* Please look at overlayGenPipe.h for info */ - explicit UIMirrorPipe(); - ~UIMirrorPipe(); - bool init(RotatorBase* rot); - bool close(); - bool commit(); - bool queueBuffer(int fd, uint32_t offset); - bool setCrop(const utils::Dim& dim); - bool setPosition(const utils::Dim& dim); - bool setTransform(const utils::eTransform& param); - bool setSource(const utils::PipeArgs& args); - void dump() const; -private: - overlay::GenericPipe<ovutils::EXTERNAL> mUI; - utils::eTransform mPrimFBOr; //Primary FB's orientation -}; - -//----------------------------Inlines ----------------------------- - -inline UIMirrorPipe::UIMirrorPipe() { mPrimFBOr = utils::OVERLAY_TRANSFORM_0; } -inline UIMirrorPipe::~UIMirrorPipe() { close(); } -inline bool UIMirrorPipe::init(RotatorBase* rot) { - ALOGE_IF(DEBUG_OVERLAY, "UIMirrorPipe init"); - bool ret = mUI.init(rot); - //If source to rotator is FB, which is the case with UI Mirror pipe, - //we need to inform driver during playback, since FB does not use ION. - rot->setSrcFB(); - return ret; -} -inline bool UIMirrorPipe::close() { return mUI.close(); } -inline bool UIMirrorPipe::commit() { return mUI.commit(); } -inline bool UIMirrorPipe::queueBuffer(int fd, uint32_t offset) { - return mUI.queueBuffer(fd, offset); -} -inline bool UIMirrorPipe::setCrop(const utils::Dim& dim) { - return mUI.setCrop(dim); } - -inline bool UIMirrorPipe::setPosition(const utils::Dim& dim) { - ovutils::Dim pdim; - //using utils::eTransform; - switch (mPrimFBOr) { - case utils::OVERLAY_TRANSFORM_0: - case utils::OVERLAY_TRANSFORM_ROT_180: - { - ovutils::Whf whf(dim.w, dim.h, 0); - pdim = mUI.getAspectRatio(whf); - break; - } - case utils::OVERLAY_TRANSFORM_ROT_90: - case utils::OVERLAY_TRANSFORM_ROT_270: - { - // Calculate the Aspectratio for the UI in the landscape mode - // Width and height will be swapped as there is rotation - ovutils::Whf whf(dim.h, dim.w, 0); - pdim = mUI.getAspectRatio(whf); - break; - } - default: - ALOGE("%s: Unknown orientation %d", __FUNCTION__, dim.o); - return false; - } - return mUI.setPosition(pdim); -} - -inline bool UIMirrorPipe::setTransform(const utils::eTransform& param) { - - //Cache the primary FB orientation, since the TV's will be 0, we need this - //info to translate later. - mPrimFBOr = param; - utils::eTransform transform = param; - - // Figure out orientation to transform to - switch (param) { - case utils::OVERLAY_TRANSFORM_0: - transform = utils::OVERLAY_TRANSFORM_0; - break; - case utils::OVERLAY_TRANSFORM_ROT_180: - //If prim FB is drawn 180 rotated, rotate by additional 180 to make - //it to 0, which is TV's orientation. - transform = utils::OVERLAY_TRANSFORM_ROT_180; - break; - case utils::OVERLAY_TRANSFORM_ROT_90: - //If prim FB is drawn 90 rotated, rotate by additional 270 to make - //it to 0, which is TV's orientation. - transform = utils::OVERLAY_TRANSFORM_ROT_270; - break; - case utils::OVERLAY_TRANSFORM_ROT_270: - //If prim FB is drawn 270 rotated, rotate by additional 90 to make - //it to 0, which is TV's orientation. - transform = utils::OVERLAY_TRANSFORM_ROT_90; - break; - default: - ALOGE("%s: Unknown orientation %d", __FUNCTION__, - static_cast<int>(param)); - return false; - } - - return mUI.setTransform(transform); -} - -inline bool UIMirrorPipe::setSource(const utils::PipeArgs& args) { - utils::PipeArgs arg(args); - - // Rotator flag enabled because buffer comes from fb - arg.rotFlags = utils::ROT_FLAG_ENABLED; - - // For true UI mirroring, want the UI to go through available RGB pipe - // so do not set the PIPE SHARE flag which allocates VG pipe - if (utils::FrameBufferInfo::getInstance()->supportTrueMirroring()) { - arg.mdpFlags = static_cast<utils::eMdpFlags>( - arg.mdpFlags & ~utils::OV_MDP_PIPE_SHARE); - } - - return mUI.setSource(arg); -} -inline void UIMirrorPipe::dump() const { - ALOGE("UI Mirror Pipe"); - mUI.dump(); -} - - -} // overlay - -#endif // OVERLAY_UI_PIPE_H diff --git a/liboverlay/pipes/overlayVideoExtPipe.h b/liboverlay/pipes/overlayVideoExtPipe.h deleted file mode 100644 index d4e1f3fe5..000000000 --- a/liboverlay/pipes/overlayVideoExtPipe.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following -* disclaimer in the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its -* contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef OVERLAY_VIDEO_EXT_PIPE_H -#define OVERLAY_VIDEO_EXT_PIPE_H - -#include "overlayGenPipe.h" -#include "overlayUtils.h" -#include "overlayCtrlData.h" -#include "overlayMdp.h" -#include "overlayRotator.h" - -namespace overlay { - -/* A specific impl of GenericPipe -* Whenever needed to have a pass through - we do it. -* If there is a special need for a different behavior - do it here */ -class VideoExtPipe : utils::NoCopy { -public: - /* Please look at overlayGenPipe.h for info */ - explicit VideoExtPipe(); - ~VideoExtPipe(); - bool init(RotatorBase* rot); - bool close(); - bool commit(); - bool queueBuffer(int fd, uint32_t offset); - bool setCrop(const utils::Dim& dim); - bool setPosition(const utils::Dim& dim); - bool setTransform(const utils::eTransform& param); - bool setSource(const utils::PipeArgs& args); - void dump() const; -private: - overlay::GenericPipe<ovutils::EXTERNAL> mVideoExt; -}; - -//------------------Inlines ----------------------------- - -inline VideoExtPipe::VideoExtPipe() {} -inline VideoExtPipe::~VideoExtPipe() { close(); } -inline bool VideoExtPipe::init(RotatorBase* rot) { - ALOGE_IF(DEBUG_OVERLAY, "VideoExtPipe init"); - return mVideoExt.init(rot); -} -inline bool VideoExtPipe::close() { return mVideoExt.close(); } -inline bool VideoExtPipe::commit() { return mVideoExt.commit(); } -inline bool VideoExtPipe::queueBuffer(int fd, uint32_t offset) { - return mVideoExt.queueBuffer(fd, offset); -} -inline bool VideoExtPipe::setCrop(const utils::Dim& dim) { - return mVideoExt.setCrop(dim); -} -inline bool VideoExtPipe::setPosition(const utils::Dim& dim) -{ - utils::Dim d; - // Need to change dim to aspect ratio - if (utils::FrameBufferInfo::getInstance()->supportTrueMirroring()) { - // Use dim info to calculate aspect ratio for true UI mirroring - d = mVideoExt.getAspectRatio(dim); - } else { - // Use cached crop data to get aspect ratio - utils::Dim crop = mVideoExt.getCrop(); - utils::Whf whf(crop.w, crop.h, 0); - d = mVideoExt.getAspectRatio(whf); - } - ALOGE_IF(DEBUG_OVERLAY, "Calculated aspect ratio for EXT: x=%d, y=%d, w=%d," - "h=%d, o=%d", - d.x, d.y, d.w, d.h, d.o); - return mVideoExt.setPosition(d); -} -inline bool VideoExtPipe::setTransform(const utils::eTransform& param) { - return mVideoExt.setTransform(param); -} -inline bool VideoExtPipe::setSource(const utils::PipeArgs& args) { - utils::PipeArgs arg(args); - return mVideoExt.setSource(arg); -} -inline void VideoExtPipe::dump() const { - ALOGE("Video Ext Pipe"); - mVideoExt.dump(); -} - - -} // overlay - -#endif // OVERLAY_VIDEO_EXT_PIPE_H diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk index 8ecfaf8ab..61daeacf9 100644 --- a/libqdutils/Android.mk +++ b/libqdutils/Android.mk @@ -4,10 +4,10 @@ include $(CLEAR_VARS) LOCAL_MODULE := libqdutils LOCAL_MODULE_TAGS := optional -LOCAL_SHARED_LIBRARIES := $(common_libs) libdl +LOCAL_SHARED_LIBRARIES := $(common_libs) LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes) LOCAL_CFLAGS := $(common_flags) LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := profiler.cpp mdp_version.cpp \ - idle_invalidator.cpp egl_handles.cpp + idle_invalidator.cpp include $(BUILD_SHARED_LIBRARY) diff --git a/libqdutils/clear_regions.h b/libqdutils/clear_regions.h deleted file mode 100644 index 2d1f3df74..000000000 --- a/libqdutils/clear_regions.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of Code Aurora Forum, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef QCOM_CLEARREGIONS_H -#define QCOM_CLEARREGIONS_H - -#include <gralloc_priv.h> -#include <cutils/memory.h> -#include <comptype.h> -#include "egl_handles.h" - -namespace qdutils { -/* - * Clear Region implementation for C2D/MDP versions. - * - * @param: region to be cleared - * @param: EGL Display - * @param: EGL Surface - * - * @return 0 on success - */ -static int qcomuiClearRegion(Region region, EGLDisplay dpy){ - - int ret = 0; - int compositionType = QCCompositionType::getInstance().getCompositionType(); - if (compositionType == COMPOSITION_TYPE_GPU){ - //SF can use the GPU to draw the wormhole. - return -1; - } - - android_native_buffer_t *renderBuffer = - qdutils::eglHandles::getInstance().getAndroidNativeRenderBuffer(dpy); - if (!renderBuffer) { - ALOGE("%s: eglGetRenderBufferANDROID returned NULL buffer", - __FUNCTION__); - return -1; - } - private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle; - if(!fbHandle) { - ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__); - return -1; - } - - int bytesPerPixel = 4; - if (HAL_PIXEL_FORMAT_RGB_565 == fbHandle->format) { - bytesPerPixel = 2; - } - - Region::const_iterator it = region.begin(); - Region::const_iterator const end = region.end(); - const int32_t stride = renderBuffer->stride*bytesPerPixel; - while (it != end) { - const Rect& r = *it++; - uint8_t* dst = (uint8_t*) fbHandle->base + - (r.left + r.top*renderBuffer->stride)*bytesPerPixel; - int w = r.width()*bytesPerPixel; - int h = r.height(); - do { - if(4 == bytesPerPixel) - android_memset32((uint32_t*)dst, 0, w); - else - android_memset16((uint16_t*)dst, 0, w); - dst += stride; - } while(--h); - } - return 0; -} -}; //namespace qdutils -#endif /* end of include guard: QCOM_CLEARREGIONS_H*/ diff --git a/libqdutils/egl_handles.cpp b/libqdutils/egl_handles.cpp deleted file mode 100644 index d8a15dea2..000000000 --- a/libqdutils/egl_handles.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * Copyright (C) 2012, Code Aurora Forum. All rights reserved. - * - * Not a Contribution, Apache license notifications and license are retained - * for attribution purposes only. - * - * 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 <cutils/log.h> -#include <fcntl.h> -#include "egl_handles.h" -#include <dlfcn.h> - -ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::eglHandles); -namespace qdutils { - -eglHandles::eglHandles(){ - LINK_eglGetRenderBufferANDROID = NULL ; - LINK_eglGetCurrentSurface = NULL; - egl_lib = NULL; - openEglLibAndGethandle(); - updateEglHandles(egl_lib); -} - -eglHandles::~eglHandles(){ - closeEglLib(); - -} - -void eglHandles::updateEglHandles(void* egl_lib){ - - if(egl_lib != NULL) { - *(void **)&LINK_eglGetRenderBufferANDROID = - ::dlsym(egl_lib, "eglGetRenderBufferANDROID"); - *(void **)&LINK_eglGetCurrentSurface = - ::dlsym(egl_lib, "eglGetCurrentSurface"); - if(LINK_eglGetRenderBufferANDROID == NULL || - LINK_eglGetCurrentSurface == NULL) - ALOGE(" %s::Unable to find symbols",__FUNCTION__) ; - }else { - LINK_eglGetRenderBufferANDROID = NULL; - LINK_eglGetCurrentSurface = NULL; - } -} - -void eglHandles::openEglLibAndGethandle(){ - - egl_lib = ::dlopen("libEGL_adreno200.so", RTLD_GLOBAL | RTLD_LAZY); - if (!egl_lib) { - ALOGE(" %s::Unable to open libEGL_adreno200",__FUNCTION__) ; - } -} - -android_native_buffer_t * - eglHandles::getAndroidNativeRenderBuffer(EGLDisplay dpy){ - - if(LINK_eglGetRenderBufferANDROID == NULL || - LINK_eglGetCurrentSurface == NULL){ - ALOGE("%s:: Unable to load or find the symbols ",__FUNCTION__); - return NULL; - } - EGLSurface eglSurface = LINK_eglGetCurrentSurface(EGL_DRAW); - android_native_buffer_t *renderBuffer = - (android_native_buffer_t*)LINK_eglGetRenderBufferANDROID(dpy, eglSurface); - return renderBuffer; -} - -void eglHandles ::closeEglLib(){ - if(egl_lib) - ::dlclose(egl_lib); - egl_lib = NULL; - updateEglHandles(NULL); -} - -}; - - - diff --git a/libqdutils/egl_handles.h b/libqdutils/egl_handles.h deleted file mode 100644 index c5fb24437..000000000 --- a/libqdutils/egl_handles.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * Copyright (C) 2012, Code Aurora Forum. All rights reserved. - * - * Not a Contribution, Apache license notifications and license are retained - * for attribution purposes only. - * - * 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 EGL_HANDLES_H -#define EGL_HANDLES_H - -#include <stdint.h> -#include <utils/Singleton.h> -#include <EGL/egl.h> -#include <gralloc_priv.h> -#include <EGL/eglext.h> - -typedef EGLClientBuffer (*functype_eglGetRenderBufferANDROID) ( - EGLDisplay dpy, - EGLSurface draw); -typedef EGLSurface (*functype_eglGetCurrentSurface)(EGLint readdraw); - -using namespace android; -namespace qdutils { -class eglHandles : public Singleton <eglHandles> -{ - - functype_eglGetRenderBufferANDROID LINK_eglGetRenderBufferANDROID; - functype_eglGetCurrentSurface LINK_eglGetCurrentSurface; - void* egl_lib; - - void updateEglHandles(void* egl_lib); - void openEglLibAndGethandle(); - void closeEglLib(); - -public : - eglHandles(); - ~eglHandles(); - functype_eglGetRenderBufferANDROID getEGLRenderBufferANDROID(){ - return LINK_eglGetRenderBufferANDROID; - } - functype_eglGetCurrentSurface getEGLCurrentSurface(){ - return LINK_eglGetCurrentSurface; - } - android_native_buffer_t *getAndroidNativeRenderBuffer(EGLDisplay dpy); -}; -}; -#endif // end of EGL_HANDLES_H - - |