Loading libs/gui/Surface.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -1253,7 +1253,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd, // Surface::queueBuffer // -> IConsumerListener::onFrameAvailable callback triggers automatically // -> implementation calls IGraphicBufferConsumer::acquire/release immediately // -> SurfaceListener::onBufferRelesed callback triggers automatically // -> SurfaceListener::onBufferReleased callback triggers automatically // -> implementation calls Surface::dequeueBuffer status_t err = mGraphicBufferProducer->queueBuffer(slot, input, &output); { Loading Loading @@ -2724,7 +2724,8 @@ status_t Surface::lock( return err; } // we're intending to do software rendering from this point setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | (mIsForCursor ? GRALLOC_USAGE_CURSOR : 0)); } ANativeWindowBuffer* out; Loading Loading @@ -2984,4 +2985,17 @@ const char* Surface::getDebugName() { return mName.c_str(); } bool Surface::IsCursorPlaneCompatibilitySupported() { if (com::android::graphics::libgui::flags::cursor_plane_compatibility()) { const AHardwareBuffer_Desc testDesc{.width = 64, .height = 64, .layers = 1, .format = AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM, .usage = GRALLOC_USAGE_CURSOR}; return AHardwareBuffer_isSupported(&testDesc); } return false; } }; // namespace android libs/gui/SurfaceControl.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,9 @@ sp<Surface> SurfaceControl::generateSurfaceLocked() // This surface is always consumed by SurfaceFlinger, so the // producerControlledByApp value doesn't matter; using false. mSurfaceData = mBbq->getSurface(true); if (Surface::IsCursorPlaneCompatibilitySupported()) { mSurfaceData->setIsForCursor(flags & ISurfaceComposerClient::eCursorWindow); } return mSurfaceData; } Loading libs/gui/include/gui/Surface.h +12 −1 Original line number Diff line number Diff line Loading @@ -263,6 +263,12 @@ public: virtual status_t setFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy); virtual status_t setFrameTimelineInfo(uint64_t frameNumber, const FrameTimelineInfo& info); // Returns whether this surface holds the mouse cursor. bool isForCursor() const { return mIsForCursor; } // Sets whether this surface holds the mouse cursor. void setIsForCursor(bool isForCursor) { mIsForCursor = isForCursor; } static bool IsCursorPlaneCompatibilitySupported(); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) /** Loading Loading @@ -598,7 +604,7 @@ protected: HdrMetadata mHdrMetadata; // mHdrMetadataIsSet is a bitfield to track which HDR metadata has been set. // Prevent Surface from resetting HDR metadata that was set on a bufer when // Prevent Surface from resetting HDR metadata that was set on a buffer when // HDR metadata is not set on this Surface. uint32_t mHdrMetadataIsSet{0}; Loading Loading @@ -753,6 +759,11 @@ protected: // Buffers that are successfully dequeued/attached and handed to clients std::unordered_set<int> mDequeuedSlots; // Indicates whether this surface holds the mouse cursor, and subsequently determines whether // the GRALLOC_USAGE_CURSOR usage flag should be set on the buffer created when this surface is // locked. bool mIsForCursor = false; }; } // namespace android Loading libs/gui/tests/Surface_test.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -598,6 +598,27 @@ TEST_F(SurfaceTest, TestGetLastDequeueStartTime) { ASSERT_GE(after, lastDequeueTime); } TEST_F(SurfaceTest, SurfaceIsForCursor) { sp<SurfaceControl> control; ASSERT_EQ(NO_ERROR, mComposerClient->createSurfaceChecked(String8("Test Surface"), 32, 32, PIXEL_FORMAT_BGRA_8888, &control, 0)); sp<Surface> surface = control->getSurface(); sp<ANativeWindow> anw(surface); surface->setIsForCursor(true); ANativeWindow_Buffer b; ASSERT_EQ(NO_ERROR, surface->lock(&b, nullptr)); ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); int fence; ANativeWindowBuffer* buffer; ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buffer, &fence)); EXPECT_TRUE(buffer->usage & GRALLOC_USAGE_CURSOR); } class FakeConsumer : public IConsumerListener { public: void onFrameAvailable(const BufferItem& /*item*/) override {} Loading libs/gui/view/Surface.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ Surface Surface::fromSurface(const sp<android::Surface>& surface) { s.name = String16(surface->getConsumerName()); s.graphicBufferProducer = surface->getIGraphicBufferProducer(); s.surfaceControlHandle = surface->getSurfaceControlHandle(); ALOGW_IF(surface->isForCursor(), "%s: Unexpectedly encountered cursor surface.", __FUNCTION__); return s; } Loading Loading
libs/gui/Surface.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -1253,7 +1253,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd, // Surface::queueBuffer // -> IConsumerListener::onFrameAvailable callback triggers automatically // -> implementation calls IGraphicBufferConsumer::acquire/release immediately // -> SurfaceListener::onBufferRelesed callback triggers automatically // -> SurfaceListener::onBufferReleased callback triggers automatically // -> implementation calls Surface::dequeueBuffer status_t err = mGraphicBufferProducer->queueBuffer(slot, input, &output); { Loading Loading @@ -2724,7 +2724,8 @@ status_t Surface::lock( return err; } // we're intending to do software rendering from this point setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | (mIsForCursor ? GRALLOC_USAGE_CURSOR : 0)); } ANativeWindowBuffer* out; Loading Loading @@ -2984,4 +2985,17 @@ const char* Surface::getDebugName() { return mName.c_str(); } bool Surface::IsCursorPlaneCompatibilitySupported() { if (com::android::graphics::libgui::flags::cursor_plane_compatibility()) { const AHardwareBuffer_Desc testDesc{.width = 64, .height = 64, .layers = 1, .format = AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM, .usage = GRALLOC_USAGE_CURSOR}; return AHardwareBuffer_isSupported(&testDesc); } return false; } }; // namespace android
libs/gui/SurfaceControl.cpp +3 −0 Original line number Diff line number Diff line Loading @@ -147,6 +147,9 @@ sp<Surface> SurfaceControl::generateSurfaceLocked() // This surface is always consumed by SurfaceFlinger, so the // producerControlledByApp value doesn't matter; using false. mSurfaceData = mBbq->getSurface(true); if (Surface::IsCursorPlaneCompatibilitySupported()) { mSurfaceData->setIsForCursor(flags & ISurfaceComposerClient::eCursorWindow); } return mSurfaceData; } Loading
libs/gui/include/gui/Surface.h +12 −1 Original line number Diff line number Diff line Loading @@ -263,6 +263,12 @@ public: virtual status_t setFrameRate(float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy); virtual status_t setFrameTimelineInfo(uint64_t frameNumber, const FrameTimelineInfo& info); // Returns whether this surface holds the mouse cursor. bool isForCursor() const { return mIsForCursor; } // Sets whether this surface holds the mouse cursor. void setIsForCursor(bool isForCursor) { mIsForCursor = isForCursor; } static bool IsCursorPlaneCompatibilitySupported(); #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE) /** Loading Loading @@ -598,7 +604,7 @@ protected: HdrMetadata mHdrMetadata; // mHdrMetadataIsSet is a bitfield to track which HDR metadata has been set. // Prevent Surface from resetting HDR metadata that was set on a bufer when // Prevent Surface from resetting HDR metadata that was set on a buffer when // HDR metadata is not set on this Surface. uint32_t mHdrMetadataIsSet{0}; Loading Loading @@ -753,6 +759,11 @@ protected: // Buffers that are successfully dequeued/attached and handed to clients std::unordered_set<int> mDequeuedSlots; // Indicates whether this surface holds the mouse cursor, and subsequently determines whether // the GRALLOC_USAGE_CURSOR usage flag should be set on the buffer created when this surface is // locked. bool mIsForCursor = false; }; } // namespace android Loading
libs/gui/tests/Surface_test.cpp +21 −0 Original line number Diff line number Diff line Loading @@ -598,6 +598,27 @@ TEST_F(SurfaceTest, TestGetLastDequeueStartTime) { ASSERT_GE(after, lastDequeueTime); } TEST_F(SurfaceTest, SurfaceIsForCursor) { sp<SurfaceControl> control; ASSERT_EQ(NO_ERROR, mComposerClient->createSurfaceChecked(String8("Test Surface"), 32, 32, PIXEL_FORMAT_BGRA_8888, &control, 0)); sp<Surface> surface = control->getSurface(); sp<ANativeWindow> anw(surface); surface->setIsForCursor(true); ANativeWindow_Buffer b; ASSERT_EQ(NO_ERROR, surface->lock(&b, nullptr)); ASSERT_EQ(NO_ERROR, surface->unlockAndPost()); int fence; ANativeWindowBuffer* buffer; ASSERT_EQ(NO_ERROR, anw->dequeueBuffer(anw.get(), &buffer, &fence)); EXPECT_TRUE(buffer->usage & GRALLOC_USAGE_CURSOR); } class FakeConsumer : public IConsumerListener { public: void onFrameAvailable(const BufferItem& /*item*/) override {} Loading
libs/gui/view/Surface.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ Surface Surface::fromSurface(const sp<android::Surface>& surface) { s.name = String16(surface->getConsumerName()); s.graphicBufferProducer = surface->getIGraphicBufferProducer(); s.surfaceControlHandle = surface->getSurfaceControlHandle(); ALOGW_IF(surface->isForCursor(), "%s: Unexpectedly encountered cursor surface.", __FUNCTION__); return s; } Loading