summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcopybit/copybit_c2d.cpp11
-rw-r--r--libhwcomposer/hwc.cpp3
-rw-r--r--libhwcomposer/hwc_copybit.cpp207
-rw-r--r--libhwcomposer/hwc_copybit.h12
4 files changed, 160 insertions, 73 deletions
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index 29bf61e2..365be5f3 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -125,6 +125,7 @@ struct copybit_context_t {
int fb_width;
int fb_height;
bool isPremultipliedAlpha;
+ bool mBlitToFB;
};
struct blitlist{
@@ -782,6 +783,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 ad84d254..e30e06b5 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -87,6 +87,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
@@ -103,7 +105,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 99aecca1..f14d00f4 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -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::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;
+ 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;
- }
+ 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;
-
- framebuffer_device_t* fbDev = ctx->mFbDev;
- if(!fbDev) {
- ALOGE("ERROR: canUseCopybit : fb device is invalid");
- return false;
- }
-
- if (!list)
- return false;
-
- // If , couldnt link to adreno library return false.
- if(LINK_eglGetRenderBufferANDROID == NULL ||
- LINK_eglGetCurrentSurface == NULL )
- return false;
-
- if(!ctx->mMDP.hasOverlay) {
- if (numYUVBuffers)
- return true;
- }
-
- int fb_w = fbDev->width;
- int fb_h = fbDev->height;
+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;
+ }
- /*
- * Use copybit only when we need to blit
- * max 2 full screen sized regions
- */
+ framebuffer_device_t *fbDev = ctx->mFbDev;
- unsigned int renderArea = 0;
+ if (!fbDev) {
+ ALOGE("%s:Invalid FB device", __FUNCTION__);
+ return false;
+ }
- for(unsigned int i = 0; i < list->numHwLayers; i++ ) {
- int w, h;
- getLayerResolution(&list->hwLayers[i], w, h);
- renderArea += w*h;
- }
+ if (LINK_eglGetRenderBufferANDROID == NULL ||
+ LINK_eglGetCurrentSurface == NULL) {
+ ALOGE("%s:Not able to link to ADRENO", __FUNCTION__);
+ return false;
+ }
- 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 602898e5..8390968d 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 {