libhwcomposer: Add C2D support to copybit

Change-Id: Icb1a010f8079bb3f2122d8520c87d60b757d73bd
This commit is contained in:
Neti Ravi Kumar 2012-07-21 21:02:05 +05:30
parent 8d90904f86
commit 97d3484b12
4 changed files with 163 additions and 76 deletions

View File

@ -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;

View File

@ -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;

View File

@ -18,9 +18,12 @@
* limitations under the License.
*/
#define DEBUG_COPYBIT 0
#include <copybit.h>
#include <genlock.h>
#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; i<list->numHwLayers; 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; i<list->numHwLayers; 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;

View File

@ -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 {