summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-10 16:35:49 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-10 16:35:49 +0000
commitfc86461f833285f3222fb91fe8e3f2e478646294 (patch)
treec5509fb9771d705785e19c2828343af782e59240
parent497f32fcb3c2b0738caaf1e8ae13d337a3ef0b59 (diff)
parent8f4e41d679d67436ee3868cab8785a35b3cc613f (diff)
downloadnative-android13-mainline-go-adservices-release.tar.gz
Snap for 8708169 from 8f4e41d679d67436ee3868cab8785a35b3cc613f to mainline-go-adservices-releaseaml_go_ads_330915100aml_go_ads_330915000aml_go_ads_330913000android13-mainline-go-adservices-release
Change-Id: I3891cdde2b9ba20779bac1382be5d0aac49f65f9
-rw-r--r--include/input/Input.h2
-rw-r--r--libs/input/Input.cpp71
-rw-r--r--libs/shaders/TEST_MAPPING10
-rw-r--r--libs/shaders/shaders.cpp9
-rw-r--r--libs/shaders/tests/Android.bp48
-rw-r--r--libs/shaders/tests/shaders_test.cpp98
-rw-r--r--services/gpuservice/gpuwork/bpfprogs/include/gpuwork/gpu_work.h2
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp6
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp52
-rw-r--r--services/surfaceflinger/BufferLayer.cpp2
-rw-r--r--services/surfaceflinger/BufferStateLayer.cpp4
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h2
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h6
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Output.cpp1
-rw-r--r--services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp1
-rw-r--r--services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp6
-rw-r--r--services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp7
-rw-r--r--services/surfaceflinger/Layer.h3
-rw-r--r--services/surfaceflinger/Scheduler/EventThread.cpp5
-rw-r--r--services/surfaceflinger/Scheduler/EventThread.h3
20 files changed, 326 insertions, 12 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<PointerCoords> 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 <inttypes.h>
#include <string.h>
+#include <android-base/logging.h>
#include <android-base/stringprintf.h>
+#include <cutils/compiler.h>
#include <gui/constants.h>
#include <input/DisplayViewport.h>
#include <input/Input.h>
@@ -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) {
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<tonemap::ShaderUniform> buildLinearEffectUniforms(
float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
std::vector<tonemap::ShaderUniform> 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>(mat4())});
uniforms.push_back(
{.name = "in_xyzToRgb", .value = buildUniformValue<mat4>(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>(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 <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <math/mat4.h>
+#include <tonemap/tonemap.h>
+#include <ui/ColorSpace.h>
+#include <cmath>
+
+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 <typename T, std::enable_if_t<std::is_trivially_copyable<T>::value, bool> = true>
+std::vector<uint8_t> buildUniformValue(T value) {
+ std::vector<uint8_t> 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>(mat4()))));
+ EXPECT_THAT(uniforms,
+ Contains(UniformEq("in_xyzToRgb", buildUniformValue<mat4>(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>(mat4(inputColorSpace.getRGBtoXYZ())))));
+ EXPECT_THAT(uniforms,
+ Contains(UniformEq("in_xyzToRgb",
+ buildUniformValue<mat4>(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>(mat4()))));
+ EXPECT_THAT(uniforms, Contains(UniformEq("in_xyzToRgb", buildUniformValue<mat4>(mat4()))));
+}
+
+} // namespace android
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 {
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<FakeWindowHandle> 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) {
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<FenceResult> 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/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/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<LayerFE::LayerSettings> 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/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<Run> runs = findCandidateRuns(now);
std::optional<Run> bestRun = findBestRun(runs);
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>& fence) override {
mLastClientCompositionFence = fence;
+ mClearClientCompositionFenceOnLayerDisplayed = false;
}
const char* getDebugName() const override;
@@ -1035,7 +1036,7 @@ protected:
mutable bool mDrawingStateModified = false;
sp<Fence> mLastClientCompositionFence;
- bool mAlreadyDisplayedThisCompose = false;
+ bool mClearClientCompositionFenceOnLayerDisplayed = false;
private:
virtual void setTransformHint(ui::Transform::RotationFlags) {}
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<DisplayEventReceiver::Event> mPendingEvents;
};