summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;