diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp index 72aa279..af03015 100644 --- a/libcopybit/copybit_c2d.cpp +++ b/libcopybit/copybit_c2d.cpp @@ -126,6 +126,7 @@ struct copybit_context_t { int fb_width; int fb_height; bool isPremultipliedAlpha; + bool mBlitToFB; }; struct blitlist{ @@ -783,6 +784,16 @@ static int set_parameter_copybit( case COPYBIT_FRAMEBUFFER_HEIGHT: ctx->fb_height = value; break; + case COPYBIT_BLIT_TO_FRAMEBUFFER: + if (COPYBIT_ENABLE == value) { + ctx->mBlitToFB = value; + } else if (COPYBIT_DISABLE == value) { + ctx->mBlitToFB = value; + } else { + ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d", + __FUNCTION__, value); + } + break; default: ALOGE("%s: default case param=0x%x", __FUNCTION__, name); return -EINVAL; diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp index 6ee461c..1d7cf7b 100644 --- a/libhwcomposer/hwc.cpp +++ b/libhwcomposer/hwc.cpp @@ -86,6 +86,8 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) ExtOnly::reset(); getLayerStats(ctx, list); + // Mark all layers to COPYBIT initially + CopyBit::prepare(ctx, list); if(VideoOverlay::prepare(ctx, list)) { ctx->overlayInUse = true; //Nothing here @@ -102,7 +104,6 @@ static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list) // fail in non-overlay targets. ctx->overlayInUse = false; } - CopyBit::prepare(ctx, list); } return 0; diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp index 99aecca..f14d00f 100644 --- a/libhwcomposer/hwc_copybit.cpp +++ b/libhwcomposer/hwc_copybit.cpp @@ -18,9 +18,12 @@ * limitations under the License. */ +#define DEBUG_COPYBIT 0 #include #include #include "hwc_copybit.h" +#include "hwc_copybit.h" +#include "comptype.h" namespace qhwc { @@ -102,32 +105,124 @@ void CopyBit::updateEglHandles(void* egl_lib) } } -bool CopyBit::prepare(hwc_context_t *ctx, hwc_layer_list_t *list) { - for (int i=list->numHwLayers-1; i >= 0 ; i--) { - private_handle_t *hnd = - (private_handle_t *)list->hwLayers[i].handle; - if (isSkipLayer(&list->hwLayers[i])) { - break; - } else if(canUseCopybit(ctx, list, getYuvCount()) - && !ctx->overlayInUse){ - list->hwLayers[i].compositionType = HWC_USE_COPYBIT; - } else { - list->hwLayers[i].compositionType = HWC_FRAMEBUFFER; - } +bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) { + // return true for non-overlay targets + if(ctx->mMDP.hasOverlay) { + return false; } return true; } + +bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx, hwc_layer_list_t *list) { + int compositionType = + qdutils::QCCompositionType::getInstance().getCompositionType(); + + 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 + return false; + } + } + + if (compositionType & qdutils::COMPOSITION_TYPE_DYN) { + // DYN Composition: + // use copybit, if (TotalRGBRenderArea < 2 * FB Area) + // this is done based on perf inputs in ICS + // TODO: Above condition needs to be re-evaluated in JB + + framebuffer_device_t *fbDev = ctx->mFbDev; + if (!fbDev) { + ALOGE("%s:Invalid FB device", __FUNCTION__); + return false; + } + unsigned int fbArea = (fbDev->width * fbDev->height); + unsigned int renderArea = getRGBRenderingArea(list); + ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u", + __FUNCTION__, renderArea, fbArea); + if (renderArea < (2 * fbArea)) { + return true; + } + } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) { + // MDP composition, use COPYBIT always + return true; + } else if ((compositionType & qdutils::COMPOSITION_TYPE_C2D)) { + // C2D composition, use COPYBIT + return true; + } + return false; +} + +unsigned int CopyBit::getRGBRenderingArea(const hwc_layer_list_t *list) { + //Calculates total rendering area for RGB layers + unsigned int renderArea = 0; + unsigned int w=0, h=0; + for (unsigned int i=0; inumHwLayers; i++) { + private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle; + if (hnd) { + if (BUFFER_TYPE_UI == hnd->bufferType) { + getLayerResolution(&list->hwLayers[i], w, h); + renderArea += (w*h); + } + } + } + return renderArea; +} + +bool CopyBit::prepare(hwc_context_t *ctx, hwc_layer_list_t *list) { + + int compositionType = + qdutils::QCCompositionType::getInstance().getCompositionType(); + + if ((compositionType & qdutils::COMPOSITION_TYPE_GPU) || + (compositionType & qdutils::COMPOSITION_TYPE_CPU)) { + //GPU/CPU composition, don't change layer composition type + return true; + } + + bool useCopybitForYUV = canUseCopybitForYUV(ctx); + bool useCopybitForRGB = canUseCopybitForRGB(ctx, list); + + if(!(validateParams(ctx, list))) { + ALOGE("%s:Invalid Params", __FUNCTION__); + return false; + } + + for (int i=list->numHwLayers-1; i >= 0 ; i--) { + private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle; + + if (isSkipLayer(&list->hwLayers[i])) { + return true; + } else if (hnd->bufferType == BUFFER_TYPE_VIDEO) { + //YUV layer, check, if copybit can be used + if (useCopybitForYUV) { + list->hwLayers[i].compositionType = HWC_USE_COPYBIT; + } + } else if (hnd->bufferType == BUFFER_TYPE_UI) { + //RGB layer, check, if copybit can be used + if (useCopybitForRGB) { + list->hwLayers[i].compositionType = HWC_USE_COPYBIT; + } + } + } + return true; +} + bool CopyBit::draw(hwc_context_t *ctx, hwc_layer_list_t *list, EGLDisplay dpy, - EGLSurface sur){ + EGLSurface sur){ + // draw layers marked for COPYBIT + int retVal = true; for (size_t i=0; inumHwLayers; i++) { - if (list->hwLayers[i].flags & HWC_SKIP_LAYER) { - continue; - } else if (list->hwLayers[i].compositionType == HWC_USE_COPYBIT) { - drawLayerUsingCopybit(ctx, &(list->hwLayers[i]), - (EGLDisplay)dpy, - (EGLSurface)sur, - LINK_eglGetRenderBufferANDROID, - LINK_eglGetCurrentSurface); + if (list->hwLayers[i].compositionType == HWC_USE_COPYBIT) { + retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]), + (EGLDisplay)dpy, + (EGLSurface)sur, + LINK_eglGetRenderBufferANDROID, + LINK_eglGetCurrentSurface); + if(retVal<0) { + ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__); + } } } return true; @@ -307,9 +402,8 @@ int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_t *layer, hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect}; region_iterator tmp_it(tmp_hwc_reg); copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0); - // TODO : alpha not defined , fix this - // copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, - // (layer->blending == HWC_BLENDING_NONE) ? -1 : layer->alpha); + //TODO: once, we are able to read layer alpha, update this + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255); err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect, &srcRect, &tmp_it); if(err < 0){ @@ -335,9 +429,8 @@ int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_t *layer, renderBuffer->height); copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform); - // TODO : alpha not defined , fix this - // copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, - // (layer->blending == HWC_BLENDING_NONE) ? -1 : layer->alpha); + //TODO: once, we are able to read layer alpha, update this + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255); copybit->set_parameter(copybit, COPYBIT_PREMULTIPLIED_ALPHA, (layer->blending == HWC_BLENDING_PREMULT)? COPYBIT_ENABLE : COPYBIT_DISABLE); @@ -366,8 +459,8 @@ int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_t *layer, return err; } -void CopyBit::getLayerResolution(const hwc_layer_t* layer, int& width, - int& height) +void CopyBit::getLayerResolution(const hwc_layer_t* layer, + unsigned int& width, unsigned int& height) { hwc_rect_t displayFrame = layer->displayFrame; @@ -375,54 +468,32 @@ void CopyBit::getLayerResolution(const hwc_layer_t* layer, int& width, height = displayFrame.bottom - displayFrame.top; } -bool CopyBit::canUseCopybit(hwc_context_t *ctx, const hwc_layer_list_t* list, - const int numYUVBuffers) -{ - // XXX : TODO , currently returning false for MDP4 targets, - // This has to be modified after adding C2D support. - if(ctx->mMDP.hasOverlay) - return false; +bool CopyBit::validateParams(hwc_context_t *ctx, const hwc_layer_list_t *list) { + //Validate parameters + if (!ctx) { + ALOGE("%s:Invalid HWC context", __FUNCTION__); + return false; + } else if (!list) { + ALOGE("%s:Invalid HWC layer list", __FUNCTION__); + return false; + } - framebuffer_device_t* fbDev = ctx->mFbDev; - if(!fbDev) { - ALOGE("ERROR: canUseCopybit : fb device is invalid"); - return false; - } + framebuffer_device_t *fbDev = ctx->mFbDev; - if (!list) - return false; + if (!fbDev) { + ALOGE("%s:Invalid FB device", __FUNCTION__); + return false; + } - // If , couldnt link to adreno library return false. - if(LINK_eglGetRenderBufferANDROID == NULL || - LINK_eglGetCurrentSurface == NULL ) - return false; + if (LINK_eglGetRenderBufferANDROID == NULL || + LINK_eglGetCurrentSurface == NULL) { + ALOGE("%s:Not able to link to ADRENO", __FUNCTION__); + return false; + } - if(!ctx->mMDP.hasOverlay) { - if (numYUVBuffers) - return true; - } - - int fb_w = fbDev->width; - int fb_h = fbDev->height; - - /* - * Use copybit only when we need to blit - * max 2 full screen sized regions - */ - - unsigned int renderArea = 0; - - for(unsigned int i = 0; i < list->numHwLayers; i++ ) { - int w, h; - getLayerResolution(&list->hwLayers[i], w, h); - renderArea += w*h; - } - - return (renderArea <= (2 * fb_w * fb_h)); + return true; } - - //CopybitEngine Class functions CopybitEngine* CopybitEngine::sInstance = 0; diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h index 602898e..8390968 100644 --- a/libhwcomposer/hwc_copybit.h +++ b/libhwcomposer/hwc_copybit.h @@ -51,8 +51,11 @@ public: EGLDisplay dpy, EGLSurface surface, functype_eglGetRenderBufferANDROID& LINK_eglGetRenderBufferANDROID, functype_eglGetCurrentSurface LINK_eglGetCurrentSurface); - static bool canUseCopybit(hwc_context_t* ctx, const hwc_layer_list_t* list, - const int numYUVBuffers); + static bool canUseCopybitForYUV (hwc_context_t *ctx); + static bool canUseCopybitForRGB (hwc_context_t *ctx, + hwc_layer_list_t *list); + static bool validateParams (hwc_context_t *ctx, + const hwc_layer_list_t *list); static void closeEglLib(); static void openEglLibAndGethandle(); private: @@ -75,9 +78,10 @@ private: static functype_eglGetRenderBufferANDROID LINK_eglGetRenderBufferANDROID; static functype_eglGetCurrentSurface LINK_eglGetCurrentSurface; - static void getLayerResolution(const hwc_layer_t* layer, int& width, - int& height); + static unsigned int getRGBRenderingArea (const hwc_layer_list_t *list); + static void getLayerResolution(const hwc_layer_t* layer, + unsigned int &width, unsigned int& height); }; class CopybitEngine {