diff options
author | Ruben Brunk <rubenbrunk@google.com> | 2014-06-27 15:51:55 -0700 |
---|---|---|
committer | Ruben Brunk <rubenbrunk@google.com> | 2014-07-14 22:14:32 +0000 |
commit | 1681d95989271f3a9ac0dbb93d10e4a29f2b4444 (patch) | |
tree | 52e23db3604b9b52d3f4d62324f279cb8942de69 /libs | |
parent | f3381cf1a645f857dccad9a4369ae23054e9d7d4 (diff) | |
download | frameworks_native-1681d95989271f3a9ac0dbb93d10e4a29f2b4444.zip frameworks_native-1681d95989271f3a9ac0dbb93d10e4a29f2b4444.tar.gz frameworks_native-1681d95989271f3a9ac0dbb93d10e4a29f2b4444.tar.bz2 |
Add sticky transform to surfaceflinger.
Bug: 15116722
- Adds a sticky transform field that can be set from a
SurfaceFlinger client Surface. This transform is
added to any transform applied to the Surface.
Change-Id: Idaa4311dfd027b2d2b8ea5e2c6cba2da5779d753
Diffstat (limited to 'libs')
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 11 | ||||
-rw-r--r-- | libs/gui/IGraphicBufferProducer.cpp | 4 | ||||
-rw-r--r-- | libs/gui/Surface.cpp | 40 |
3 files changed, 50 insertions, 5 deletions
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 70c3ff3..6feebf7 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -37,7 +37,8 @@ namespace android { BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) : mCore(core), mSlots(core->mSlots), - mConsumerName() {} + mConsumerName(), + mStickyTransform(0) {} BufferQueueProducer::~BufferQueueProducer() {} @@ -509,10 +510,11 @@ status_t BufferQueueProducer::queueBuffer(int slot, Rect crop; int scalingMode; uint32_t transform; + uint32_t stickyTransform; bool async; sp<Fence> fence; input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform, - &async, &fence); + &async, &fence, &stickyTransform); if (fence == NULL) { BQ_LOGE("queueBuffer: fence is NULL"); @@ -601,6 +603,8 @@ status_t BufferQueueProducer::queueBuffer(int slot, item.mFence = fence; item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async; + mStickyTransform = stickyTransform; + if (mCore->mQueue.empty()) { // When the queue is empty, we can ignore mDequeueBufferCannotBlock // and simply queue this buffer @@ -701,6 +705,9 @@ int BufferQueueProducer::query(int what, int *outValue) { case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: value = mCore->getMinUndequeuedBufferCountLocked(false); break; + case NATIVE_WINDOW_STICKY_TRANSFORM: + value = static_cast<int>(mStickyTransform); + break; case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: value = (mCore->mQueue.size() > 1); break; diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 8d9a800..1e28f9b 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -435,6 +435,7 @@ size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const { + sizeof(crop) + sizeof(scalingMode) + sizeof(transform) + + sizeof(stickyTransform) + sizeof(async) + fence->getFlattenedSize(); } @@ -454,6 +455,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten( FlattenableUtils::write(buffer, size, crop); FlattenableUtils::write(buffer, size, scalingMode); FlattenableUtils::write(buffer, size, transform); + FlattenableUtils::write(buffer, size, stickyTransform); FlattenableUtils::write(buffer, size, async); return fence->flatten(buffer, size, fds, count); } @@ -467,6 +469,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( + sizeof(crop) + sizeof(scalingMode) + sizeof(transform) + + sizeof(stickyTransform) + sizeof(async); if (size < minNeeded) { @@ -478,6 +481,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten( FlattenableUtils::read(buffer, size, crop); FlattenableUtils::read(buffer, size, scalingMode); FlattenableUtils::read(buffer, size, transform); + FlattenableUtils::read(buffer, size, stickyTransform); FlattenableUtils::read(buffer, size, async); fence = new Fence(); diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 8cb9189..86451be 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -66,6 +66,7 @@ Surface::Surface( mCrop.clear(); mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; mTransform = 0; + mStickyTransform = 0; mDefaultWidth = 0; mDefaultHeight = 0; mUserWidth = 0; @@ -315,15 +316,22 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); IGraphicBufferProducer::QueueBufferOutput output; IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, - crop, mScalingMode, mTransform, mSwapIntervalZero, fence); + crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero, + fence, mStickyTransform); status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); if (err != OK) { ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); } uint32_t numPendingBuffers = 0; - output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, + uint32_t hint = 0; + output.deflate(&mDefaultWidth, &mDefaultHeight, &hint, &numPendingBuffers); + // Disable transform hint if sticky transform is set. + if (mStickyTransform == 0) { + mTransformHint = hint; + } + mConsumerRunningBehind = (numPendingBuffers >= 2); return err; @@ -405,6 +413,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: res = dispatchSetBuffersTransform(args); break; + case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM: + res = dispatchSetBuffersStickyTransform(args); + break; case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: res = dispatchSetBuffersTimestamp(args); break; @@ -502,6 +513,11 @@ int Surface::dispatchSetBuffersTransform(va_list args) { return setBuffersTransform(transform); } +int Surface::dispatchSetBuffersStickyTransform(va_list args) { + int transform = va_arg(args, int); + return setBuffersStickyTransform(transform); +} + int Surface::dispatchSetBuffersTimestamp(va_list args) { int64_t timestamp = va_arg(args, int64_t); return setBuffersTimestamp(timestamp); @@ -527,8 +543,15 @@ int Surface::connect(int api) { int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); if (err == NO_ERROR) { uint32_t numPendingBuffers = 0; - output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, + uint32_t hint = 0; + output.deflate(&mDefaultWidth, &mDefaultHeight, &hint, &numPendingBuffers); + + // Disable transform hint if sticky transform is set. + if (mStickyTransform == 0) { + mTransformHint = hint; + } + mConsumerRunningBehind = (numPendingBuffers >= 2); } if (!err && api == NATIVE_WINDOW_API_CPU) { @@ -552,6 +575,8 @@ int Surface::disconnect(int api) { mCrop.clear(); mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; mTransform = 0; + mStickyTransform = 0; + if (api == NATIVE_WINDOW_API_CPU) { mConnectedToCpu = false; } @@ -678,6 +703,15 @@ int Surface::setBuffersTransform(int transform) return NO_ERROR; } +int Surface::setBuffersStickyTransform(int transform) +{ + ATRACE_CALL(); + ALOGV("Surface::setBuffersStickyTransform"); + Mutex::Autolock lock(mMutex); + mStickyTransform = transform; + return NO_ERROR; +} + int Surface::setBuffersTimestamp(int64_t timestamp) { ALOGV("Surface::setBuffersTimestamp"); |