hwc: Use intermediate buffers for copybit
The earlier copybit solution involved blitting directly into
the SurfaceFlinger's framebuffer target. That solution involved
unnecessary framework changes and caused issues when the
framebuffer was being written to both by GL and copybit.
Update hwc_copybit to use our own buffers for this purpose.
We also make sure we display only the region we're interested in
so that unnecessary artifacts from previous blits do not show up
on the display. This way, we can avoid clearing the intermediate
buffers every frame.
Change-Id: I713b3fc606e0768444c621af76853ece41964da1
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index a0dbbe3..f9161a3 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -46,21 +46,24 @@
mDest = ovutils::OV_INVALID;
}
-bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) {
+bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list)
+{
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
__FUNCTION__);
return false;
}
- mModeOn = configure(ctx, fblayer);
+ mModeOn = configure(ctx, list);
ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
return mModeOn;
}
// Configure
-bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer)
+bool FBUpdateLowRes::configure(hwc_context_t *ctx,
+ hwc_display_contents_1 *list)
{
bool ret = false;
+ hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
if (LIKELY(ctx->mOverlay)) {
overlay::Overlay& ov = *(ctx->mOverlay);
private_handle_t *hnd = (private_handle_t *)layer->handle;
@@ -87,7 +90,8 @@
ovutils::ROT_FLAGS_NONE);
ov.setSource(parg, dest);
- hwc_rect_t sourceCrop = layer->sourceCrop;
+ hwc_rect_t sourceCrop;
+ getNonWormholeRegion(list, sourceCrop);
// x,y,w,h
ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
sourceCrop.right - sourceCrop.left,
@@ -99,7 +103,7 @@
static_cast<ovutils::eTransform>(transform);
ov.setTransform(orient, dest);
- hwc_rect_t displayFrame = layer->displayFrame;
+ hwc_rect_t displayFrame = sourceCrop;
ovutils::Dim dpos(displayFrame.left,
displayFrame.top,
displayFrame.right - displayFrame.left,
@@ -118,7 +122,7 @@
return ret;
}
-bool FBUpdateLowRes::draw(hwc_context_t *ctx, hwc_layer_1_t *layer)
+bool FBUpdateLowRes::draw(hwc_context_t *ctx, private_handle_t *hnd)
{
if(!mModeOn) {
return true;
@@ -126,7 +130,6 @@
bool ret = true;
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eDest dest = mDest;
- private_handle_t *hnd = (private_handle_t *)layer->handle;
if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
ALOGE("%s: queueBuffer failed for FBUpdate", __FUNCTION__);
ret = false;
@@ -143,21 +146,24 @@
mDestRight = ovutils::OV_INVALID;
}
-bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) {
+bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list)
+{
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
__FUNCTION__);
return false;
}
ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
- mModeOn = configure(ctx, fblayer);
+ mModeOn = configure(ctx, list);
return mModeOn;
}
// Configure
-bool FBUpdateHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer)
+bool FBUpdateHighRes::configure(hwc_context_t *ctx,
+ hwc_display_contents_1 *list)
{
bool ret = false;
+ hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
if (LIKELY(ctx->mOverlay)) {
overlay::Overlay& ov = *(ctx->mOverlay);
private_handle_t *hnd = (private_handle_t *)layer->handle;
@@ -199,7 +205,8 @@
ovutils::ROT_FLAGS_NONE);
ov.setSource(pargR, destR);
- hwc_rect_t sourceCrop = layer->sourceCrop;
+ hwc_rect_t sourceCrop;
+ getNonWormholeRegion(list, sourceCrop);
ovutils::Dim dcropL(sourceCrop.left, sourceCrop.top,
(sourceCrop.right - sourceCrop.left) / 2,
sourceCrop.bottom - sourceCrop.top);
@@ -217,7 +224,7 @@
ov.setTransform(orient, destL);
ov.setTransform(orient, destR);
- hwc_rect_t displayFrame = layer->displayFrame;
+ hwc_rect_t displayFrame = sourceCrop;
//For FB left, top will always be 0
//That should also be the case if using 2 mixers for single display
ovutils::Dim dpos(displayFrame.left,
@@ -240,7 +247,7 @@
return ret;
}
-bool FBUpdateHighRes::draw(hwc_context_t *ctx, hwc_layer_1_t *layer)
+bool FBUpdateHighRes::draw(hwc_context_t *ctx, private_handle_t *hnd)
{
if(!mModeOn) {
return true;
@@ -249,7 +256,6 @@
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eDest destL = mDestLeft;
ovutils::eDest destR = mDestRight;
- private_handle_t *hnd = (private_handle_t *)layer->handle;
if (!ov.queueBuffer(hnd->fd, hnd->offset, destL)) {
ALOGE("%s: queue failed for left of dpy = %d",
__FUNCTION__, mDpy);