diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index b2169c84c..ff85eb5ce 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -921,7 +921,11 @@ status_t BufferQueueProducer::queueBuffer(int slot, // Call back without the main BufferQueue lock held, but with the callback // lock held so we can ensure that callbacks occur in order - { + + int connectedApi; + sp lastQueuedFence; + + { // scope for the lock Mutex::Autolock lock(mCallbackMutex); while (callbackTicket != mCurrentCallbackTicket) { mCallbackCondition.wait(mCallbackMutex); @@ -933,20 +937,24 @@ status_t BufferQueueProducer::queueBuffer(int slot, frameReplacedListener->onFrameReplaced(item); } + connectedApi = mCore->mConnectedApi; + lastQueuedFence = std::move(mLastQueueBufferFence); + + mLastQueueBufferFence = std::move(fence); + mLastQueuedCrop = item.mCrop; + mLastQueuedTransform = item.mTransform; + ++mCurrentCallbackTicket; mCallbackCondition.broadcast(); } // Wait without lock held - if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) { + if (connectedApi == NATIVE_WINDOW_API_EGL) { // Waiting here allows for two full buffers to be queued but not a // third. In the event that frames take varying time, this makes a // small trade-off in favor of latency rather than throughput. - mLastQueueBufferFence->waitForever("Throttling EGL Production"); + lastQueuedFence->waitForever("Throttling EGL Production"); } - mLastQueueBufferFence = fence; - mLastQueuedCrop = item.mCrop; - mLastQueuedTransform = item.mTransform; return NO_ERROR; } diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 16ccbc30e..d423d124a 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1178,7 +1178,8 @@ void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { static status_t copyBlt( const sp& dst, const sp& src, - const Region& reg) + const Region& reg, + int *dstFenceFd) { // src and dst with, height and format must be identical. no verification // is done here. @@ -1189,9 +1190,10 @@ static status_t copyBlt( ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); uint8_t* dst_bits = NULL; - err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), - reinterpret_cast(&dst_bits)); + err = dst->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), + reinterpret_cast(&dst_bits), *dstFenceFd); ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); + *dstFenceFd = -1; Region::const_iterator head(reg.begin()); Region::const_iterator tail(reg.end()); @@ -1225,7 +1227,7 @@ static status_t copyBlt( src->unlock(); if (dst_bits) - dst->unlock(); + dst->unlockAsync(dstFenceFd); return err; } @@ -1285,8 +1287,9 @@ status_t Surface::lock( } } const Region copyback(oldDirtyRegion.subtract(newDirtyRegion)); - if (!copyback.isEmpty()) - copyBlt(backBuffer, frontBuffer, copyback); + if (!copyback.isEmpty()) { + copyBlt(backBuffer, frontBuffer, copyback, &fenceFd); + } } else { // if we can't copy-back anything, modify the user's dirty // region to make sure they redraw the whole buffer diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 736c4d553..9114fdc75 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -58,7 +58,11 @@ #include #define DEBUG_RESIZE 0 +#ifdef QTI_BSP +#define NUM_PIXEL_LOW_RES_PANEL (720*1280) +#endif +#define MAX_POSITION 32767 namespace android { // --------------------------------------------------------------------------- @@ -1059,17 +1063,38 @@ void Layer::drawWithOpenGL(const sp& hw, * like more of a hack. */ #ifdef QTI_BSP + const uint32_t hw_w = hw->getWidth(); + const uint32_t hw_h = hw->getHeight(); Rect win(s.active.w, s.active.h); + if((hw_w * hw_h) > NUM_PIXEL_LOW_RES_PANEL) { + if (!s.crop.isEmpty()) { + win = s.crop; + } - if (!s.crop.isEmpty()) { - win = s.crop; - } + win = s.active.transform.transform(win); + win.intersect(hw->getViewport(), &win); + if (!s.finalCrop.isEmpty()) { + if (!win.intersect(s.finalCrop, &win)) { + win.clear(); + } + } + win = s.active.transform.inverse().transform(win); + win.intersect(Rect(s.active.w, s.active.h), &win); + win = reduce(win, s.activeTransparentRegion); + } else { + win = computeBounds(); - win = s.active.transform.transform(win); - win.intersect(hw->getViewport(), &win); - win = s.active.transform.inverse().transform(win); - win.intersect(Rect(s.active.w, s.active.h), &win); - win = reduce(win, s.activeTransparentRegion); + if (!s.finalCrop.isEmpty()) { + win = s.active.transform.transform(win); + if (!win.intersect(s.finalCrop, &win)) { + win.clear(); + } + win = s.active.transform.inverse().transform(win); + if (!win.intersect(computeBounds(), &win)) { + win.clear(); + } + } + } #else Rect win(computeBounds()); @@ -1281,35 +1306,45 @@ void Layer::computeGeometry(const sp& hw, Mesh& mesh, win.intersect(s.crop, &win); } #ifdef QTI_BSP - win = s.active.transform.transform(win); - win.intersect(hw->getViewport(), &win); - win = s.active.transform.inverse().transform(win); - win.intersect(Rect(s.active.w, s.active.h), &win); - win = reduce(win, s.activeTransparentRegion); + const uint32_t hw_w = hw->getWidth(); + uint32_t orientation = 0; + if((hw_w * hw_h) > NUM_PIXEL_LOW_RES_PANEL) { + win = s.active.transform.transform(win); + win.intersect(hw->getViewport(), &win); + if (!s.finalCrop.isEmpty()) { + if (!win.intersect(s.finalCrop, &win)) { + win.clear(); + } + } + win = s.active.transform.inverse().transform(win); + win.intersect(Rect(s.active.w, s.active.h), &win); + win = reduce(win, s.activeTransparentRegion); - const Transform bufferOrientation(mCurrentTransform); - Transform transform(tr * s.active.transform * bufferOrientation); - if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { - uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform(); - if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { - invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | + const Transform bufferOrientation(mCurrentTransform); + Transform transform(tr * s.active.transform * bufferOrientation); + if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { + uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform(); + if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { + invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | NATIVE_WINDOW_TRANSFORM_FLIP_H; - } - transform = Transform(invTransform) * transform; - } - const uint32_t orientation = transform.getOrientation(); - if (!(orientation | mCurrentTransform | mTransformHint)) { - if (!useIdentityTransform) { - win = s.active.transform.transform(win); - win.intersect(hw->getViewport(), &win); + } + transform = Transform(invTransform) * transform; + } + orientation = transform.getOrientation(); + if (!(orientation | mCurrentTransform | mTransformHint)) { + if (!useIdentityTransform) { + win = s.active.transform.transform(win); + win.intersect(hw->getViewport(), &win); + } } + } else { + win = reduce(win, s.activeTransparentRegion); } #else win = reduce(win, s.activeTransparentRegion); #endif - // subtract the transparent region and snap to the bounds vec2 lt = vec2(win.left, win.top); @@ -1319,17 +1354,24 @@ void Layer::computeGeometry(const sp& hw, Mesh& mesh, if (!useIdentityTransform) { #ifdef QTI_BSP - if (orientation | mCurrentTransform | mTransformHint) { + if((hw_w * hw_h) > NUM_PIXEL_LOW_RES_PANEL) { + if (orientation | mCurrentTransform | mTransformHint) { + lt = s.active.transform.transform(lt); + lb = s.active.transform.transform(lb); + rb = s.active.transform.transform(rb); + rt = s.active.transform.transform(rt); + } + } else { lt = s.active.transform.transform(lt); lb = s.active.transform.transform(lb); rb = s.active.transform.transform(rb); rt = s.active.transform.transform(rt); } #else - lt = s.active.transform.transform(lt); - lb = s.active.transform.transform(lb); - rb = s.active.transform.transform(rb); - rt = s.active.transform.transform(rt); + lt = s.active.transform.transform(lt); + lb = s.active.transform.transform(lb); + rb = s.active.transform.transform(rb); + rt = s.active.transform.transform(rt); #endif } if (!s.finalCrop.isEmpty()) { @@ -1652,6 +1694,10 @@ uint32_t Layer::setTransactionFlags(uint32_t flags) { bool Layer::setPosition(float x, float y, bool immediate) { if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y) return false; + if ((y > MAX_POSITION) || (x > MAX_POSITION)) { + ALOGE("%s:: failed %s x = %f y = %f",__FUNCTION__,mName.string(),x, y); + return false; + } mCurrentState.sequence++; // We update the requested and active position simultaneously because diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp index c99dd6478..ed144c1bd 100644 --- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp +++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp @@ -1197,7 +1197,7 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) mAnimFrameTracker.advanceFrame(); } - dumpDrawCycle(true); + dumpDrawCycle(false); if (hw->getPowerMode() == HWC_POWER_MODE_OFF) { return;