Merge changes I25ddd986,I3cc43b2b
* changes:
BlastBufferQueue: Add support for auto refresh
BlastBufferQueue: Add buffer rejection
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index ac1c736..e6aa02a 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -111,8 +111,8 @@
int width, int height, bool enableTripleBuffering)
: mName(name),
mSurfaceControl(surface),
- mWidth(width),
- mHeight(height),
+ mSize(width, height),
+ mRequestedSize(mSize),
mNextTransaction(nullptr) {
BufferQueue::createBufferQueue(&mProducer, &mConsumer);
// since the adapter is in the client process, set dequeue timeout
@@ -130,7 +130,7 @@
mBufferItemConsumer->setName(String8(consumerName.c_str()));
mBufferItemConsumer->setFrameAvailableListener(this);
mBufferItemConsumer->setBufferFreedListener(this);
- mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
+ mBufferItemConsumer->setDefaultBufferSize(mSize.width, mSize.height);
mBufferItemConsumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888);
mTransformHint = mSurfaceControl->getTransformHint();
@@ -146,10 +146,10 @@
std::unique_lock _lock{mMutex};
mSurfaceControl = surface;
- if (mWidth != width || mHeight != height) {
- mWidth = width;
- mHeight = height;
- mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
+ ui::Size newSize(width, height);
+ if (mRequestedSize != newSize) {
+ mRequestedSize.set(newSize);
+ mBufferItemConsumer->setDefaultBufferSize(mRequestedSize.width, mRequestedSize.height);
}
}
@@ -218,6 +218,7 @@
// number of buffers.
if (mNumFrameAvailable == 0 || maxBuffersAcquired()) {
BQA_LOGV("processNextBufferLocked waiting for frame available or callback");
+ mCallbackCV.notify_all();
return;
}
@@ -252,10 +253,13 @@
}
if (rejectBuffer(bufferItem)) {
- BQA_LOGE("rejecting buffer:configured size=%dx%d, buffer{size=%dx%d transform=%d}", mWidth,
- mHeight, buffer->getWidth(), buffer->getHeight(), bufferItem.mTransform);
- // TODO(b/168917217) temporarily don't reject buffers until we can synchronize buffer size
- // changes from ViewRootImpl.
+ BQA_LOGE("rejecting buffer:active_size=%dx%d, requested_size=%dx%d"
+ "buffer{size=%dx%d transform=%d}",
+ mSize.width, mSize.height, mRequestedSize.width, mRequestedSize.height,
+ buffer->getWidth(), buffer->getHeight(), bufferItem.mTransform);
+ mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
+ processNextBufferLocked(useNextTransaction);
+ return;
}
mNumAcquired++;
@@ -278,26 +282,31 @@
t->addTransactionCompletedCallback(transactionCallbackThunk, static_cast<void*>(this));
t->setFrame(mSurfaceControl,
- {0, 0, static_cast<int32_t>(mWidth), static_cast<int32_t>(mHeight)});
+ {0, 0, static_cast<int32_t>(mSize.width), static_cast<int32_t>(mSize.height)});
t->setCrop(mSurfaceControl, computeCrop(bufferItem));
t->setTransform(mSurfaceControl, bufferItem.mTransform);
t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse);
t->setDesiredPresentTime(bufferItem.mTimestamp);
t->setFrameNumber(mSurfaceControl, bufferItem.mFrameNumber);
+ if (mAutoRefresh != bufferItem.mAutoRefresh) {
+ t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh);
+ mAutoRefresh = bufferItem.mAutoRefresh;
+ }
+
if (applyTransaction) {
t->apply();
}
BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64
" applyTransaction=%s mTimestamp=%" PRId64,
- mWidth, mHeight, bufferItem.mFrameNumber, toString(applyTransaction),
+ mSize.width, mSize.height, bufferItem.mFrameNumber, toString(applyTransaction),
bufferItem.mTimestamp);
}
Rect BLASTBufferQueue::computeCrop(const BufferItem& item) {
if (item.mScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) {
- return GLConsumer::scaleDownCrop(item.mCrop, mWidth, mHeight);
+ return GLConsumer::scaleDownCrop(item.mCrop, mSize.width, mSize.height);
}
return item.mCrop;
}
@@ -332,8 +341,9 @@
mNextTransaction = t;
}
-bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) const {
+bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) {
if (item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) {
+ mSize = mRequestedSize;
// Only reject buffers if scaling mode is freeze.
return false;
}
@@ -345,9 +355,14 @@
if (item.mTransform & ui::Transform::ROT_90) {
std::swap(bufWidth, bufHeight);
}
+ ui::Size bufferSize(bufWidth, bufHeight);
+ if (mRequestedSize != mSize && mRequestedSize == bufferSize) {
+ mSize = mRequestedSize;
+ return false;
+ }
// reject buffers if the buffer size doesn't match.
- return bufWidth != mWidth || bufHeight != mHeight;
+ return mSize != bufferSize;
}
// Check if we have acquired the maximum number of buffers.
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 90999fa..7d2c7b8 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -61,7 +61,9 @@
frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
shouldBeSeamless(true),
fixedTransformHint(ui::Transform::ROT_INVALID),
- frameNumber(0) {
+ frameNumber(0),
+ frameTimelineVsyncId(ISurfaceComposer::INVALID_VSYNC_ID),
+ autoRefresh(false) {
matrix.dsdx = matrix.dtdy = 1.0f;
matrix.dsdy = matrix.dtdx = 0.0f;
hdrMetadata.validTypes = 0;
@@ -149,6 +151,7 @@
SAFE_PARCEL(output.writeUint32, fixedTransformHint);
SAFE_PARCEL(output.writeUint64, frameNumber);
SAFE_PARCEL(output.writeInt64, frameTimelineVsyncId);
+ SAFE_PARCEL(output.writeBool, autoRefresh);
SAFE_PARCEL(output.writeUint32, blurRegions.size());
for (auto region : blurRegions) {
@@ -269,6 +272,7 @@
fixedTransformHint = static_cast<ui::Transform::RotationFlags>(tmpUint32);
SAFE_PARCEL(input.readUint64, &frameNumber);
SAFE_PARCEL(input.readInt64, &frameTimelineVsyncId);
+ SAFE_PARCEL(input.readBool, &autoRefresh);
uint32_t numRegions = 0;
SAFE_PARCEL(input.readUint32, &numRegions);
@@ -534,6 +538,20 @@
what |= eFrameNumberChanged;
frameNumber = other.frameNumber;
}
+ if (other.what & eFrameTimelineVsyncChanged) {
+ // When merging vsync Ids we take the oldest valid one
+ if (frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID &&
+ other.frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID) {
+ frameTimelineVsyncId = std::max(frameTimelineVsyncId, other.frameTimelineVsyncId);
+ } else if (frameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID) {
+ frameTimelineVsyncId = other.frameTimelineVsyncId;
+ }
+ what |= eFrameTimelineVsyncChanged;
+ }
+ if (other.what & eAutoRefreshChanged) {
+ what |= eAutoRefreshChanged;
+ autoRefresh = other.autoRefresh;
+ }
if ((other.what & what) != other.what) {
ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
"other.what=0x%" PRIu64 " what=0x%" PRIu64,
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index a822598..47a08ab 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1527,6 +1527,19 @@
return *this;
}
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAutoRefresh(
+ const sp<SurfaceControl>& sc, bool autoRefresh) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+
+ s->what |= layer_state_t::eAutoRefreshChanged;
+ s->autoRefresh = autoRefresh;
+ return *this;
+}
+
// ---------------------------------------------------------------------------
DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 7741d8c..9fb7d6f 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -100,7 +100,7 @@
void processNextBufferLocked(bool useNextTransaction) REQUIRES(mMutex);
Rect computeCrop(const BufferItem& item) REQUIRES(mMutex);
// Return true if we need to reject the buffer based on the scaling mode and the buffer size.
- bool rejectBuffer(const BufferItem& item) const REQUIRES(mMutex);
+ bool rejectBuffer(const BufferItem& item) REQUIRES(mMutex);
bool maxBuffersAcquired() const REQUIRES(mMutex);
std::string mName;
@@ -126,8 +126,8 @@
// is ready to be presented.
PendingReleaseItem mPendingReleaseItem GUARDED_BY(mMutex);
- uint32_t mWidth GUARDED_BY(mMutex);
- uint32_t mHeight GUARDED_BY(mMutex);
+ ui::Size mSize GUARDED_BY(mMutex);
+ ui::Size mRequestedSize GUARDED_BY(mMutex);
uint32_t mTransformHint GUARDED_BY(mMutex);
@@ -139,6 +139,10 @@
// If set to true, the next queue buffer will wait until the shadow queue has been processed by
// the adapter.
bool mFlushShadowQueue = false;
+ // Last requested auto refresh state set by the producer. The state indicates that the consumer
+ // should acquire the next frame as soon as it can and not wait for a frame to become available.
+ // This is only relevant for shared buffer mode.
+ bool mAutoRefresh GUARDED_BY(mMutex) = false;
};
} // namespace android
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index d9f2806..f1c5d67 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -130,6 +130,7 @@
eFrameNumberChanged = 0x400'00000000,
eFrameTimelineVsyncChanged = 0x800'00000000,
eBlurRegionsChanged = 0x1000'00000000,
+ eAutoRefreshChanged = 0x2000'00000000,
};
layer_state_t();
@@ -234,6 +235,11 @@
uint64_t frameNumber;
int64_t frameTimelineVsyncId;
+
+ // Indicates that the consumer should acquire the next frame as soon as it
+ // can and not wait for a frame to become available. This is only relevant
+ // in shared buffer mode.
+ bool autoRefresh;
};
struct ComposerState {
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 6289c6a..2eb97f2 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -541,6 +541,11 @@
Transaction& setFrameTimelineVsync(const sp<SurfaceControl>& sc,
int64_t frameTimelineVsyncId);
+ // Indicates that the consumer should acquire the next frame as soon as it
+ // can and not wait for a frame to become available. This is only relevant
+ // in shared buffer mode.
+ Transaction& setAutoRefresh(const sp<SurfaceControl>& sc, bool autoRefresh);
+
status_t setDisplaySurface(const sp<IBinder>& token,
const sp<IGraphicBufferProducer>& bufferProducer);
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index f3559fa..4282ef9 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -55,9 +55,9 @@
mBlastBufferQueueAdapter->setNextTransaction(next);
}
- int getWidth() { return mBlastBufferQueueAdapter->mWidth; }
+ int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
- int getHeight() { return mBlastBufferQueueAdapter->mHeight; }
+ int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
Transaction* getNextTransaction() { return mBlastBufferQueueAdapter->mNextTransaction; }
@@ -250,8 +250,15 @@
PIXEL_FORMAT_RGBA_8888);
adapter.update(updateSurface, mDisplayWidth / 2, mDisplayHeight / 2);
ASSERT_EQ(updateSurface, adapter.getSurfaceControl());
- ASSERT_EQ(mDisplayWidth / 2, adapter.getWidth());
- ASSERT_EQ(mDisplayHeight / 2, adapter.getHeight());
+ sp<IGraphicBufferProducer> igbProducer;
+ setUpProducer(adapter, igbProducer);
+
+ int32_t width;
+ igbProducer->query(NATIVE_WINDOW_WIDTH, &width);
+ ASSERT_EQ(mDisplayWidth / 2, width);
+ int32_t height;
+ igbProducer->query(NATIVE_WINDOW_HEIGHT, &height);
+ ASSERT_EQ(mDisplayHeight / 2, height);
}
TEST_F(BLASTBufferQueueTest, SetNextTransaction) {
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index deaf846..63dfe5f 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -178,13 +178,17 @@
/// the mStateLock.
ui::Transform::RotationFlags mTransformHint = ui::Transform::ROT_0;
+ bool getAutoRefresh() const { return mAutoRefresh; }
+ bool getSidebandStreamChanged() const { return mSidebandStreamChanged; }
+
+ std::atomic<bool> mAutoRefresh{false};
+ std::atomic<bool> mSidebandStreamChanged{false};
+
private:
virtual bool fenceHasSignaled() const = 0;
virtual bool framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const = 0;
virtual uint64_t getFrameNumber(nsecs_t expectedPresentTime) const = 0;
- virtual bool getAutoRefresh() const = 0;
- virtual bool getSidebandStreamChanged() const = 0;
// Latch sideband stream and returns true if the dirty region should be updated.
virtual bool latchSidebandStream(bool& recomputeVisibleRegions) = 0;
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 71b05fd..dc99986 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -196,14 +196,6 @@
return frameNumber;
}
-bool BufferQueueLayer::getAutoRefresh() const {
- return mAutoRefresh;
-}
-
-bool BufferQueueLayer::getSidebandStreamChanged() const {
- return mSidebandStreamChanged;
-}
-
bool BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
// We need to update the sideband stream if the layer has both a buffer and a sideband stream.
const bool updateSidebandStream = hasFrameUpdate() && mSidebandStream.get();
@@ -265,8 +257,10 @@
const uint64_t maxFrameNumberToAcquire =
std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber);
- status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh,
+ bool autoRefresh;
+ status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &autoRefresh,
&queuedBuffer, maxFrameNumberToAcquire);
+ mAutoRefresh = autoRefresh;
if (updateResult == BufferQueue::PRESENT_LATER) {
// Producer doesn't want buffer to be displayed yet. Signal a
// layer update so we check again at the next opportunity.
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index fb8a0c2..b45900e 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -90,9 +90,6 @@
private:
uint64_t getFrameNumber(nsecs_t expectedPresentTime) const override;
- bool getAutoRefresh() const override;
- bool getSidebandStreamChanged() const override;
-
bool latchSidebandStream(bool& recomputeVisibleRegions) override;
void setTransformHint(ui::Transform::RotationFlags displayTransformHint) override;
@@ -140,11 +137,8 @@
std::vector<BufferData> mQueueItems;
std::atomic<uint64_t> mLastFrameNumberReceived{0};
- bool mAutoRefresh{false};
-
// thread-safe
std::atomic<int32_t> mQueuedFrames{0};
- std::atomic<bool> mSidebandStreamChanged{false};
sp<ContentsChangedListener> mContentsChangedListener;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index a64b243..963e541 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -482,13 +482,10 @@
return mCurrentState.frameNumber;
}
-bool BufferStateLayer::getAutoRefresh() const {
- // TODO(marissaw): support shared buffer mode
- return false;
-}
-
-bool BufferStateLayer::getSidebandStreamChanged() const {
- return mSidebandStreamChanged.load();
+void BufferStateLayer::setAutoRefresh(bool autoRefresh) {
+ if (!mAutoRefresh.exchange(autoRefresh)) {
+ mFlinger->signalLayerUpdate();
+ }
}
bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
@@ -526,37 +523,12 @@
return NO_ERROR;
}
- const int32_t layerId = getSequence();
-
- // Reject if the layer is invalid
- uint32_t bufferWidth = s.buffer->width;
- uint32_t bufferHeight = s.buffer->height;
-
- if (s.transform & ui::Transform::ROT_90) {
- std::swap(bufferWidth, bufferHeight);
- }
-
- if (s.transformToDisplayInverse) {
- uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
- if (invTransform & ui::Transform::ROT_90) {
- std::swap(bufferWidth, bufferHeight);
- }
- }
-
- if (getEffectiveScalingMode() == NATIVE_WINDOW_SCALING_MODE_FREEZE &&
- (s.active.w != bufferWidth || s.active.h != bufferHeight)) {
- ALOGE("[%s] rejecting buffer: "
- "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}",
- getDebugName(), bufferWidth, bufferHeight, s.active.w, s.active.h);
- mFlinger->mTimeStats->removeTimeRecord(layerId, mDrawingState.frameNumber);
- return BAD_VALUE;
- }
-
for (auto& handle : mDrawingState.callbackHandles) {
handle->latchTime = latchTime;
handle->frameNumber = mDrawingState.frameNumber;
}
+ const int32_t layerId = getSequence();
mFlinger->mTimeStats->setAcquireFence(layerId, mDrawingState.frameNumber,
std::make_shared<FenceTime>(mDrawingState.acquireFence));
mFlinger->mTimeStats->setLatchTime(layerId, mDrawingState.frameNumber, latchTime);
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 104a13b..42be62a 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -100,6 +100,7 @@
Rect getBufferSize(const State& s) const override;
FloatRect computeSourceBounds(const FloatRect& parentBounds) const override;
Layer::RoundedCornerState getRoundedCornerState() const override;
+ void setAutoRefresh(bool autoRefresh) override;
// -----------------------------------------------------------------------
@@ -123,9 +124,6 @@
uint64_t getFrameNumber(nsecs_t expectedPresentTime) const override;
- bool getAutoRefresh() const override;
- bool getSidebandStreamChanged() const override;
-
bool latchSidebandStream(bool& recomputeVisibleRegions) override;
bool hasFrameUpdate() const override;
@@ -149,8 +147,6 @@
std::unique_ptr<renderengine::Image> mTextureImage;
- std::atomic<bool> mSidebandStreamChanged{false};
-
mutable uint64_t mFrameNumber{0};
uint64_t mFrameCounter{0};
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 1a784aa..8d67ce5 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -444,6 +444,7 @@
virtual bool setColorSpaceAgnostic(const bool agnostic);
virtual bool setFrameRateSelectionPriority(int32_t priority);
virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint);
+ virtual void setAutoRefresh(bool /* autoRefresh */) {}
// If the variable is not set on the layer, it traverses up the tree to inherit the frame
// rate priority from its parent.
virtual int32_t getFrameRateSelectionPriority() const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cc1c5c5..604a83a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3796,6 +3796,9 @@
flags |= eTraversalNeeded | eTransformHintUpdateNeeded;
}
}
+ if (what & layer_state_t::eAutoRefreshChanged) {
+ layer->setAutoRefresh(s.autoRefresh);
+ }
// This has to happen after we reparent children because when we reparent to null we remove
// child layers from current state and remove its relative z. If the children are reparented in
// the same transaction, then we have to make sure we reparent the children first so we do not