Skip to content

Commit dfda84b

Browse files
author
Andrew Wolfers
committed
Set GRALLOC_USAGE_CURSOR flag
This change uses the eCursorWindow flag to determine whether the GRALLOC_USAGE_CURSOR flag should be set when a Surface is locked. The Gralloc flag is utilized during buffer allocation to support cursor specific behaviors. Bug: b/383344900 Flag: com.android.graphics.libgui.flags.cursor_plane_compatibility Test: atest SurfaceTest#SurfaceIsForCursor (cherry picked from https://android-review.googlesource.com/q/commit:dafb9f9e119ecbb486d7548fe6614559b853709c) Change-Id: I997578ce8decb0121acffe3fc6445c981d64fa22
1 parent 1b7198f commit dfda84b

File tree

5 files changed

+53
-3
lines changed

5 files changed

+53
-3
lines changed

libs/gui/Surface.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd,
12531253
// Surface::queueBuffer
12541254
// -> IConsumerListener::onFrameAvailable callback triggers automatically
12551255
// -> implementation calls IGraphicBufferConsumer::acquire/release immediately
1256-
// -> SurfaceListener::onBufferRelesed callback triggers automatically
1256+
// -> SurfaceListener::onBufferReleased callback triggers automatically
12571257
// -> implementation calls Surface::dequeueBuffer
12581258
status_t err = mGraphicBufferProducer->queueBuffer(slot, input, &output);
12591259
{
@@ -2724,7 +2724,8 @@ status_t Surface::lock(
27242724
return err;
27252725
}
27262726
// we're intending to do software rendering from this point
2727-
setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
2727+
setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
2728+
(mIsForCursor ? GRALLOC_USAGE_CURSOR : 0));
27282729
}
27292730

27302731
ANativeWindowBuffer* out;
@@ -2984,4 +2985,17 @@ const char* Surface::getDebugName() {
29842985
return mName.c_str();
29852986
}
29862987

2988+
bool Surface::IsCursorPlaneCompatibilitySupported() {
2989+
if (com::android::graphics::libgui::flags::cursor_plane_compatibility()) {
2990+
const AHardwareBuffer_Desc testDesc{.width = 64,
2991+
.height = 64,
2992+
.layers = 1,
2993+
.format = AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM,
2994+
.usage = GRALLOC_USAGE_CURSOR};
2995+
return AHardwareBuffer_isSupported(&testDesc);
2996+
}
2997+
2998+
return false;
2999+
}
3000+
29873001
}; // namespace android

libs/gui/SurfaceControl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ sp<Surface> SurfaceControl::generateSurfaceLocked()
147147
// This surface is always consumed by SurfaceFlinger, so the
148148
// producerControlledByApp value doesn't matter; using false.
149149
mSurfaceData = mBbq->getSurface(true);
150+
if (Surface::IsCursorPlaneCompatibilitySupported()) {
151+
mSurfaceData->setIsForCursor(flags & ISurfaceComposerClient::eCursorWindow);
152+
}
150153

151154
return mSurfaceData;
152155
}

libs/gui/include/gui/Surface.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ class Surface
263263
virtual status_t setFrameRate(float frameRate, int8_t compatibility,
264264
int8_t changeFrameRateStrategy);
265265
virtual status_t setFrameTimelineInfo(uint64_t frameNumber, const FrameTimelineInfo& info);
266+
// Returns whether this surface holds the mouse cursor.
267+
bool isForCursor() const { return mIsForCursor; }
268+
// Sets whether this surface holds the mouse cursor.
269+
void setIsForCursor(bool isForCursor) { mIsForCursor = isForCursor; }
270+
271+
static bool IsCursorPlaneCompatibilitySupported();
266272

267273
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE)
268274
/**
@@ -598,7 +604,7 @@ class Surface
598604
HdrMetadata mHdrMetadata;
599605

600606
// mHdrMetadataIsSet is a bitfield to track which HDR metadata has been set.
601-
// Prevent Surface from resetting HDR metadata that was set on a bufer when
607+
// Prevent Surface from resetting HDR metadata that was set on a buffer when
602608
// HDR metadata is not set on this Surface.
603609
uint32_t mHdrMetadataIsSet{0};
604610

@@ -753,6 +759,11 @@ class Surface
753759

754760
// Buffers that are successfully dequeued/attached and handed to clients
755761
std::unordered_set<int> mDequeuedSlots;
762+
763+
// Indicates whether this surface holds the mouse cursor, and subsequently determines whether
764+
// the GRALLOC_USAGE_CURSOR usage flag should be set on the buffer created when this surface is
765+
// locked.
766+
bool mIsForCursor = false;
756767
};
757768

758769
} // namespace android

libs/gui/tests/Surface_test.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,27 @@ TEST_F(SurfaceTest, TestGetLastDequeueStartTime) {
598598
ASSERT_GE(after, lastDequeueTime);
599599
}
600600

601+
TEST_F(SurfaceTest, SurfaceIsForCursor) {
602+
sp<SurfaceControl> control;
603+
ASSERT_EQ(NO_ERROR,
604+
mComposerClient->createSurfaceChecked(String8("Test Surface"), 32, 32,
605+
PIXEL_FORMAT_BGRA_8888, &control, 0));
606+
sp<Surface> surface = control->getSurface();
607+
sp<ANativeWindow> anw(surface);
608+
609+
surface->setIsForCursor(true);
610+
611+
ANativeWindow_Buffer b;
612+
ASSERT_EQ(NO_ERROR, surface->lock(&b, nullptr));
613+
ASSERT_EQ(NO_ERROR, surface->unlockAndPost());
614+
615+
int fence;
616+
ANativeWindowBuffer* buffer;
617+
ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buffer, &fence));
618+
619+
EXPECT_TRUE(buffer->usage & GRALLOC_USAGE_CURSOR);
620+
}
621+
601622
class FakeConsumer : public IConsumerListener {
602623
public:
603624
void onFrameAvailable(const BufferItem& /*item*/) override {}

libs/gui/view/Surface.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ Surface Surface::fromSurface(const sp<android::Surface>& surface) {
131131
s.name = String16(surface->getConsumerName());
132132
s.graphicBufferProducer = surface->getIGraphicBufferProducer();
133133
s.surfaceControlHandle = surface->getSurfaceControlHandle();
134+
ALOGW_IF(surface->isForCursor(), "%s: Unexpectedly encountered cursor surface.", __FUNCTION__);
134135
return s;
135136
}
136137

0 commit comments

Comments
 (0)