summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRuben Brunk <rubenbrunk@google.com>2014-06-27 15:51:55 -0700
committerRuben Brunk <rubenbrunk@google.com>2014-07-14 22:14:32 +0000
commit1681d95989271f3a9ac0dbb93d10e4a29f2b4444 (patch)
tree52e23db3604b9b52d3f4d62324f279cb8942de69 /libs
parentf3381cf1a645f857dccad9a4369ae23054e9d7d4 (diff)
downloadframeworks_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.cpp11
-rw-r--r--libs/gui/IGraphicBufferProducer.cpp4
-rw-r--r--libs/gui/Surface.cpp40
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(&timestamp, &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");