summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yiwei Zhang <zzyiwei@google.com> 2019-06-24 19:35:03 -0700
committer Yiwei Zhang <zzyiwei@google.com> 2019-06-27 10:39:26 -0700
commit538cedc381f66f6b07265f82be65e5bc725c7e87 (patch)
tree599155aac6f4456e88c7622a567306e5cc8a19ac
parent0f400276db433961cf713d7570eef9e9a7165a2e (diff)
BufferQueue: handle consumer driven size for pre-rotation
This change adds an option for the producer to set auto pre-rotation on the buffers to be allocated. When auto pre-rotation is enabled, if the current buffer size is driven by the consumer and there's 90 or 270 degree rotation specified in the transform hint currently used by the producer, then the dimension of the buffers to be allocated will be additionally swapped upon buffers pre-allocaton or dequeueBuffer. Auto prerotaion will be cached at Surface producer side, and will be reset to false upon Surface disconnection. Bug: 129422697 Test: atest libgui_test:SurfaceTest#DequeueWithConsumerDrivenSize Change-Id: I01ddf3e00d5951935e557d18932ea9869f36b5d6
-rw-r--r--libs/gui/BufferQueueCore.cpp12
-rw-r--r--libs/gui/BufferQueueProducer.cpp31
-rw-r--r--libs/gui/IGraphicBufferProducer.cpp29
-rw-r--r--libs/gui/Surface.cpp27
-rw-r--r--libs/gui/include/gui/BufferQueueCore.h8
-rw-r--r--libs/gui/include/gui/BufferQueueProducer.h3
-rw-r--r--libs/gui/include/gui/IGraphicBufferProducer.h8
-rw-r--r--libs/gui/include/gui/Surface.h3
-rw-r--r--libs/gui/tests/Surface_test.cpp70
-rw-r--r--libs/nativewindow/ANativeWindow.cpp4
-rw-r--r--libs/nativewindow/include/system/window.h83
-rw-r--r--libs/nativewindow/include/vndk/window.h9
-rw-r--r--libs/nativewindow/libnativewindow.map.txt1
-rw-r--r--services/surfaceflinger/MonitoredProducer.cpp4
-rw-r--r--services/surfaceflinger/MonitoredProducer.h1
15 files changed, 253 insertions, 40 deletions
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index e0e3431ca5..b429d387ad 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -97,7 +97,9 @@ BufferQueueCore::BufferQueueCore() :
mSharedBufferCache(Rect::INVALID_RECT, 0, NATIVE_WINDOW_SCALING_MODE_FREEZE,
HAL_DATASPACE_UNKNOWN),
mLastQueuedSlot(INVALID_BUFFER_SLOT),
- mUniqueId(getUniqueId())
+ mUniqueId(getUniqueId()),
+ mAutoPrerotation(false),
+ mTransformHintInUse(0)
{
int numStartingBuffers = getMaxBufferCountLocked();
for (int s = 0; s < numStartingBuffers; s++) {
@@ -123,10 +125,12 @@ void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const
mQueueBufferCanDrop, mLegacyBufferDrop);
outResult->appendFormat("%s default-size=[%dx%d] default-format=%d ", prefix.string(),
mDefaultWidth, mDefaultHeight, mDefaultBufferFormat);
- outResult->appendFormat("transform-hint=%02x frame-counter=%" PRIu64, mTransformHint,
- mFrameCounter);
+ outResult->appendFormat("%s transform-hint=%02x frame-counter=%" PRIu64 "\n", prefix.string(),
+ mTransformHint, mFrameCounter);
+ outResult->appendFormat("%s mTransformHintInUse=%02x mAutoPrerotation=%d\n", prefix.string(),
+ mTransformHintInUse, mAutoPrerotation);
- outResult->appendFormat("\n%sFIFO(%zu):\n", prefix.string(), mQueue.size());
+ outResult->appendFormat("%sFIFO(%zu):\n", prefix.string(), mQueue.size());
Fifo::const_iterator current(mQueue.begin());
while (current != mQueue.end()) {
double timestamp = current->mTimestamp / 1e9;
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 9c311a314f..e05667e895 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -408,6 +408,10 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
if (useDefaultSize) {
width = mCore->mDefaultWidth;
height = mCore->mDefaultHeight;
+ if (mCore->mAutoPrerotation &&
+ (mCore->mTransformHintInUse & NATIVE_WINDOW_TRANSFORM_ROT_90)) {
+ std::swap(width, height);
+ }
}
int found = BufferItem::INVALID_BUFFER_SLOT;
@@ -951,7 +955,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
output->width = mCore->mDefaultWidth;
output->height = mCore->mDefaultHeight;
- output->transformHint = mCore->mTransformHint;
+ output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;
output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
output->nextFrameNumber = mCore->mFrameCounter + 1;
@@ -1194,7 +1198,7 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
output->width = mCore->mDefaultWidth;
output->height = mCore->mDefaultHeight;
- output->transformHint = mCore->mTransformHint;
+ output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;
output->numPendingBuffers =
static_cast<uint32_t>(mCore->mQueue.size());
output->nextFrameNumber = mCore->mFrameCounter + 1;
@@ -1298,6 +1302,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
mCore->mConnectedPid = -1;
mCore->mSidebandStream.clear();
mCore->mDequeueCondition.notify_all();
+ mCore->mAutoPrerotation = false;
listener = mCore->mConsumerListener;
} else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
BQ_LOGE("disconnect: not connected (req=%d)", api);
@@ -1341,6 +1346,8 @@ status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream)
void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
PixelFormat format, uint64_t usage) {
ATRACE_CALL();
+
+ const bool useDefaultSize = !width && !height;
while (true) {
size_t newBufferCount = 0;
uint32_t allocWidth = 0;
@@ -1367,6 +1374,11 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
allocWidth = width > 0 ? width : mCore->mDefaultWidth;
allocHeight = height > 0 ? height : mCore->mDefaultHeight;
+ if (useDefaultSize && mCore->mAutoPrerotation &&
+ (mCore->mTransformHintInUse & NATIVE_WINDOW_TRANSFORM_ROT_90)) {
+ std::swap(allocWidth, allocHeight);
+ }
+
allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
allocUsage = usage | mCore->mConsumerUsageBits;
allocName.assign(mCore->mConsumerName.string(), mCore->mConsumerName.size());
@@ -1397,6 +1409,11 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
std::unique_lock<std::mutex> lock(mCore->mMutex);
uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
+ if (useDefaultSize && mCore->mAutoPrerotation &&
+ (mCore->mTransformHintInUse & NATIVE_WINDOW_TRANSFORM_ROT_90)) {
+ std::swap(checkWidth, checkHeight);
+ }
+
PixelFormat checkFormat = format != 0 ?
format : mCore->mDefaultBufferFormat;
uint64_t checkUsage = usage | mCore->mConsumerUsageBits;
@@ -1599,4 +1616,14 @@ status_t BufferQueueProducer::getConsumerUsage(uint64_t* outUsage) const {
return NO_ERROR;
}
+status_t BufferQueueProducer::setAutoPrerotation(bool autoPrerotation) {
+ ATRACE_CALL();
+ BQ_LOGV("setAutoPrerotation: %d", autoPrerotation);
+
+ std::lock_guard<std::mutex> lock(mCore->mMutex);
+
+ mCore->mAutoPrerotation = autoPrerotation;
+ return NO_ERROR;
+}
+
} // namespace android
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 0e03b7d393..0b8c70525b 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -73,6 +73,7 @@ enum {
GET_UNIQUE_ID,
GET_CONSUMER_USAGE,
SET_LEGACY_BUFFER_DROP,
+ SET_AUTO_PREROTATION,
};
class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -547,6 +548,17 @@ public:
}
return actualResult;
}
+
+ virtual status_t setAutoPrerotation(bool autoPrerotation) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+ data.writeBool(autoPrerotation);
+ status_t result = remote()->transact(SET_AUTO_PREROTATION, data, &reply);
+ if (result == NO_ERROR) {
+ result = reply.readInt32();
+ }
+ return result;
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -675,6 +687,10 @@ public:
status_t getConsumerUsage(uint64_t* outUsage) const override {
return mBase->getConsumerUsage(outUsage);
}
+
+ status_t setAutoPrerotation(bool autoPrerotation) override {
+ return mBase->setAutoPrerotation(autoPrerotation);
+ }
};
IMPLEMENT_HYBRID_META_INTERFACE(GraphicBufferProducer,
@@ -688,6 +704,12 @@ status_t IGraphicBufferProducer::setLegacyBufferDrop(bool drop) {
return INVALID_OPERATION;
}
+status_t IGraphicBufferProducer::setAutoPrerotation(bool autoPrerotation) {
+ // No-op for IGBP other than BufferQueue.
+ (void)autoPrerotation;
+ return INVALID_OPERATION;
+}
+
status_t IGraphicBufferProducer::exportToParcel(Parcel* parcel) {
status_t res = OK;
res = parcel->writeUint32(USE_BUFFER_QUEUE);
@@ -1050,6 +1072,13 @@ status_t BnGraphicBufferProducer::onTransact(
reply->writeInt32(result);
return NO_ERROR;
}
+ case SET_AUTO_PREROTATION: {
+ CHECK_INTERFACE(IGraphicBuffer, data, reply);
+ bool autoPrerotation = data.readBool();
+ status_t result = setAutoPrerotation(autoPrerotation);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index e6eb327c6f..26b630fec6 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1072,6 +1072,9 @@ int Surface::perform(int operation, va_list args)
case NATIVE_WINDOW_GET_CONSUMER_USAGE64:
res = dispatchGetConsumerUsage64(args);
break;
+ case NATIVE_WINDOW_SET_AUTO_PREROTATION:
+ res = dispatchSetAutoPrerotation(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -1272,6 +1275,11 @@ int Surface::dispatchGetConsumerUsage64(va_list args) {
return getConsumerUsage(usage);
}
+int Surface::dispatchSetAutoPrerotation(va_list args) {
+ bool autoPrerotation = va_arg(args, int);
+ return setAutoPrerotation(autoPrerotation);
+}
+
bool Surface::transformToDisplayInverse() {
return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) ==
NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
@@ -1339,6 +1347,7 @@ int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
mStickyTransform = 0;
+ mAutoPrerotation = false;
if (api == NATIVE_WINDOW_API_CPU) {
mConnectedToCpu = false;
@@ -1941,4 +1950,22 @@ status_t Surface::attachAndQueueBuffer(Surface* surface, sp<GraphicBuffer> buffe
return err;
}
+int Surface::setAutoPrerotation(bool autoPrerotation) {
+ ATRACE_CALL();
+ ALOGV("Surface::setAutoPrerotation (%d)", autoPrerotation);
+ Mutex::Autolock lock(mMutex);
+
+ if (mAutoPrerotation == autoPrerotation) {
+ return OK;
+ }
+
+ status_t err = mGraphicBufferProducer->setAutoPrerotation(autoPrerotation);
+ if (err == NO_ERROR) {
+ mAutoPrerotation = autoPrerotation;
+ }
+ ALOGE_IF(err, "IGraphicBufferProducer::setAutoPrerotation(%d) returned %s", autoPrerotation,
+ strerror(-err));
+ return err;
+}
+
}; // namespace android
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index 690a85f395..205e79c879 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -348,6 +348,14 @@ private:
const uint64_t mUniqueId;
+ // When buffer size is driven by the consumer and mTransformHint specifies
+ // a 90 or 270 degree rotation, this indicates whether the width and height
+ // used by dequeueBuffer will be additionally swapped.
+ bool mAutoPrerotation;
+
+ // mTransformHintInUse is to cache the mTransformHint used by the producer.
+ uint32_t mTransformHintInUse;
+
}; // class BufferQueueCore
} // namespace android
diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h
index d2a47a6aa8..9ad92a6e78 100644
--- a/libs/gui/include/gui/BufferQueueProducer.h
+++ b/libs/gui/include/gui/BufferQueueProducer.h
@@ -190,6 +190,9 @@ public:
// See IGraphicBufferProducer::getConsumerUsage
virtual status_t getConsumerUsage(uint64_t* outUsage) const override;
+ // See IGraphicBufferProducer::setAutoPrerotation
+ virtual status_t setAutoPrerotation(bool autoPrerotation);
+
private:
// This is required by the IBinder::DeathRecipient interface
virtual void binderDied(const wp<IBinder>& who);
diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
index 3dde8c8c80..986adae864 100644
--- a/libs/gui/include/gui/IGraphicBufferProducer.h
+++ b/libs/gui/include/gui/IGraphicBufferProducer.h
@@ -629,6 +629,14 @@ public:
// NATIVE_WINDOW_CONSUMER_USAGE_BITS attribute.
virtual status_t getConsumerUsage(uint64_t* outUsage) const = 0;
+ // Enable/disable the auto prerotation at buffer allocation when the buffer
+ // size is driven by the consumer.
+ //
+ // When buffer size is driven by the consumer and the transform hint
+ // specifies a 90 or 270 degree rotation, if auto prerotation is enabled,
+ // the width and height used for dequeueBuffer will be additionally swapped.
+ virtual status_t setAutoPrerotation(bool autoPrerotation);
+
// Static method exports any IGraphicBufferProducer object to a parcel. It
// handles null producer as well.
static status_t exportToParcel(const sp<IGraphicBufferProducer>& producer,
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 0c471bb701..da0282c02e 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -230,6 +230,7 @@ private:
int dispatchGetWideColorSupport(va_list args);
int dispatchGetHdrSupport(va_list args);
int dispatchGetConsumerUsage64(va_list args);
+ int dispatchSetAutoPrerotation(va_list args);
bool transformToDisplayInverse();
protected:
@@ -265,6 +266,7 @@ public:
virtual int setAsyncMode(bool async);
virtual int setSharedBufferMode(bool sharedBufferMode);
virtual int setAutoRefresh(bool autoRefresh);
+ virtual int setAutoPrerotation(bool autoPrerotation);
virtual int setBuffersDimensions(uint32_t width, uint32_t height);
virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
virtual int unlockAndPost();
@@ -433,6 +435,7 @@ protected:
// Caches the values that have been passed to the producer.
bool mSharedBufferMode;
bool mAutoRefresh;
+ bool mAutoPrerotation;
// If in shared buffer mode and auto refresh is enabled, store the shared
// buffer slot and return it for all calls to queue/dequeue without going
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index d3708586f5..7718bc1b8e 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -1746,4 +1746,74 @@ TEST_F(GetFrameTimestampsTest, PresentUnsupportedNoSync) {
EXPECT_EQ(-1, outDisplayPresentTime);
}
+TEST_F(SurfaceTest, DequeueWithConsumerDrivenSize) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ sp<DummyConsumer> dummyConsumer(new DummyConsumer);
+ consumer->consumerConnect(dummyConsumer, false);
+ consumer->setDefaultBufferSize(10, 10);
+
+ sp<Surface> surface = new Surface(producer);
+ sp<ANativeWindow> window(surface);
+ native_window_api_connect(window.get(), NATIVE_WINDOW_API_CPU);
+ native_window_set_buffers_dimensions(window.get(), 0, 0);
+
+ int fence;
+ ANativeWindowBuffer* buffer;
+
+ // Buffer size is driven by the consumer
+ ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fence));
+ EXPECT_EQ(10, buffer->width);
+ EXPECT_EQ(10, buffer->height);
+ ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fence));
+
+ // Buffer size is driven by the consumer
+ consumer->setDefaultBufferSize(10, 20);
+ ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fence));
+ EXPECT_EQ(10, buffer->width);
+ EXPECT_EQ(20, buffer->height);
+ ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fence));
+
+ // Transform hint isn't synced to producer before queueBuffer or connect
+ consumer->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_270);
+ ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fence));
+ EXPECT_EQ(10, buffer->width);
+ EXPECT_EQ(20, buffer->height);
+ ASSERT_EQ(NO_ERROR, window->queueBuffer(window.get(), buffer, fence));
+
+ // Transform hint is synced to producer but no auto prerotation
+ consumer->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_270);
+ ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fence));
+ EXPECT_EQ(10, buffer->width);
+ EXPECT_EQ(20, buffer->height);
+ ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fence));
+
+ // Prerotation is driven by the consumer with the transform hint used by producer
+ native_window_set_auto_prerotation(window.get(), true);
+ ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fence));
+ EXPECT_EQ(20, buffer->width);
+ EXPECT_EQ(10, buffer->height);
+ ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fence));
+
+ // Turn off auto prerotaton
+ native_window_set_auto_prerotation(window.get(), false);
+ ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fence));
+ EXPECT_EQ(10, buffer->width);
+ EXPECT_EQ(20, buffer->height);
+ ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fence));
+
+ // Test auto prerotation bit is disabled after disconnect
+ native_window_set_auto_prerotation(window.get(), true);
+ native_window_api_disconnect(window.get(), NATIVE_WINDOW_API_CPU);
+ native_window_api_connect(window.get(), NATIVE_WINDOW_API_CPU);
+ consumer->setTransformHint(NATIVE_WINDOW_TRANSFORM_ROT_270);
+ native_window_set_buffers_dimensions(window.get(), 0, 0);
+ ASSERT_EQ(NO_ERROR, window->dequeueBuffer(window.get(), &buffer, &fence));
+ EXPECT_EQ(10, buffer->width);
+ EXPECT_EQ(20, buffer->height);
+ ASSERT_EQ(NO_ERROR, window->cancelBuffer(window.get(), buffer, fence));
+}
+
} // namespace android
diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp
index 8435dac636..1751443419 100644
--- a/libs/nativewindow/ANativeWindow.cpp
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -262,3 +262,7 @@ int ANativeWindow_setSharedBufferMode(ANativeWindow* window, bool sharedBufferMo
int ANativeWindow_setAutoRefresh(ANativeWindow* window, bool autoRefresh) {
return native_window_set_auto_refresh(window, autoRefresh);
}
+
+int ANativeWindow_setAutoPrerotation(ANativeWindow* window, bool autoPrerotation) {
+ return native_window_set_auto_prerotation(window, autoPrerotation);
+}
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 61590e0196..8cbf0a4244 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -203,41 +203,42 @@ enum {
*/
enum {
// clang-format off
- NATIVE_WINDOW_SET_USAGE = 0, /* deprecated */
- NATIVE_WINDOW_CONNECT = 1, /* deprecated */
- NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */
- NATIVE_WINDOW_SET_CROP = 3, /* private */
- NATIVE_WINDOW_SET_BUFFER_COUNT = 4,
- NATIVE_WINDOW_SET_BUFFERS_GEOMETRY = 5, /* deprecated */
- NATIVE_WINDOW_SET_BUFFERS_TRANSFORM = 6,
- NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP = 7,
- NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS = 8,
- NATIVE_WINDOW_SET_BUFFERS_FORMAT = 9,
- NATIVE_WINDOW_SET_SCALING_MODE = 10, /* private */
- NATIVE_WINDOW_LOCK = 11, /* private */
- NATIVE_WINDOW_UNLOCK_AND_POST = 12, /* private */
- NATIVE_WINDOW_API_CONNECT = 13, /* private */
- NATIVE_WINDOW_API_DISCONNECT = 14, /* private */
- NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS = 15, /* private */
- NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* deprecated, unimplemented */
- NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17, /* private */
- NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18,
- NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19,
- NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */
- NATIVE_WINDOW_SET_SHARED_BUFFER_MODE = 21,
- NATIVE_WINDOW_SET_AUTO_REFRESH = 22,
- NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION = 23,
- NATIVE_WINDOW_GET_NEXT_FRAME_ID = 24,
- NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS = 25,
- NATIVE_WINDOW_GET_COMPOSITOR_TIMING = 26,
- NATIVE_WINDOW_GET_FRAME_TIMESTAMPS = 27,
- NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28,
- NATIVE_WINDOW_GET_HDR_SUPPORT = 29,
- NATIVE_WINDOW_SET_USAGE64 = 30,
- NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31,
- NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32,
- NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33,
+ NATIVE_WINDOW_SET_USAGE = 0, /* deprecated */
+ NATIVE_WINDOW_CONNECT = 1, /* deprecated */
+ NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */
+ NATIVE_WINDOW_SET_CROP = 3, /* private */
+ NATIVE_WINDOW_SET_BUFFER_COUNT = 4,
+ NATIVE_WINDOW_SET_BUFFERS_GEOMETRY = 5, /* deprecated */
+ NATIVE_WINDOW_SET_BUFFERS_TRANSFORM = 6,
+ NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP = 7,
+ NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS = 8,
+ NATIVE_WINDOW_SET_BUFFERS_FORMAT = 9,
+ NATIVE_WINDOW_SET_SCALING_MODE = 10, /* private */
+ NATIVE_WINDOW_LOCK = 11, /* private */
+ NATIVE_WINDOW_UNLOCK_AND_POST = 12, /* private */
+ NATIVE_WINDOW_API_CONNECT = 13, /* private */
+ NATIVE_WINDOW_API_DISCONNECT = 14, /* private */
+ NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS = 15, /* private */
+ NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* deprecated, unimplemented */
+ NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17, /* private */
+ NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18,
+ NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19,
+ NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */
+ NATIVE_WINDOW_SET_SHARED_BUFFER_MODE = 21,
+ NATIVE_WINDOW_SET_AUTO_REFRESH = 22,
+ NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION = 23,
+ NATIVE_WINDOW_GET_NEXT_FRAME_ID = 24,
+ NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS = 25,
+ NATIVE_WINDOW_GET_COMPOSITOR_TIMING = 26,
+ NATIVE_WINDOW_GET_FRAME_TIMESTAMPS = 27,
+ NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28,
+ NATIVE_WINDOW_GET_HDR_SUPPORT = 29,
+ NATIVE_WINDOW_SET_USAGE64 = 30,
+ NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31,
+ NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32,
+ NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33,
NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA = 34,
+ NATIVE_WINDOW_SET_AUTO_PREROTATION = 35,
// clang-format on
};
@@ -985,4 +986,18 @@ static inline int native_window_get_consumer_usage(struct ANativeWindow* window,
return window->perform(window, NATIVE_WINDOW_GET_CONSUMER_USAGE64, outUsage);
}
+/*
+ * native_window_set_auto_prerotation(..., autoPrerotation)
+ * Enable/disable the auto prerotation at buffer allocation when the buffer size
+ * is driven by the consumer.
+ *
+ * When buffer size is driven by the consumer and the transform hint specifies
+ * a 90 or 270 degree rotation, if auto prerotation is enabled, the width and
+ * height used for dequeueBuffer will be additionally swapped.
+ */
+static inline int native_window_set_auto_prerotation(struct ANativeWindow* window,
+ bool autoPrerotation) {
+ return window->perform(window, NATIVE_WINDOW_SET_AUTO_PREROTATION, autoPrerotation);
+}
+
__END_DECLS
diff --git a/libs/nativewindow/include/vndk/window.h b/libs/nativewindow/include/vndk/window.h
index 995ba44d20..500052c936 100644
--- a/libs/nativewindow/include/vndk/window.h
+++ b/libs/nativewindow/include/vndk/window.h
@@ -316,6 +316,15 @@ int ANativeWindow_setSharedBufferMode(ANativeWindow* window, bool sharedBufferMo
*/
int ANativeWindow_setAutoRefresh(ANativeWindow* window, bool autoRefresh);
+/*
+ * Enable/disable the auto prerotation at buffer allocation when the buffer size
+ * is driven by the consumer.
+ *
+ * When buffer size is driven by the consumer and the transform hint specifies
+ * a 90 or 270 degree rotation, if auto prerotation is enabled, the width and
+ * height used for dequeueBuffer will be additionally swapped.
+ */
+int ANativeWindow_setAutoPrerotation(ANativeWindow* window, bool autoPrerotation);
/*****************************************************************************/
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
index bad8b11540..119a07dad7 100644
--- a/libs/nativewindow/libnativewindow.map.txt
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -28,6 +28,7 @@ LIBNATIVEWINDOW {
ANativeWindow_queryf; # vndk
ANativeWindow_queueBuffer; # vndk
ANativeWindow_release;
+ ANativeWindow_setAutoPrerotation; # vndk
ANativeWindow_setAutoRefresh; # vndk
ANativeWindow_setBufferCount; # vndk
ANativeWindow_setBuffersDataSpace; # introduced=28
diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index c60421b538..7a959f7b19 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -154,6 +154,10 @@ status_t MonitoredProducer::getConsumerUsage(uint64_t* outUsage) const {
return mProducer->getConsumerUsage(outUsage);
}
+status_t MonitoredProducer::setAutoPrerotation(bool autoPrerotation) {
+ return mProducer->setAutoPrerotation(autoPrerotation);
+}
+
IBinder* MonitoredProducer::onAsBinder() {
return this;
}
diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h
index d346f821d3..788919b3da 100644
--- a/services/surfaceflinger/MonitoredProducer.h
+++ b/services/surfaceflinger/MonitoredProducer.h
@@ -70,6 +70,7 @@ public:
virtual void getFrameTimestamps(FrameEventHistoryDelta *outDelta) override;
virtual status_t getUniqueId(uint64_t* outId) const override;
virtual status_t getConsumerUsage(uint64_t* outUsage) const override;
+ virtual status_t setAutoPrerotation(bool autoPrerotation) override;
// The Layer which created this producer, and on which queued Buffer's will be displayed.
sp<Layer> getLayer() const;