Merge changes Id1e90796,Ic8fe0fee,I2ed83355
* changes:
SF: Move HWComposerBufferCache in to CompositionEngine
SF: Intro CE::OutputLayer
SF: Setup CompositionEngine::Layer
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 49d8fe9..db8848a 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -981,6 +981,8 @@
AddAnrTraceDir(add_to_zip, anr_traces_dir);
+ RunCommand("ANR FILES", {"ls", "-lt", ANR_DIR});
+
// Slow traces for slow operations.
struct stat st;
int i = 0;
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 940ba79..a639951 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -314,9 +314,15 @@
bool skip_compilation = vold_decrypt == "trigger_restart_min_framework" ||
vold_decrypt == "1";
- const std::string resolve_startup_string_arg =
+ std::string resolve_startup_string_arg =
+ MapPropertyToArg("persist.device_config.runtime.dex2oat_resolve_startup_strings",
+ "--resolve-startup-const-strings=%s");
+ if (resolve_startup_string_arg.empty()) {
+ // If empty, fall back to system property.
+ resolve_startup_string_arg =
MapPropertyToArg("dalvik.vm.dex2oat-resolve-startup-strings",
"--resolve-startup-const-strings=%s");
+ }
const std::string image_block_size_arg =
MapPropertyToArg("dalvik.vm.dex2oat-max-image-block-size",
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index e2afe1d..78edce0 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -23,6 +23,8 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <binder/Status.h>
@@ -85,6 +87,23 @@
system(cmd.c_str());
}
+template <typename Visitor>
+static void run_cmd_and_process_output(const std::string& cmd, const Visitor& visitor) {
+ FILE* file = popen(cmd.c_str(), "r");
+ CHECK(file != nullptr) << "Failed to ptrace " << cmd;
+ char* line = nullptr;
+ while (true) {
+ size_t n = 0u;
+ ssize_t value = getline(&line, &n, file);
+ if (value == -1) {
+ break;
+ }
+ visitor(line);
+ }
+ free(line);
+ fclose(file);
+}
+
static int mkdir(const std::string& path, uid_t owner, gid_t group, mode_t mode) {
int ret = ::mkdir(path.c_str(), mode);
if (ret != 0) {
@@ -222,7 +241,8 @@
::testing::AssertionResult create_mock_app() {
// Create the oat dir.
app_oat_dir_ = app_apk_dir_ + "/oat";
- if (mkdir(app_apk_dir_, kSystemUid, kSystemGid, 0755) != 0) {
+ // For debug mode, the directory might already exist. Avoid erroring out.
+ if (mkdir(app_apk_dir_, kSystemUid, kSystemGid, 0755) != 0 && !kDebug) {
return ::testing::AssertionFailure() << "Could not create app dir " << app_apk_dir_
<< " : " << strerror(errno);
}
@@ -628,6 +648,50 @@
DEX2OAT_FROM_SCRATCH);
}
+TEST_F(DexoptTest, ResolveStartupConstStrings) {
+ LOG(INFO) << "DexoptDex2oatResolveStartupStrings";
+ const std::string property = "persist.device_config.runtime.dex2oat_resolve_startup_strings";
+ const std::string previous_value = android::base::GetProperty(property, "");
+ auto restore_property = android::base::make_scope_guard([=]() {
+ android::base::SetProperty(property, previous_value);
+ });
+ std::string odex = GetPrimaryDexArtifact(app_oat_dir_.c_str(), apk_path_, "odex");
+ // Disable the property to start.
+ bool found_disable = false;
+ ASSERT_TRUE(android::base::SetProperty(property, "false")) << property;
+ CompilePrimaryDexOk("speed-profile",
+ DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
+ DEXOPT_GENERATE_APP_IMAGE,
+ app_oat_dir_.c_str(),
+ kTestAppGid,
+ DEX2OAT_FROM_SCRATCH);
+ run_cmd_and_process_output(
+ "oatdump --header-only --oat-file=" + odex,
+ [&](const std::string& line) {
+ if (line.find("--resolve-startup-const-strings=false") != std::string::npos) {
+ found_disable = true;
+ }
+ });
+ EXPECT_TRUE(found_disable);
+ // Enable the property and inspect that .art artifact is larger.
+ bool found_enable = false;
+ ASSERT_TRUE(android::base::SetProperty(property, "true")) << property;
+ CompilePrimaryDexOk("speed-profile",
+ DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
+ DEXOPT_GENERATE_APP_IMAGE,
+ app_oat_dir_.c_str(),
+ kTestAppGid,
+ DEX2OAT_FROM_SCRATCH);
+ run_cmd_and_process_output(
+ "oatdump --header-only --oat-file=" + odex,
+ [&](const std::string& line) {
+ if (line.find("--resolve-startup-const-strings=true") != std::string::npos) {
+ found_enable = true;
+ }
+ });
+ EXPECT_TRUE(found_enable);
+}
+
class PrimaryDexReCompilationTest : public DexoptTest {
public:
virtual void SetUp() {
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index f779d6e..49592a8 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -599,17 +599,53 @@
return mHasFds;
}
+void Parcel::updateWorkSourceRequestHeaderPosition() const {
+ // Only update the request headers once. We only want to point
+ // to the first headers read/written.
+ if (!mRequestHeaderPresent) {
+ mWorkSourceRequestHeaderPosition = dataPosition();
+ mRequestHeaderPresent = true;
+ }
+}
+
// Write RPC headers. (previously just the interface token)
status_t Parcel::writeInterfaceToken(const String16& interface)
{
const IPCThreadState* threadState = IPCThreadState::self();
writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
+ updateWorkSourceRequestHeaderPosition();
writeInt32(threadState->shouldPropagateWorkSource() ?
threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
// currently the interface identification token is just its name as a string
return writeString16(interface);
}
+bool Parcel::replaceCallingWorkSourceUid(uid_t uid)
+{
+ if (!mRequestHeaderPresent) {
+ return false;
+ }
+
+ const size_t initialPosition = dataPosition();
+ setDataPosition(mWorkSourceRequestHeaderPosition);
+ status_t err = writeInt32(uid);
+ setDataPosition(initialPosition);
+ return err == NO_ERROR;
+}
+
+uid_t Parcel::readCallingWorkSourceUid()
+{
+ if (!mRequestHeaderPresent) {
+ return IPCThreadState::kUnsetWorkSource;
+ }
+
+ const size_t initialPosition = dataPosition();
+ setDataPosition(mWorkSourceRequestHeaderPosition);
+ uid_t uid = readInt32();
+ setDataPosition(initialPosition);
+ return uid;
+}
+
bool Parcel::checkInterface(IBinder* binder) const
{
return enforceInterface(binder->getInterfaceDescriptor());
@@ -634,6 +670,7 @@
threadState->setStrictModePolicy(strictPolicy);
}
// WorkSource.
+ updateWorkSourceRequestHeaderPosition();
int32_t workSource = readInt32();
threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
// Interface descriptor.
@@ -2889,6 +2926,8 @@
mAllowFds = true;
mOwner = nullptr;
mOpenAshmemSize = 0;
+ mWorkSourceRequestHeaderPosition = 0;
+ mRequestHeaderPresent = false;
// racing multiple init leads only to multiple identical write
if (gMaxFds == 0) {
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 240b708..afdfe4f 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -395,6 +395,12 @@
static size_t getGlobalAllocSize();
static size_t getGlobalAllocCount();
+ bool replaceCallingWorkSourceUid(uid_t uid);
+ // Returns the work source provided by the caller. This can only be trusted for trusted calling
+ // uid.
+ uid_t readCallingWorkSourceUid();
+ void readRequestHeaders() const;
+
private:
typedef void (*release_func)(Parcel* parcel,
const uint8_t* data, size_t dataSize,
@@ -429,6 +435,7 @@
void initState();
void scanForFds() const;
status_t validateReadData(size_t len) const;
+ void updateWorkSourceRequestHeaderPosition() const;
template<class T>
status_t readAligned(T *pArg) const;
@@ -477,6 +484,9 @@
mutable size_t mNextObjectHint;
mutable bool mObjectsSorted;
+ mutable bool mRequestHeaderPresent;
+ mutable size_t mWorkSourceRequestHeaderPosition;
+
mutable bool mFdsKnown;
mutable bool mHasFds;
bool mAllowFds;
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 6091d3f..206bc30 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -98,8 +98,8 @@
output.writeInt32(cachedBuffer.bufferId);
output.writeParcelable(metadata);
- output.writeFloat(colorAlpha);
- output.writeUint32(static_cast<uint32_t>(colorDataspace));
+ output.writeFloat(bgColorAlpha);
+ output.writeUint32(static_cast<uint32_t>(bgColorDataspace));
return NO_ERROR;
}
@@ -175,8 +175,8 @@
cachedBuffer.bufferId = input.readInt32();
input.readParcelable(&metadata);
- colorAlpha = input.readFloat();
- colorDataspace = static_cast<ui::Dataspace>(input.readUint32());
+ bgColorAlpha = input.readFloat();
+ bgColorDataspace = static_cast<ui::Dataspace>(input.readUint32());
return NO_ERROR;
}
@@ -390,13 +390,11 @@
what |= eCachedBufferChanged;
cachedBuffer = other.cachedBuffer;
}
- if (other.what & eColorAlphaChanged) {
- what |= eColorAlphaChanged;
- colorAlpha = other.colorAlpha;
- }
- if (other.what & eColorDataspaceChanged) {
- what |= eColorDataspaceChanged;
- colorDataspace = other.colorDataspace;
+ if (other.what & eBackgroundColorChanged) {
+ what |= eBackgroundColorChanged;
+ color = other.color;
+ bgColorAlpha = other.bgColorAlpha;
+ bgColorDataspace = other.bgColorDataspace;
}
if (other.what & eMetadataChanged) {
what |= eMetadataChanged;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index c712bde..51385b8 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -678,31 +678,18 @@
return *this;
}
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorAlpha(
- const sp<SurfaceControl>& sc, float alpha) {
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundColor(
+ const sp<SurfaceControl>& sc, const half3& color, float alpha, ui::Dataspace dataspace) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
- s->what |= layer_state_t::eColorAlphaChanged;
- s->colorAlpha = alpha;
-
- registerSurfaceControlForCallback(sc);
- return *this;
-}
-
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColorDataspace(
- const sp<SurfaceControl>& sc, ui::Dataspace dataspace) {
- layer_state_t* s = getLayerState(sc);
- if (!s) {
- mStatus = BAD_INDEX;
- return *this;
- }
-
- s->what |= layer_state_t::eColorDataspaceChanged;
- s->colorDataspace = dataspace;
+ s->what |= layer_state_t::eBackgroundColorChanged;
+ s->color = color;
+ s->bgColorAlpha = alpha;
+ s->bgColorDataspace = dataspace;
registerSurfaceControlForCallback(sc);
return *this;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index afd843f..c780c07 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -86,9 +86,8 @@
eCornerRadiusChanged = 0x80000000,
eFrameChanged = 0x1'00000000,
eCachedBufferChanged = 0x2'00000000,
- eColorAlphaChanged = 0x4'00000000,
- eColorDataspaceChanged = 0x8'00000000,
- eMetadataChanged = 0x10'00000000,
+ eBackgroundColorChanged = 0x4'00000000,
+ eMetadataChanged = 0x8'00000000,
};
layer_state_t()
@@ -115,8 +114,8 @@
surfaceDamageRegion(),
api(-1),
colorTransform(mat4()),
- colorAlpha(0),
- colorDataspace(ui::Dataspace::UNKNOWN) {
+ bgColorAlpha(0),
+ bgColorDataspace(ui::Dataspace::UNKNOWN) {
matrix.dsdx = matrix.dtdy = 1.0f;
matrix.dsdy = matrix.dtdx = 0.0f;
hdrMetadata.validTypes = 0;
@@ -187,10 +186,12 @@
cached_buffer_t cachedBuffer;
- float colorAlpha;
- ui::Dataspace colorDataspace;
-
LayerMetadata metadata;
+
+ // The following refer to the alpha, and dataspace, respectively of
+ // the background color layer
+ float bgColorAlpha;
+ ui::Dataspace bgColorDataspace;
};
struct ComposerState {
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 8e2bb2b..a95664b 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -330,11 +330,9 @@
Transaction& setColor(const sp<SurfaceControl>& sc, const half3& color);
- // Sets the alpha of the background color layer if it exists.
- Transaction& setColorAlpha(const sp<SurfaceControl>& sc, float alpha);
-
- // Sets the dataspace of the background color layer if it exists.
- Transaction& setColorDataspace(const sp<SurfaceControl>& sc, ui::Dataspace dataspace);
+ // Sets the background color of a layer with the specified color, alpha, and dataspace
+ Transaction& setBackgroundColor(const sp<SurfaceControl>& sc, const half3& color,
+ float alpha, ui::Dataspace dataspace);
Transaction& setTransform(const sp<SurfaceControl>& sc, uint32_t transform);
Transaction& setTransformToDisplayInverse(const sp<SurfaceControl>& sc,
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 96a66cb..2005d20 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -303,48 +303,6 @@
return true;
}
-bool BufferStateLayer::setColor(const half3& color) {
- // create color layer if one does not yet exist
- if (!mCurrentState.bgColorLayer) {
- uint32_t flags = ISurfaceComposerClient::eFXSurfaceColor;
- const String8& name = mName + "BackgroundColorLayer";
- mCurrentState.bgColorLayer =
- new ColorLayer(LayerCreationArgs(mFlinger.get(), nullptr, name, 0, 0, flags));
-
- // add to child list
- addChild(mCurrentState.bgColorLayer);
- mFlinger->mLayersAdded = true;
- // set up SF to handle added color layer
- if (isRemovedFromCurrentState()) {
- mCurrentState.bgColorLayer->onRemovedFromCurrentState();
- }
- mFlinger->setTransactionFlags(eTransactionNeeded);
- }
-
- mCurrentState.bgColorLayer->setColor(color);
- mCurrentState.bgColorLayer->setLayer(std::numeric_limits<int32_t>::min());
-
- return true;
-}
-
-bool BufferStateLayer::setColorAlpha(float alpha) {
- if (!mCurrentState.bgColorLayer) {
- ALOGE("Attempting to set color alpha on a buffer state layer with no background color");
- return false;
- }
- mCurrentState.bgColorLayer->setAlpha(alpha);
- return true;
-}
-
-bool BufferStateLayer::setColorDataspace(ui::Dataspace dataspace) {
- if (!mCurrentState.bgColorLayer) {
- ALOGE("Attempting to set color dataspace on a buffer state layer with no background color");
- return false;
- }
- mCurrentState.bgColorLayer->setDataspace(dataspace);
- return true;
-}
-
Rect BufferStateLayer::getBufferSize(const State& s) const {
// for buffer state layers we use the display frame size as the buffer size.
if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) {
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index bef9f19..138bb4c 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -82,9 +82,6 @@
}
bool setCrop_legacy(const Rect& /*crop*/, bool /*immediate*/) override { return false; }
bool setOverrideScalingMode(int32_t /*overrideScalingMode*/) override { return false; }
- bool setColor(const half3& color) override;
- bool setColorAlpha(float alpha) override;
- bool setColorDataspace(ui::Dataspace dataspace) override;
void deferTransactionUntil_legacy(const sp<IBinder>& /*barrierHandle*/,
uint64_t /*frameNumber*/) override {}
void deferTransactionUntil_legacy(const sp<Layer>& /*barrierLayer*/,
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index c2f81c2..d82ff0e 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -58,6 +58,21 @@
return !isHiddenByPolicy() && getAlpha() > 0.0f;
}
+bool ColorLayer::setColor(const half3& color) {
+ if (mCurrentState.color.r == color.r && mCurrentState.color.g == color.g &&
+ mCurrentState.color.b == color.b) {
+ return false;
+ }
+
+ mCurrentState.sequence++;
+ mCurrentState.color.r = color.r;
+ mCurrentState.color.g = color.g;
+ mCurrentState.color.b = color.b;
+ mCurrentState.modified = true;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+
void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform,
const Rect& viewport, int32_t /* supportedPerFrameMetadata */) {
RETURN_IF_NO_HWC_LAYER(displayId);
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index ecaef82..ed4c2d8 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -33,6 +33,8 @@
virtual const char* getTypeId() const { return "ColorLayer"; }
bool isVisible() const override;
+ bool setColor(const half3& color) override;
+
void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
int32_t supportedPerFrameMetadata) override;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f49733b..185393e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -46,6 +46,7 @@
#include <gui/Surface.h>
#include "BufferLayer.h"
+#include "ColorLayer.h"
#include "Colorizer.h"
#include "DisplayDevice.h"
#include "Layer.h"
@@ -107,7 +108,6 @@
mCurrentState.cornerRadius = 0.0f;
mCurrentState.api = -1;
mCurrentState.hasColorTransform = false;
- mCurrentState.colorDataspace = ui::Dataspace::UNKNOWN;
// drawing state & current state are identical
mDrawingState = mCurrentState;
@@ -1106,6 +1106,11 @@
mNeedsFiltering = (!getActiveTransform(c).preserveRects() || type >= ui::Transform::SCALE);
}
+ if (mChildrenChanged) {
+ flags |= eVisibleRegion;
+ mChildrenChanged = false;
+ }
+
// If the layer is hidden, signal and clear out all local sync points so
// that transactions for layers depending on this layer's frames becoming
// visible are not blocked
@@ -1272,17 +1277,35 @@
return true;
}
-bool Layer::setColor(const half3& color) {
- if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g &&
- color.b == mCurrentState.color.b)
+bool Layer::setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace) {
+ if (!mCurrentState.bgColorLayer && alpha == 0) {
return false;
+ } else if (!mCurrentState.bgColorLayer && alpha != 0) {
+ // create background color layer if one does not yet exist
+ uint32_t flags = ISurfaceComposerClient::eFXSurfaceColor;
+ const String8& name = mName + "BackgroundColorLayer";
+ mCurrentState.bgColorLayer =
+ new ColorLayer(LayerCreationArgs(mFlinger.get(), nullptr, name, 0, 0, flags));
- mCurrentState.sequence++;
- mCurrentState.color.r = color.r;
- mCurrentState.color.g = color.g;
- mCurrentState.color.b = color.b;
- mCurrentState.modified = true;
- setTransactionFlags(eTransactionNeeded);
+ // add to child list
+ addChild(mCurrentState.bgColorLayer);
+ mFlinger->mLayersAdded = true;
+ // set up SF to handle added color layer
+ if (isRemovedFromCurrentState()) {
+ mCurrentState.bgColorLayer->onRemovedFromCurrentState();
+ }
+ mFlinger->setTransactionFlags(eTransactionNeeded);
+ } else if (mCurrentState.bgColorLayer && alpha == 0) {
+ mCurrentState.bgColorLayer->reparent(nullptr);
+ mCurrentState.bgColorLayer = nullptr;
+ return true;
+ }
+
+ mCurrentState.bgColorLayer->setColor(color);
+ mCurrentState.bgColorLayer->setLayer(std::numeric_limits<int32_t>::min());
+ mCurrentState.bgColorLayer->setAlpha(alpha);
+ mCurrentState.bgColorLayer->setDataspace(dataspace);
+
return true;
}
@@ -1610,13 +1633,16 @@
}
void Layer::addChild(const sp<Layer>& layer) {
+ mChildrenChanged = true;
+
mCurrentChildren.add(layer);
layer->setParent(this);
}
ssize_t Layer::removeChild(const sp<Layer>& layer) {
- layer->setParent(nullptr);
+ mChildrenChanged = true;
+ layer->setParent(nullptr);
return mCurrentChildren.remove(layer);
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f5ef761..4cead87 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -209,7 +209,6 @@
// and the buffer state layer's children. Z order will be set to
// INT_MIN
sp<Layer> bgColorLayer;
- ui::Dataspace colorDataspace; // The dataspace of the background color layer
// The deque of callback handles for this frame. The back of the deque contains the most
// recent callback handle.
@@ -275,7 +274,7 @@
virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ);
virtual bool setAlpha(float alpha);
- virtual bool setColor(const half3& color);
+ virtual bool setColor(const half3& /*color*/) { return false; };
// Set rounded corner radius for this layer and its children.
//
@@ -318,8 +317,7 @@
const std::vector<sp<CallbackHandle>>& /*handles*/) {
return false;
};
- virtual bool setColorAlpha(float /*alpha*/) { return false; };
- virtual bool setColorDataspace(ui::Dataspace /*dataspace*/) { return false; };
+ virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace);
ui::Dataspace getDataSpace() const { return mCurrentDataSpace; }
@@ -857,6 +855,8 @@
// Can only be accessed with the SF state lock held.
bool mLayerDetached{false};
+ // Can only be accessed with the SF state lock held.
+ bool mChildrenChanged{false};
private:
/**
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 35ceedc..2fea060 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3872,17 +3872,16 @@
if (layer->setColor(s.color))
flags |= eTraversalNeeded;
}
- if (what & layer_state_t::eColorAlphaChanged) {
- if (layer->setColorAlpha(s.colorAlpha)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eColorDataspaceChanged) {
- if (layer->setColorDataspace(s.colorDataspace)) flags |= eTraversalNeeded;
- }
if (what & layer_state_t::eColorTransformChanged) {
if (layer->setColorTransform(s.colorTransform)) {
flags |= eTraversalNeeded;
}
}
+ if (what & layer_state_t::eBackgroundColorChanged) {
+ if (layer->setBackgroundColor(s.color, s.bgColorAlpha, s.bgColorDataspace)) {
+ flags |= eTraversalNeeded;
+ }
+ }
if (what & layer_state_t::eMatrixChanged) {
// TODO: b/109894387
//
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 56d3bd4..4f0ded3 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -675,6 +675,8 @@
void setRelativeZBasicHelper(uint32_t layerType);
void setRelativeZGroupHelper(uint32_t layerType);
void setAlphaBasicHelper(uint32_t layerType);
+ void setBackgroundColorHelper(uint32_t layerType, bool priorColor, bool bufferFill, float alpha,
+ Color finalColor);
protected:
LayerRenderPathTestHarness mHarness;
@@ -1330,92 +1332,6 @@
getScreenCapture()->expectColor(Rect(16, 16, 48, 48), Color::RED);
}
-TEST_P(LayerRenderTypeTransactionTest, SetColorAlpha_Color_NoEffect) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(
- layer = createLayer("test", 0, 0, ISurfaceComposerClient::eFXSurfaceColor));
-
- half3 color;
- color.r = 1.0f;
- color.g = 0.0f;
- color.b = 0.0f;
- Transaction()
- .setCrop_legacy(layer, Rect(0, 0, 32, 32))
- .setAlpha(layer, 1.0f)
- .setColor(layer, color)
- .setColorAlpha(layer, 0.5f)
- .apply();
-
- screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
-}
-
-TEST_P(LayerRenderTypeTransactionTest, SetColorAlpha_BufferQueue_NoEffect) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
-
- Transaction().setAlpha(layer, 1.0f).setColorAlpha(layer, 0.5f).apply();
-
- screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
-}
-
-TEST_P(LayerRenderTypeTransactionTest, SetColorAlpha_BufferState_ColorLayer) {
- sp<SurfaceControl> bgLayer;
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(bgLayer = createLayer("test bg", 32, 32));
- ASSERT_NO_FATAL_FAILURE(
- layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
-
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bgLayer, Color::RED, 32, 32));
-
- // create color layer
- half3 color;
- color.r = 0.0f;
- color.g = 1.0f;
- color.b = 0.0f;
- Transaction().setFrame(layer, Rect(0, 0, 32, 32)).setColor(layer, color).apply();
-
- {
- SCOPED_TRACE("before alpha");
- auto shot = screenshot();
- shot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
- shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
- }
-
- // apply alpha
- Transaction().setAlpha(layer, 0.0f).apply();
- {
- SCOPED_TRACE("set alpha");
- auto shot = screenshot();
- shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
- shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
- }
-}
-
-TEST_P(LayerRenderTypeTransactionTest, SetColorAlpha_BufferState_NoColorLayer) {
- sp<SurfaceControl> bgLayer;
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(bgLayer = createLayer("test bg", 32, 32));
- ASSERT_NO_FATAL_FAILURE(
- layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
-
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bgLayer, Color::RED, 32, 32));
-
- {
- SCOPED_TRACE("before alpha");
- screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
- }
-
- // setting alpha without creating color layer should have no effect
- Transaction().setFrame(layer, Rect(0, 0, 32, 32)).setAlpha(layer, 0.5f).apply();
- {
- SCOPED_TRACE("alpha");
- auto shot = screenshot();
- shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
- shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
- }
-}
-
void LayerRenderTypeTransactionTest::setAlphaBasicHelper(uint32_t layerType) {
sp<SurfaceControl> layer1;
sp<SurfaceControl> layer2;
@@ -1567,75 +1483,190 @@
}
}
-TEST_P(LayerRenderTypeTransactionTest, SetBackgroundColor_BufferState_NoPriorColor) {
- sp<SurfaceControl> bufferQueueLayer;
- sp<SurfaceControl> bufferStateLayer;
- ASSERT_NO_FATAL_FAILURE(bufferQueueLayer = createLayer("test bg", 32, 32));
- ASSERT_NO_FATAL_FAILURE(
- bufferStateLayer =
- createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+// RED: Color layer base color and BufferQueueLayer/BufferStateLayer fill
+// BLUE: prior background color
+// GREEN: final background color
+// BLACK: no color or fill
+void LayerRenderTypeTransactionTest::setBackgroundColorHelper(uint32_t layerType, bool priorColor,
+ bool bufferFill, float alpha,
+ Color finalColor) {
+ sp<SurfaceControl> layer;
+ int32_t width = 500;
+ int32_t height = 500;
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferQueueLayer, Color::RED, 32, 32));
-
- {
- SCOPED_TRACE("default color");
- screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
+ Color fillColor = Color::RED;
+ Color priorBgColor = Color::BLUE;
+ Color expectedColor = Color::BLACK;
+ switch (layerType) {
+ case ISurfaceComposerClient::eFXSurfaceColor:
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 0, 0, layerType));
+ Transaction()
+ .setCrop_legacy(layer, Rect(0, 0, width, height))
+ .setColor(layer, half3(1.0f, 0, 0))
+ .apply();
+ expectedColor = fillColor;
+ break;
+ case ISurfaceComposerClient::eFXSurfaceBufferQueue:
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height));
+ if (bufferFill) {
+ ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, fillColor, width, height));
+ expectedColor = fillColor;
+ }
+ Transaction().setCrop_legacy(layer, Rect(0, 0, width, height)).apply();
+ break;
+ case ISurfaceComposerClient::eFXSurfaceBufferState:
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height, layerType));
+ if (bufferFill) {
+ ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, fillColor, width, height));
+ expectedColor = fillColor;
+ }
+ Transaction().setFrame(layer, Rect(0, 0, width, height)).apply();
+ break;
+ default:
+ GTEST_FAIL() << "Unknown layer type in setBackgroundColorHelper";
+ return;
}
- half3 color;
- color.r = 0.0f;
- color.g = 1.0f;
- color.b = 0.0f;
+ if (priorColor && layerType != ISurfaceComposerClient::eFXSurfaceColor) {
+ Transaction()
+ .setBackgroundColor(layer, half3(0, 0, 1.0f), 1.0f, ui::Dataspace::UNKNOWN)
+ .apply();
+ if (!bufferFill) {
+ expectedColor = priorBgColor;
+ }
+ }
+
+ {
+ SCOPED_TRACE("default before setting background color layer");
+ screenshot()->expectColor(Rect(0, 0, width, height), expectedColor);
+ }
+
Transaction()
- .setFrame(bufferStateLayer, Rect(0, 0, 32, 32))
- .setLayer(bufferStateLayer, mLayerZBase + 1)
- .setColor(bufferStateLayer, color)
+ .setBackgroundColor(layer, half3(0, 1.0f, 0), alpha, ui::Dataspace::UNKNOWN)
.apply();
{
- SCOPED_TRACE("set color");
auto shot = screenshot();
- shot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
- shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+ shot->expectColor(Rect(0, 0, width, height), finalColor);
+ shot->expectBorder(Rect(0, 0, width, height), Color::BLACK);
}
}
-TEST_P(LayerRenderTypeTransactionTest, SetBackgroundColor_BufferState_PriorColor) {
- sp<SurfaceControl> bufferQueueLayer;
- sp<SurfaceControl> bufferStateLayer;
- ASSERT_NO_FATAL_FAILURE(bufferQueueLayer = createLayer("test bg", 32, 32));
- ASSERT_NO_FATAL_FAILURE(
- bufferStateLayer =
- createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+TEST_P(LayerRenderTypeTransactionTest, SetBackgroundColor_Color_NoEffect) {
+ bool priorColor = false;
+ bool bufferFill = false;
+ float alpha = 1.0f;
+ Color finalColor = Color::RED;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceColor,
+ priorColor, bufferFill, alpha, finalColor));
+}
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferQueueLayer, Color::RED, 32, 32));
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferQueue_BufferFill_NoPriorColor_Basic) {
+ bool priorColor = false;
+ bool bufferFill = true;
+ float alpha = 1.0f;
+ Color finalColor = Color::RED;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
- half3 color;
- color.r = 0.0f;
- color.g = 1.0f;
- color.b = 0.0f;
- Transaction()
- .setFrame(bufferStateLayer, Rect(0, 0, 32, 32))
- .setLayer(bufferStateLayer, mLayerZBase + 1)
- .setColor(bufferStateLayer, color)
- .apply();
- {
- SCOPED_TRACE("default color");
- auto shot = screenshot();
- shot->expectColor(Rect(0, 0, 32, 32), Color::GREEN);
- shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
- }
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferQueue_NoBufferFill_NoPriorColor_Basic) {
+ bool priorColor = false;
+ bool bufferFill = false;
+ float alpha = 1.0f;
+ Color finalColor = Color::GREEN;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
- color.r = 0.0f;
- color.g = 0.0f;
- color.b = 1.0f;
- Transaction().setColor(bufferStateLayer, color).apply();
- {
- SCOPED_TRACE("new color");
- auto shot = screenshot();
- shot->expectColor(Rect(0, 0, 32, 32), Color::BLUE);
- shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
- }
+TEST_P(LayerRenderTypeTransactionTest, SetBackgroundColor_BufferQueue_BufferFill_PriorColor_Basic) {
+ bool priorColor = true;
+ bool bufferFill = true;
+ float alpha = 1.0f;
+ Color finalColor = Color::RED;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
+
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferQueue_NoBufferFill_PriorColor_Basic) {
+ bool priorColor = true;
+ bool bufferFill = false;
+ float alpha = 1.0f;
+ Color finalColor = Color::GREEN;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferQueue_NoPriorColor_ZeroAlpha_NoEffect) {
+ bool priorColor = false;
+ bool bufferFill = false;
+ float alpha = 0;
+ Color finalColor = Color::BLACK;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
+
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferQueue_PriorColor_ZeroAlpha_DeleteBackground) {
+ bool priorColor = true;
+ bool bufferFill = false;
+ float alpha = 0;
+ Color finalColor = Color::BLACK;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
+
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferState_BufferFill_NoPriorColor_Basic) {
+ bool priorColor = false;
+ bool bufferFill = true;
+ float alpha = 1.0f;
+ Color finalColor = Color::RED;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
+
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferState_NoBufferFill_NoPriorColor_Basic) {
+ bool priorColor = false;
+ bool bufferFill = false;
+ float alpha = 1.0f;
+ Color finalColor = Color::GREEN;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
+
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferState_NoBufferFill_PriorColor_Basic) {
+ bool priorColor = true;
+ bool bufferFill = false;
+ float alpha = 1.0f;
+ Color finalColor = Color::GREEN;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
+
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferState_NoPriorColor_ZeroAlpha_NoEffect) {
+ bool priorColor = false;
+ bool bufferFill = false;
+ float alpha = 0;
+ Color finalColor = Color::BLACK;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
+}
+
+TEST_P(LayerRenderTypeTransactionTest,
+ SetBackgroundColor_BufferState_PriorColor_ZeroAlpha_DeleteBackground) {
+ bool priorColor = true;
+ bool bufferFill = false;
+ float alpha = 0;
+ Color finalColor = Color::BLACK;
+ ASSERT_NO_FATAL_FAILURE(setBackgroundColorHelper(ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ priorColor, bufferFill, alpha, finalColor));
}
TEST_P(LayerRenderTypeTransactionTest, SetColorClamped) {
@@ -2491,71 +2522,6 @@
shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
}
-TEST_P(LayerRenderTypeTransactionTest, SetColorDataspace_ColorLayer_NoEffect) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(
- layer = createLayer("test", 0, 0, ISurfaceComposerClient::eFXSurfaceColor));
- half3 color;
- color.r = 1.0f;
- color.g = 0.0f;
- color.b = 0.0f;
- Transaction()
- .setCrop_legacy(layer, Rect(0, 0, 32, 32))
- .setColor(layer, color)
- .setDataspace(layer, ui::Dataspace::UNKNOWN)
- .setColorDataspace(layer, ui::Dataspace::BT2020_ITU)
- .apply();
-
- screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
-}
-
-TEST_P(LayerRenderTypeTransactionTest, SetColorDataspace_BufferQueue_NoEffect) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
-
- Transaction()
- .setDataspace(layer, ui::Dataspace::UNKNOWN)
- .setColorDataspace(layer, ui::Dataspace::BT2020_ITU)
- .apply();
-
- screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
-}
-
-TEST_P(LayerRenderTypeTransactionTest, SetColorDataspace_BufferState_ColorLayer) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(
- layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
-
- half3 color;
- color.r = 1.0f;
- color.g = 0.0f;
- color.b = 0.0f;
- Transaction()
- .setFrame(layer, Rect(0, 0, 32, 32))
- .setColor(layer, color)
- .setColorDataspace(layer, ui::Dataspace::BT2020_ITU)
- .apply();
- auto shot = screenshot();
- shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
- shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
-}
-
-TEST_P(LayerRenderTypeTransactionTest, SetColorDataspace_BufferState_NoColorLayer) {
- sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(
- layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
-
- Transaction()
- .setFrame(layer, Rect(0, 0, 32, 32))
- .setDataspace(layer, ui::Dataspace::UNKNOWN)
- .setColorDataspace(layer, ui::Dataspace::DCI_P3)
- .apply();
-
- screenshot()->expectColor(Rect(0, 0, 32, 32), Color::RED);
-}
-
TEST_P(LayerRenderTypeTransactionTest, SetDataspaceBasic_BufferState) {
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(