diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp index 430da0c..ad203f3 100644 --- a/libhwcomposer/hwc_copybit.cpp +++ b/libhwcomposer/hwc_copybit.cpp @@ -22,8 +22,8 @@ #include #include #include "hwc_copybit.h" -#include "hwc_copybit.h" #include "comptype.h" +#include "egl_handles.h" namespace qhwc { @@ -65,46 +65,11 @@ 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; -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::sCopyBitDraw = false; bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) { // return true for non-overlay targets if(ctx->mMDP.hasOverlay) { @@ -188,7 +153,7 @@ bool CopyBit::prepare(hwc_context_t *ctx, hwc_layer_list_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; @@ -198,11 +163,13 @@ bool CopyBit::prepare(hwc_context_t *ctx, hwc_layer_list_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; } } } @@ -213,9 +180,18 @@ bool CopyBit::draw(hwc_context_t *ctx, hwc_layer_list_t *list, EGLDisplay dpy, EGLSurface sur){ // draw layers marked for COPYBIT int retVal = true; - EGLSurface eglSurface = LINK_eglGetCurrentSurface(EGL_DRAW); + + if(sCopyBitDraw == false) // there is no any layer marked for copybit + return true ; + android_native_buffer_t *renderBuffer = - (android_native_buffer_t *)LINK_eglGetRenderBufferANDROID(dpy, eglSurface); + qdutils::eglHandles::getInstance().getAndroidNativeRenderBuffer(dpy); + if (!renderBuffer) { + ALOGE("%s: eglGetRenderBufferANDROID returned NULL buffer", + __FUNCTION__); + return -1; + } + for (size_t i=0; inumHwLayers; i++) { if (list->hwLayers[i].compositionType == HWC_USE_COPYBIT) { retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]), @@ -483,13 +459,6 @@ bool CopyBit::validateParams(hwc_context_t *ctx, const hwc_layer_list_t *list) { 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; } @@ -512,11 +481,9 @@ CopybitEngine::CopybitEngine(){ } else { ALOGE("FATAL ERROR: copybit open failed."); } - CopyBit::openEglLibAndGethandle(); } CopybitEngine::~CopybitEngine() { - CopyBit::closeEglLib(); if(sEngine) { copybit_close(sEngine); diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h index d020091..62cb340 100644 --- a/libhwcomposer/hwc_copybit.h +++ b/libhwcomposer/hwc_copybit.h @@ -30,11 +30,6 @@ #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: @@ -71,11 +66,8 @@ private: static bool sIsLayerSkip; //Flags if this feature is on. static bool sIsModeOn; - //handle for adreno lib - static void* egl_lib; - - static functype_eglGetRenderBufferANDROID LINK_eglGetRenderBufferANDROID; - static functype_eglGetCurrentSurface LINK_eglGetCurrentSurface; + // flag that indicates whether CopyBit is enabled or not + static bool sCopyBitDraw; static unsigned int getRGBRenderingArea (const hwc_layer_list_t *list); diff --git a/libqdutils/Android.mk b/libqdutils/Android.mk index 61daeac..2bf03a2 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) -LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes) +LOCAL_SHARED_LIBRARIES := $(common_libs) libdl +LOCAL_C_INCLUDES := $(common_includes) LOCAL_CFLAGS := $(common_flags) LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_SRC_FILES := profiler.cpp mdp_version.cpp \ - idle_invalidator.cpp + idle_invalidator.cpp egl_handles.cpp include $(BUILD_SHARED_LIBRARY) diff --git a/libqdutils/clear_regions.h b/libqdutils/clear_regions.h new file mode 100644 index 0000000..5bed692 --- /dev/null +++ b/libqdutils/clear_regions.h @@ -0,0 +1,93 @@ +/* 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 +#include +#include +#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_DYN|COMPOSITION_TYPE_C2D)){ + // For DYN comp. with C2D, return an error, so that 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 new file mode 100644 index 0000000..d8a15de --- /dev/null +++ b/libqdutils/egl_handles.cpp @@ -0,0 +1,91 @@ +/* + * 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 +#include +#include "egl_handles.h" +#include + +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 new file mode 100644 index 0000000..c5fb244 --- /dev/null +++ b/libqdutils/egl_handles.h @@ -0,0 +1,63 @@ +/* + * 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 +#include +#include +#include +#include + +typedef EGLClientBuffer (*functype_eglGetRenderBufferANDROID) ( + EGLDisplay dpy, + EGLSurface draw); +typedef EGLSurface (*functype_eglGetCurrentSurface)(EGLint readdraw); + +using namespace android; +namespace qdutils { +class eglHandles : public Singleton +{ + + 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 + +