From 34fe38b0c7ce6a47eaa2f328865858a2c7dac5e1 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Tue, 22 Mar 2022 15:25:54 -0700 Subject: DO NOT MERGE: SurfaceControl: Ensure unused fields are zeroed Otherwise we could leak uninitialized memory to an untrusted process. Bug: 214999987 Test: Existing tests pass Change-Id: I87993fbb920b3af938a311e6afc15383d571823a (cherry picked from commit c2cf02c17af0d7e5f58b8a17ecb9cfcc91a4d2eb) --- libs/gui/SurfaceControl.cpp | 1 + libs/gui/include/gui/SurfaceControl.h | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 6529a4e51c..f93b799757 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -70,6 +70,7 @@ SurfaceControl::SurfaceControl(const sp& other) { mLayerId = other->mLayerId; mWidth = other->mWidth; mHeight = other->mHeight; + mFormat = other->mFormat; mCreateFlags = other->mCreateFlags; } diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h index 9ee4636ae1..9a423f2453 100644 --- a/libs/gui/include/gui/SurfaceControl.h +++ b/libs/gui/include/gui/SurfaceControl.h @@ -118,12 +118,12 @@ private: mutable sp mSurfaceData; mutable sp mBbq; mutable sp mBbqChild; - int32_t mLayerId; - uint32_t mTransformHint; - uint32_t mWidth; - uint32_t mHeight; - PixelFormat mFormat; - uint32_t mCreateFlags; + int32_t mLayerId = 0; + uint32_t mTransformHint = 0; + uint32_t mWidth = 0; + uint32_t mHeight = 0; + PixelFormat mFormat = PIXEL_FORMAT_NONE; + uint32_t mCreateFlags = 0; }; }; // namespace android -- cgit v1.2.3 From 61a52db9d3a144a8ae4a6a495d61a3b59db80300 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Tue, 22 Mar 2022 15:25:54 -0700 Subject: DO NOT MERGE: SurfaceControl: Ensure unused fields are zeroed Otherwise we could leak uninitialized memory to an untrusted process. Bug: 214999987 Test: Existing tests pass Change-Id: I87993fbb920b3af938a311e6afc15383d571823a (cherry picked from commit c2cf02c17af0d7e5f58b8a17ecb9cfcc91a4d2eb) --- libs/gui/SurfaceControl.cpp | 1 + libs/gui/include/gui/SurfaceControl.h | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 6529a4e51c..f93b799757 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -70,6 +70,7 @@ SurfaceControl::SurfaceControl(const sp& other) { mLayerId = other->mLayerId; mWidth = other->mWidth; mHeight = other->mHeight; + mFormat = other->mFormat; mCreateFlags = other->mCreateFlags; } diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h index 9ee4636ae1..ed14ec6744 100644 --- a/libs/gui/include/gui/SurfaceControl.h +++ b/libs/gui/include/gui/SurfaceControl.h @@ -118,12 +118,13 @@ private: mutable sp mSurfaceData; mutable sp mBbq; mutable sp mBbqChild; - int32_t mLayerId; - uint32_t mTransformHint; - uint32_t mWidth; - uint32_t mHeight; - PixelFormat mFormat; - uint32_t mCreateFlags; + + int32_t mLayerId = 0; + uint32_t mTransformHint = 0; + uint32_t mWidth = 0; + uint32_t mHeight = 0; + PixelFormat mFormat = PIXEL_FORMAT_NONE; + uint32_t mCreateFlags = 0; }; }; // namespace android -- cgit v1.2.3 From a7c45f4f5aa275628c2ad6e72ef12bed84535d0e Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Tue, 22 Mar 2022 15:25:54 -0700 Subject: DO NOT MERGE: SurfaceControl: Ensure unused fields are zeroed Otherwise we could leak uninitialized memory to an untrusted process. Bug: 214999987 Test: Existing tests pass Change-Id: I87993fbb920b3af938a311e6afc15383d571823a (cherry picked from commit c2cf02c17af0d7e5f58b8a17ecb9cfcc91a4d2eb) --- libs/gui/SurfaceControl.cpp | 1 + libs/gui/include/gui/SurfaceControl.h | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 6529a4e51c..f93b799757 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -70,6 +70,7 @@ SurfaceControl::SurfaceControl(const sp& other) { mLayerId = other->mLayerId; mWidth = other->mWidth; mHeight = other->mHeight; + mFormat = other->mFormat; mCreateFlags = other->mCreateFlags; } diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h index 9ee4636ae1..ed14ec6744 100644 --- a/libs/gui/include/gui/SurfaceControl.h +++ b/libs/gui/include/gui/SurfaceControl.h @@ -118,12 +118,13 @@ private: mutable sp mSurfaceData; mutable sp mBbq; mutable sp mBbqChild; - int32_t mLayerId; - uint32_t mTransformHint; - uint32_t mWidth; - uint32_t mHeight; - PixelFormat mFormat; - uint32_t mCreateFlags; + + int32_t mLayerId = 0; + uint32_t mTransformHint = 0; + uint32_t mWidth = 0; + uint32_t mHeight = 0; + PixelFormat mFormat = PIXEL_FORMAT_NONE; + uint32_t mCreateFlags = 0; }; }; // namespace android -- cgit v1.2.3 From 7a8dc174f9841a962fe0585d4adc140bbad1adce Mon Sep 17 00:00:00 2001 From: Huihong Luo Date: Thu, 26 May 2022 11:52:19 -0700 Subject: Skip SOLID_COLOR layers from SF Caching Layers with SOLID_COLOR compostion type may cause fence leaks, and since these layers are not frequently used, skipping them should be ok. Bug: 230073351 Test: manual, examine logs Change-Id: I50c2488c4c5b891bf0415f1d4bd29a6e0c49be5b --- .../include/compositionengine/impl/planner/CachedSet.h | 2 ++ .../include/compositionengine/impl/planner/LayerState.h | 6 ++++++ services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp | 1 + .../surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp | 6 ++++++ .../surfaceflinger/CompositionEngine/src/planner/Flattener.cpp | 7 +++++++ 5 files changed, 22 insertions(+) diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h index 2e7a377feb..e65aa7393c 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h @@ -147,6 +147,8 @@ public: bool hasProtectedLayers() const; + bool hasSolidColorLayers() const; + private: CachedSet() = default; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h index 29d33662ab..5aec7c2e88 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h @@ -248,6 +248,12 @@ public: bool isProtected() const { return getOutputLayer()->getLayerFE().getCompositionState()->hasProtectedContent; } + + bool hasSolidColorCompositionType() const { + return getOutputLayer()->getLayerFE().getCompositionState()->compositionType == + aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR; + } + float getFps() const { return getOutputLayer()->getLayerFE().getCompositionState()->fps; } void dump(std::string& result) const; diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp index 742af58ef5..1bb9d0eb63 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp @@ -377,6 +377,7 @@ void OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t auto requestedCompositionType = outputIndependentState->compositionType; if (requestedCompositionType == Composition::SOLID_COLOR && state.overrideInfo.buffer) { + // this should never happen, as SOLID_COLOR is skipped from caching, b/230073351 requestedCompositionType = Composition::DEVICE; } diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp index d15b0a7646..641b806aec 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp @@ -388,6 +388,12 @@ bool CachedSet::hasProtectedLayers() const { [](const Layer& layer) { return layer.getState()->isProtected(); }); } +bool CachedSet::hasSolidColorLayers() const { + return std::any_of(mLayers.cbegin(), mLayers.cend(), [](const Layer& layer) { + return layer.getState()->hasSolidColorCompositionType(); + }); +} + void CachedSet::dump(std::string& result) const { const auto now = std::chrono::steady_clock::now(); diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp index 250f648f8a..1062b700dd 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp @@ -498,6 +498,13 @@ void Flattener::buildCachedSets(time_point now) { } } + for (const CachedSet& layer : mLayers) { + if (layer.hasSolidColorLayers()) { + ATRACE_NAME("layer->hasSolidColorLayers()"); + return; + } + } + std::vector runs = findCandidateRuns(now); std::optional bestRun = findBestRun(runs); -- cgit v1.2.3 From 3915c1fe6ad6378c432adee2b5b05d1e597e9f4d Mon Sep 17 00:00:00 2001 From: Arthur Hung Date: Tue, 31 May 2022 07:17:17 +0000 Subject: Fix drag surface may stuck in multi displays Check the displayId to prevent the drag state could be reset due to update input windows of another display or event from another display. Test: atest inputflinger_tests Bug: 234405420 Change-Id: I75c7e08594f4dd08b6a0103c2c5a54d8f3e3e09e --- .../inputflinger/dispatcher/InputDispatcher.cpp | 6 ++- .../inputflinger/tests/InputDispatcher_test.cpp | 52 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 4d25c5947b..5e9427ad87 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2507,7 +2507,7 @@ void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) { } void InputDispatcher::addDragEventLocked(const MotionEntry& entry) { - if (!mDragState) { + if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId) { return; } @@ -4765,9 +4765,11 @@ void InputDispatcher::setInputWindowsLocked( // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We // could just clear the state here. - if (mDragState && + if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId && std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) == windowHandles.end()) { + ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str()); + sendDropWindowCommandLocked(nullptr, 0, 0); mDragState.reset(); } } diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp index 91a666c699..df4307101f 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -6407,6 +6407,58 @@ TEST_F(InputDispatcherDragTests, DragAndDropWhenSplitTouch) { mSecondWindow->consumeMotionMove(); } +TEST_F(InputDispatcherDragTests, DragAndDropWhenMultiDisplays) { + performDrag(); + + // Update window of second display. + sp windowInSecondary = + new FakeWindowHandle(mApp, mDispatcher, "D_2", SECOND_DISPLAY_ID); + mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}}); + + // Let second display has a touch state. + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, + MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, + AINPUT_SOURCE_TOUCHSCREEN) + .displayId(SECOND_DISPLAY_ID) + .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_FINGER) + .x(100) + .y(100)) + .build())); + windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_DOWN, + SECOND_DISPLAY_ID, 0 /* expectedFlag */); + // Update window again. + mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}}); + + // Move on window. + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, + ADISPLAY_ID_DEFAULT, {50, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT); + mWindow->consumeDragEvent(false, 50, 50); + mSecondWindow->assertNoEvents(); + + // Move to another window. + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN, + ADISPLAY_ID_DEFAULT, {150, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + mDragWindow->consumeMotionMove(ADISPLAY_ID_DEFAULT); + mWindow->consumeDragEvent(true, 150, 50); + mSecondWindow->consumeDragEvent(false, 50, 50); + + // drop to another window. + ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, + injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, + {150, 50})) + << "Inject motion event should return InputEventInjectionResult::SUCCEEDED"; + mDragWindow->consumeMotionUp(ADISPLAY_ID_DEFAULT); + mFakePolicy->assertDropTargetEquals(mSecondWindow->getToken()); + mWindow->assertNoEvents(); + mSecondWindow->assertNoEvents(); +} + class InputDispatcherDropInputFeatureTest : public InputDispatcherTest {}; TEST_F(InputDispatcherDropInputFeatureTest, WindowDropsInput) { -- cgit v1.2.3 From 05da008e9dcc1466e2e7779d5f5408bbf5c7f4d6 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Wed, 25 May 2022 23:29:34 -0700 Subject: SurfaceFlinger: Correct logic error in early release Client composition early release logic should function roughly like this: 1. Set client composition fence on layer if it's client composed 2. If we process setBuffer when we have the fence, release the previous buffer with the client composition fence 3. If we display the layer a second time we clear the client composition fence. The current implementation doesn't really accomplish this. Since onLayerDisplayed comes after setting the client composition fence, we need to track "the second onLayerDisplayed after onPostComposition". Unfortunately when adding the onPostComposition logic I seem to have not thought carefully enough about this, likely because I was too focused on the multi-display issue going on in the previous bug. This logic should also work to solve that bug. Bug: 231290210 Test: Existing tests pass Change-Id: I0fbf3cf3e2b39410fdac3bc0db905a4d088aba58 --- services/surfaceflinger/BufferLayer.cpp | 2 -- services/surfaceflinger/BufferStateLayer.cpp | 4 ++-- services/surfaceflinger/CompositionEngine/src/Output.cpp | 1 + services/surfaceflinger/Layer.h | 3 ++- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index f8c53c338e..d9c89cd821 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -358,8 +358,6 @@ void BufferLayer::onPostComposition(const DisplayDevice* display, // composition. if (!mBufferInfo.mFrameLatencyNeeded) return; - mAlreadyDisplayedThisCompose = false; - // Update mFrameEventHistory. finalizeFrameEventHistory(glDoneFence, compositorTiming); diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index 1a5b925b13..fecf5ae059 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -79,10 +79,10 @@ void BufferStateLayer::onLayerDisplayed(ftl::SharedFuture futureFen // For example we can only use it if all the displays are client comp, and we need // to merge all the client comp fences. We could do this, but for now we just // disable the optimization when a layer is composed on multiple displays. - if (mAlreadyDisplayedThisCompose) { + if (mClearClientCompositionFenceOnLayerDisplayed) { mLastClientCompositionFence = nullptr; } else { - mAlreadyDisplayedThisCompose = true; + mClearClientCompositionFenceOnLayerDisplayed = true; } // The previous release fence notifies the client that SurfaceFlinger is done with the previous diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index aac478de40..c3385a8a8b 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -1300,6 +1300,7 @@ std::vector Output::generateClientCompositionRequests( const auto& layerState = layer->getState(); const auto* layerFEState = layer->getLayerFE().getCompositionState(); auto& layerFE = layer->getLayerFE(); + layerFE.setWasClientComposed(nullptr); const Region clip(viewportRegion.intersect(layerState.visibleRegion)); ALOGV("Layer: %s", layerFE.getDebugName()); diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 3988e51f84..24abad9b45 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -620,6 +620,7 @@ public: void setWasClientComposed(const sp& fence) override { mLastClientCompositionFence = fence; + mClearClientCompositionFenceOnLayerDisplayed = false; } const char* getDebugName() const override; @@ -1035,7 +1036,7 @@ protected: mutable bool mDrawingStateModified = false; sp mLastClientCompositionFence; - bool mAlreadyDisplayedThisCompose = false; + bool mClearClientCompositionFenceOnLayerDisplayed = false; private: virtual void setTransformHint(ui::Transform::RotationFlags) {} -- cgit v1.2.3 From 4ded0b06035d9e69ef88c5ccd0a794eb3104ad5c Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Thu, 26 May 2022 00:36:48 +0000 Subject: Validate indices when requesting PointerCoords We are investigating a crash in PointerCoords. To further understand what kind of MotionEvents we are dealing with, let's add some assertions to the PointerCoords that we are producing. It's possible that pointerCount is zero, for example. This would help us further narrow down the issue. In this CL, we are also adding a way to dump MotionEvent. This was loosely following MotionEvent.java::toString() method. At some point, we should remove the Java method implementation and replace it with a single jni call to native. That work is out of scope for this CL. In the jni layer, we can't remove the error checking/exception raising, because someone might be catching an exception and moving on, and a native crash would break this pattern. We can consider doing that in the future under an experiment flag, though. Bug: 233163975 Test: printed MotionEvent in log to see the formatting Change-Id: I4f641c0cb89526a06146e4c0cf3a5fab2faa42f8 --- include/input/Input.h | 2 ++ libs/input/Input.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/include/input/Input.h b/include/input/Input.h index b23a9518f7..e7d68fc349 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -837,6 +837,8 @@ protected: std::vector mSamplePointerCoords; }; +std::ostream& operator<<(std::ostream& out, const MotionEvent& event); + /* * Focus events. */ diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index fe1754c78b..13ca9ecd35 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -22,7 +22,9 @@ #include #include +#include #include +#include #include #include #include @@ -542,7 +544,14 @@ void MotionEvent::setCursorPosition(float x, float y) { } const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const { - return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex]; + if (CC_UNLIKELY(pointerIndex < 0 || pointerIndex >= getPointerCount())) { + LOG(FATAL) << __func__ << ": Invalid pointer index " << pointerIndex << " for " << *this; + } + const size_t position = getHistorySize() * getPointerCount() + pointerIndex; + if (CC_UNLIKELY(position < 0 || position >= mSamplePointerCoords.size())) { + LOG(FATAL) << __func__ << ": Invalid array index " << position << " for " << *this; + } + return &mSamplePointerCoords[position]; } float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const { @@ -555,7 +564,18 @@ float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const { const PointerCoords* MotionEvent::getHistoricalRawPointerCoords( size_t pointerIndex, size_t historicalIndex) const { - return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex]; + if (CC_UNLIKELY(pointerIndex < 0 || pointerIndex >= getPointerCount())) { + LOG(FATAL) << __func__ << ": Invalid pointer index " << pointerIndex << " for " << *this; + } + if (CC_UNLIKELY(historicalIndex < 0 || historicalIndex > getHistorySize())) { + LOG(FATAL) << __func__ << ": Invalid historical index " << historicalIndex << " for " + << *this; + } + const size_t position = historicalIndex * getPointerCount() + pointerIndex; + if (CC_UNLIKELY(position < 0 || position >= mSamplePointerCoords.size())) { + LOG(FATAL) << __func__ << ": Invalid array index " << position << " for " << *this; + } + return &mSamplePointerCoords[position]; } float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, @@ -903,6 +923,53 @@ PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source, return out; } +std::ostream& operator<<(std::ostream& out, const MotionEvent& event) { + out << "MotionEvent { action=" << MotionEvent::actionToString(event.getAction()); + if (event.getActionButton() != 0) { + out << ", actionButton=" << std::to_string(event.getActionButton()); + } + const size_t pointerCount = event.getPointerCount(); + for (size_t i = 0; i < pointerCount; i++) { + out << ", id[" << i << "]=" << event.getPointerId(i); + float x = event.getX(i); + float y = event.getY(i); + if (x != 0 || y != 0) { + out << ", x[" << i << "]=" << x; + out << ", y[" << i << "]=" << y; + } + int toolType = event.getToolType(i); + if (toolType != AMOTION_EVENT_TOOL_TYPE_FINGER) { + out << ", toolType[" << i << "]=" << toolType; + } + } + if (event.getButtonState() != 0) { + out << ", buttonState=" << event.getButtonState(); + } + if (event.getClassification() != MotionClassification::NONE) { + out << ", classification=" << motionClassificationToString(event.getClassification()); + } + if (event.getMetaState() != 0) { + out << ", metaState=" << event.getMetaState(); + } + if (event.getEdgeFlags() != 0) { + out << ", edgeFlags=" << event.getEdgeFlags(); + } + if (pointerCount != 1) { + out << ", pointerCount=" << pointerCount; + } + if (event.getHistorySize() != 0) { + out << ", historySize=" << event.getHistorySize(); + } + out << ", eventTime=" << event.getEventTime(); + out << ", downTime=" << event.getDownTime(); + out << ", deviceId=" << event.getDeviceId(); + out << ", source=" << inputEventSourceToString(event.getSource()); + out << ", displayId=" << event.getDisplayId(); + out << ", eventId=" << event.getId(); + out << "}"; + return out; +} + // --- FocusEvent --- void FocusEvent::initialize(int32_t id, bool hasFocus) { -- cgit v1.2.3 From 6ba7f2b4870df952ff8bb470fd52d91d9f206ae6 Mon Sep 17 00:00:00 2001 From: Alec Mouri Date: Thu, 2 Jun 2022 22:55:05 +0000 Subject: Use the correct dataspace in shaders.cpp This improves the quality of HDR->SDR tone-mapping in TextureView by removing an incorrect gamut mapping which was causing undesired hue shift. The technical detail is that in TextureView, skia will color manage the input image to the destination colorspace prior to tone-mapping. The tone-mapping shader library compensates when authoring the shader to use the correct EOTF when re-decoding the image, but did not compensate when binding uniforms. This patch compensates accordingly so that the correct gamut->gamut mapping is applied. This patch adds a brief test suite for libshaders to verify that the correct color gamut matrices are being selected. Bug: 234355355 Test: Observe accurate HLG colors in Photos and Instagram where TextureView is used for media playback. Test: libshaders_test Change-Id: I801349cfe1780880a55528fd7e91ff1ac553281b --- libs/shaders/TEST_MAPPING | 10 ++++ libs/shaders/shaders.cpp | 9 +++- libs/shaders/tests/Android.bp | 48 ++++++++++++++++++ libs/shaders/tests/shaders_test.cpp | 98 +++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 libs/shaders/TEST_MAPPING create mode 100644 libs/shaders/tests/Android.bp create mode 100644 libs/shaders/tests/shaders_test.cpp diff --git a/libs/shaders/TEST_MAPPING b/libs/shaders/TEST_MAPPING new file mode 100644 index 0000000000..ad6514d201 --- /dev/null +++ b/libs/shaders/TEST_MAPPING @@ -0,0 +1,10 @@ +{ + "presubmit": [ + { + "name": "librenderengine_test" + }, + { + "name": "libshaders_test" + } + ] +} diff --git a/libs/shaders/shaders.cpp b/libs/shaders/shaders.cpp index 62745dc8d5..f80e93f6f8 100644 --- a/libs/shaders/shaders.cpp +++ b/libs/shaders/shaders.cpp @@ -469,12 +469,17 @@ std::vector buildLinearEffectUniforms( float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer, aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) { std::vector uniforms; - if (linearEffect.inputDataspace == linearEffect.outputDataspace) { + + const ui::Dataspace inputDataspace = linearEffect.fakeInputDataspace == ui::Dataspace::UNKNOWN + ? linearEffect.inputDataspace + : linearEffect.fakeInputDataspace; + + if (inputDataspace == linearEffect.outputDataspace) { uniforms.push_back({.name = "in_rgbToXyz", .value = buildUniformValue(mat4())}); uniforms.push_back( {.name = "in_xyzToRgb", .value = buildUniformValue(colorTransform)}); } else { - ColorSpace inputColorSpace = toColorSpace(linearEffect.inputDataspace); + ColorSpace inputColorSpace = toColorSpace(inputDataspace); ColorSpace outputColorSpace = toColorSpace(linearEffect.outputDataspace); uniforms.push_back({.name = "in_rgbToXyz", .value = buildUniformValue(mat4(inputColorSpace.getRGBtoXYZ()))}); diff --git a/libs/shaders/tests/Android.bp b/libs/shaders/tests/Android.bp new file mode 100644 index 0000000000..cf671bcb7a --- /dev/null +++ b/libs/shaders/tests/Android.bp @@ -0,0 +1,48 @@ +// Copyright 2022 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_native_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_native_license"], +} + +cc_test { + name: "libshaders_test", + test_suites: ["device-tests"], + srcs: [ + "shaders_test.cpp", + ], + header_libs: [ + "libtonemap_headers", + ], + shared_libs: [ + "android.hardware.graphics.common-V3-ndk", + "android.hardware.graphics.composer3-V1-ndk", + "android.hardware.graphics.common@1.2", + "libnativewindow", + ], + static_libs: [ + "libarect", + "libgmock", + "libgtest", + "libmath", + "libshaders", + "libtonemap", + "libui-types", + ], +} diff --git a/libs/shaders/tests/shaders_test.cpp b/libs/shaders/tests/shaders_test.cpp new file mode 100644 index 0000000000..d45fb246c7 --- /dev/null +++ b/libs/shaders/tests/shaders_test.cpp @@ -0,0 +1,98 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "shaders/shaders.h" +#include +#include +#include +#include +#include +#include + +namespace android { + +using testing::Contains; +using testing::HasSubstr; + +struct ShadersTest : public ::testing::Test {}; + +namespace { + +MATCHER_P2(UniformEq, name, value, "") { + return arg.name == name && arg.value == value; +} + +template ::value, bool> = true> +std::vector buildUniformValue(T value) { + std::vector result; + result.resize(sizeof(value)); + std::memcpy(result.data(), &value, sizeof(value)); + return result; +} + +} // namespace + +TEST_F(ShadersTest, buildLinearEffectUniforms_selectsNoOpGamutMatrices) { + shaders::LinearEffect effect = + shaders::LinearEffect{.inputDataspace = ui::Dataspace::V0_SRGB_LINEAR, + .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR, + .fakeInputDataspace = ui::Dataspace::UNKNOWN}; + + mat4 colorTransform = mat4::scale(vec4(.9, .9, .9, 1.)); + auto uniforms = + shaders::buildLinearEffectUniforms(effect, colorTransform, 1.f, 1.f, 1.f, nullptr, + aidl::android::hardware::graphics::composer3:: + RenderIntent::COLORIMETRIC); + EXPECT_THAT(uniforms, Contains(UniformEq("in_rgbToXyz", buildUniformValue(mat4())))); + EXPECT_THAT(uniforms, + Contains(UniformEq("in_xyzToRgb", buildUniformValue(colorTransform)))); +} + +TEST_F(ShadersTest, buildLinearEffectUniforms_selectsGamutTransformMatrices) { + shaders::LinearEffect effect = + shaders::LinearEffect{.inputDataspace = ui::Dataspace::V0_SRGB, + .outputDataspace = ui::Dataspace::DISPLAY_P3, + .fakeInputDataspace = ui::Dataspace::UNKNOWN}; + + ColorSpace inputColorSpace = ColorSpace::sRGB(); + ColorSpace outputColorSpace = ColorSpace::DisplayP3(); + auto uniforms = + shaders::buildLinearEffectUniforms(effect, mat4(), 1.f, 1.f, 1.f, nullptr, + aidl::android::hardware::graphics::composer3:: + RenderIntent::COLORIMETRIC); + EXPECT_THAT(uniforms, + Contains(UniformEq("in_rgbToXyz", + buildUniformValue(mat4(inputColorSpace.getRGBtoXYZ()))))); + EXPECT_THAT(uniforms, + Contains(UniformEq("in_xyzToRgb", + buildUniformValue(mat4(outputColorSpace.getXYZtoRGB()))))); +} + +TEST_F(ShadersTest, buildLinearEffectUniforms_respectsFakeInputDataspace) { + shaders::LinearEffect effect = + shaders::LinearEffect{.inputDataspace = ui::Dataspace::V0_SRGB, + .outputDataspace = ui::Dataspace::DISPLAY_P3, + .fakeInputDataspace = ui::Dataspace::DISPLAY_P3}; + + auto uniforms = + shaders::buildLinearEffectUniforms(effect, mat4(), 1.f, 1.f, 1.f, nullptr, + aidl::android::hardware::graphics::composer3:: + RenderIntent::COLORIMETRIC); + EXPECT_THAT(uniforms, Contains(UniformEq("in_rgbToXyz", buildUniformValue(mat4())))); + EXPECT_THAT(uniforms, Contains(UniformEq("in_xyzToRgb", buildUniformValue(mat4())))); +} + +} // namespace android -- cgit v1.2.3 From 899e8cd0749cb3f43bef0bdb28002edab42bbb1b Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Mon, 6 Jun 2022 15:16:06 -0700 Subject: SurfaceFlinger: fix a potential race condition in stealReceiveChannel Add a mutex to prevent a potential race condition. Bug: 232541124 Test: See bug for details Change-Id: Ia338f124c786bf12d6adba10a67b9048fe9c34a5 --- services/surfaceflinger/Scheduler/EventThread.cpp | 5 +++++ services/surfaceflinger/Scheduler/EventThread.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index cbea77e8fb..639ba5a3f1 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -177,6 +177,11 @@ void EventThreadConnection::onFirstRef() { } binder::Status EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) { + std::scoped_lock lock(mLock); + if (mChannel.initCheck() != NO_ERROR) { + return binder::Status::fromStatusT(NAME_NOT_FOUND); + } + outChannel->setReceiveFd(mChannel.moveReceiveFd()); outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd()))); return binder::Status::ok(); diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index c406478c17..adb96fd462 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -112,7 +112,8 @@ public: private: virtual void onFirstRef(); EventThread* const mEventThread; - gui::BitTube mChannel; + std::mutex mLock; + gui::BitTube mChannel GUARDED_BY(mLock); std::vector mPendingEvents; }; -- cgit v1.2.3 From 29e34cfcf95c6de1f2cbfe2bf588e4e354dbabe0 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Mon, 6 Jun 2022 15:16:06 -0700 Subject: RESTRICT AUTOMERGE SurfaceFlinger: fix a potential race condition in stealReceiveChannel Add a mutex to prevent a potential race condition. Bug: 232541124 Test: See bug for details Change-Id: Ia338f124c786bf12d6adba10a67b9048fe9c34a5 --- services/surfaceflinger/Scheduler/EventThread.cpp | 5 +++++ services/surfaceflinger/Scheduler/EventThread.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 2321e2d082..68f62ba8c3 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -171,6 +171,11 @@ void EventThreadConnection::onFirstRef() { } status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) { + std::scoped_lock lock(mLock); + if (mChannel.initCheck() != NO_ERROR) { + return NAME_NOT_FOUND; + } + outChannel->setReceiveFd(mChannel.moveReceiveFd()); outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd()))); return NO_ERROR; diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 1e6793f77c..b15817a41b 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -102,7 +102,8 @@ public: private: virtual void onFirstRef(); EventThread* const mEventThread; - gui::BitTube mChannel; + std::mutex mLock; + gui::BitTube mChannel GUARDED_BY(mLock); std::vector mPendingEvents; }; -- cgit v1.2.3 From 97a317064a76b8fc3a65bd980027f820fd4d53ae Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Mon, 6 Jun 2022 15:16:06 -0700 Subject: RESTRICT AUTOMERGE SurfaceFlinger: fix a potential race condition in stealReceiveChannel Add a mutex to prevent a potential race condition. Bug: 232541124 Test: See bug for details Change-Id: Ia338f124c786bf12d6adba10a67b9048fe9c34a5 --- services/surfaceflinger/Scheduler/EventThread.cpp | 5 +++++ services/surfaceflinger/Scheduler/EventThread.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 2bdcaf6ad0..695c2a3787 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -171,6 +171,11 @@ void EventThreadConnection::onFirstRef() { } status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) { + std::scoped_lock lock(mLock); + if (mChannel.initCheck() != NO_ERROR) { + return NAME_NOT_FOUND; + } + outChannel->setReceiveFd(mChannel.moveReceiveFd()); outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd()))); return NO_ERROR; diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 9265a25b86..9526fe18be 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -102,7 +102,8 @@ public: private: virtual void onFirstRef(); EventThread* const mEventThread; - gui::BitTube mChannel; + std::mutex mLock; + gui::BitTube mChannel GUARDED_BY(mLock); std::vector mPendingEvents; }; -- cgit v1.2.3 From 0840cdd08f39994e3f8c58eb65f24a8db1dc1173 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Mon, 6 Jun 2022 15:16:06 -0700 Subject: RESTRICT AUTOMERGE SurfaceFlinger: fix a potential race condition in stealReceiveChannel Add a mutex to prevent a potential race condition. Bug: 232541124 Test: See bug for details Change-Id: Ia338f124c786bf12d6adba10a67b9048fe9c34a5 --- services/surfaceflinger/Scheduler/EventThread.cpp | 5 +++++ services/surfaceflinger/Scheduler/EventThread.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 05bad4ddd8..e5711c2e84 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -123,6 +123,11 @@ void EventThreadConnection::onFirstRef() { } status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) { + std::scoped_lock lock(mLock); + if (mChannel.initCheck() != NO_ERROR) { + return NAME_NOT_FOUND; + } + outChannel->setReceiveFd(mChannel.moveReceiveFd()); return NO_ERROR; } diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 61530c62e5..15f21d5dec 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -86,7 +86,8 @@ public: private: virtual void onFirstRef(); EventThread* const mEventThread; - gui::BitTube mChannel; + std::mutex mLock; + gui::BitTube mChannel GUARDED_BY(mLock); }; class EventThread { -- cgit v1.2.3 From 067def0585f4b290f48e79d8f43c5fea9a934a83 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Mon, 6 Jun 2022 15:16:06 -0700 Subject: RESTRICT AUTOMERGE SurfaceFlinger: fix a potential race condition in stealReceiveChannel Add a mutex to prevent a potential race condition. Bug: 232541124 Test: See bug for details Change-Id: Ia338f124c786bf12d6adba10a67b9048fe9c34a5 --- services/surfaceflinger/Scheduler/EventThread.cpp | 5 +++++ services/surfaceflinger/Scheduler/EventThread.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 845bf50ad3..c116dae284 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -138,6 +138,11 @@ void EventThreadConnection::onFirstRef() { } status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) { + std::scoped_lock lock(mLock); + if (mChannel.initCheck() != NO_ERROR) { + return NAME_NOT_FOUND; + } + outChannel->setReceiveFd(mChannel.moveReceiveFd()); outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd()))); return NO_ERROR; diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 49f624c35e..df7fb7dedd 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -92,7 +92,8 @@ public: private: virtual void onFirstRef(); EventThread* const mEventThread; - gui::BitTube mChannel; + std::mutex mLock; + gui::BitTube mChannel GUARDED_BY(mLock); }; class EventThread { -- cgit v1.2.3 From a820057ae00dba322b10d47b3711b04519324690 Mon Sep 17 00:00:00 2001 From: Ady Abraham Date: Mon, 6 Jun 2022 15:16:06 -0700 Subject: RESTRICT AUTOMERGE SurfaceFlinger: fix a potential race condition in stealReceiveChannel Add a mutex to prevent a potential race condition. Bug: 232541124 Test: See bug for details Change-Id: Ia338f124c786bf12d6adba10a67b9048fe9c34a5 --- services/surfaceflinger/Scheduler/EventThread.cpp | 5 +++++ services/surfaceflinger/Scheduler/EventThread.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index cee36a121f..cf57664cd5 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -138,6 +138,11 @@ void EventThreadConnection::onFirstRef() { } status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) { + std::scoped_lock lock(mLock); + if (mChannel.initCheck() != NO_ERROR) { + return NAME_NOT_FOUND; + } + outChannel->setReceiveFd(mChannel.moveReceiveFd()); return NO_ERROR; } diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 64acbd72d0..831bf7baa9 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -98,7 +98,8 @@ public: private: virtual void onFirstRef(); EventThread* const mEventThread; - gui::BitTube mChannel; + std::mutex mLock; + gui::BitTube mChannel GUARDED_BY(mLock); }; class EventThread { -- cgit v1.2.3 From 8f4e41d679d67436ee3868cab8785a35b3cc613f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Wed, 8 Jun 2022 21:38:21 +0000 Subject: add explicit 32-bits of padding to UidTrackingInfo struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (fixes 32-bit arch) Bug: 235386871 Test: TreeHugger Signed-off-by: Maciej Żenczykowski Change-Id: I9c37483eca17011f3f6d9755427c5a380166228e --- services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h b/services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h index 57338f4c91..2affb60a0c 100644 --- a/services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h +++ b/services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h @@ -49,6 +49,8 @@ typedef struct { // negative duration. uint32_t error_count; + // Needed to make 32-bit arch struct size match 64-bit BPF arch struct size. + uint32_t padding0; } UidTrackingInfo; typedef struct { -- cgit v1.2.3