SF: Use CompositionInfo to program HWComposer
Bug: 112259502
Test: cts -m CtsViewTestCases
SurfaceFlinger_test
vrflinger_test
Change-Id: Ib0fea4e325473e552efbf4d974661d795d302244
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 44305df..1bb7a85 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -242,65 +242,27 @@
const auto& viewport = display->getViewport();
Region visible = tr.transform(visibleRegion.intersect(viewport));
const auto displayId = display->getId();
- if (!hasHwcLayer(displayId)) {
- ALOGE("[%s] failed to setPerFrameData: no HWC layer found (%d)",
- mName.string(), displayId);
- return;
- }
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
- auto error = hwcLayer->setVisibleRegion(visible);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- visible.dump(LOG_TAG);
- }
getBE().compositionInfo.hwc.visibleRegion = visible;
-
- error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- surfaceDamageRegion.dump(LOG_TAG);
- }
getBE().compositionInfo.hwc.surfaceDamage = surfaceDamageRegion;
// Sideband layers
if (getBE().compositionInfo.hwc.sidebandStream.get()) {
setCompositionType(displayId, HWC2::Composition::Sideband);
- ALOGV("[%s] Requesting Sideband composition", mName.string());
- error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
- getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
- static_cast<int32_t>(error));
- }
getBE().compositionInfo.compositionType = HWC2::Composition::Sideband;
return;
}
- // Device or Cursor layers
- if (mPotentialCursor) {
- ALOGV("[%s] Requesting Cursor composition", mName.string());
- setCompositionType(displayId, HWC2::Composition::Cursor);
- } else {
- ALOGV("[%s] Requesting Device composition", mName.string());
- setCompositionType(displayId, HWC2::Composition::Device);
+ if (getBE().compositionInfo.hwc.skipGeometry) {
+ // Device or Cursor layers
+ if (mPotentialCursor) {
+ ALOGV("[%s] Requesting Cursor composition", mName.string());
+ setCompositionType(displayId, HWC2::Composition::Cursor);
+ } else {
+ ALOGV("[%s] Requesting Device composition", mName.string());
+ setCompositionType(displayId, HWC2::Composition::Device);
+ }
}
- ALOGV("setPerFrameData: dataspace = %d", mCurrentDataSpace);
- error = hwcLayer->setDataspace(mCurrentDataSpace);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace,
- to_string(error).c_str(), static_cast<int32_t>(error));
- }
-
- const HdrMetadata& metadata = getDrawingHdrMetadata();
- error = hwcLayer->setPerFrameMetadata(display->getSupportedPerFrameMetadata(), metadata);
- if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
- ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- }
getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
getBE().compositionInfo.hwc.hdrMetadata = getDrawingHdrMetadata();
getBE().compositionInfo.hwc.supportedPerFrameMetadata = display->getSupportedPerFrameMetadata();
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index dc908d2..10974b4 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -337,22 +337,8 @@
return NO_ERROR;
}
-void BufferQueueLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) {
- const auto displayId = display->getId();
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
-
- uint32_t hwcSlot = 0;
- sp<GraphicBuffer> hwcBuffer;
- hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer);
-
+void BufferQueueLayer::setHwcLayerBuffer(const sp<const DisplayDevice>&) {
auto acquireFence = mConsumer->getCurrentFence();
- auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
- getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
- static_cast<int32_t>(error));
- }
getBE().compositionInfo.mBufferSlot = mActiveBufferSlot;
getBE().compositionInfo.mBuffer = mActiveBuffer;
getBE().compositionInfo.hwc.fence = acquireFence;
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 24e3d94..acadfa0 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -65,48 +65,18 @@
const auto& viewport = display->getViewport();
Region visible = tr.transform(visibleRegion.intersect(viewport));
const auto displayId = display->getId();
- if (!hasHwcLayer(displayId)) {
- ALOGE("[%s] failed to setPerFrameData: no HWC layer found (%d)",
- mName.string(), displayId);
- return;
- }
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
- auto error = hwcLayer->setVisibleRegion(visible);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- visible.dump(LOG_TAG);
- }
getBE().compositionInfo.hwc.visibleRegion = visible;
+ getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
setCompositionType(displayId, HWC2::Composition::SolidColor);
-
- error = hwcLayer->setDataspace(mCurrentDataSpace);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentDataSpace,
- to_string(error).c_str(), static_cast<int32_t>(error));
- }
getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
half4 color = getColor();
- error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
- static_cast<uint8_t>(std::round(255.0f * color.g)),
- static_cast<uint8_t>(std::round(255.0f * color.b)), 255});
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(),
- static_cast<int32_t>(error));
- }
getBE().compositionInfo.hwc.color = { static_cast<uint8_t>(std::round(255.0f * color.r)),
static_cast<uint8_t>(std::round(255.0f * color.g)),
static_cast<uint8_t>(std::round(255.0f * color.b)), 255 };
// Clear out the transform, because it doesn't make sense absent a source buffer
- error = hwcLayer->setTransform(HWC2::Transform::None);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(),
- static_cast<int32_t>(error));
- }
getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 873de25..2c94a0e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -498,7 +498,6 @@
validateChange(compositionInfo.compositionType,
changedTypes[&*hwcLayer]);
compositionInfo.compositionType = changedTypes[&*hwcLayer];
- compositionInfo.layer->mLayer->setCompositionType(displayId, compositionInfo.compositionType, false);
}
switch (compositionInfo.compositionType) {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4f0b212..58503c5 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -494,6 +494,18 @@
}
auto& hwcInfo = getBE().mHwcLayers[displayId];
+ // Device or Cursor layers
+ if (mPotentialCursor) {
+ ALOGV("[%s] Requesting Cursor composition", mName.string());
+ setCompositionType(displayId, HWC2::Composition::Cursor);
+ } else {
+ ALOGV("[%s] Requesting Device composition", mName.string());
+ setCompositionType(displayId, HWC2::Composition::Device);
+ }
+
+ // Need to program geometry parts
+ getBE().compositionInfo.hwc.skipGeometry = false;
+
// enable this layer
hwcInfo.forceClientComposition = false;
@@ -501,8 +513,6 @@
hwcInfo.forceClientComposition = true;
}
- auto& hwcLayer = hwcInfo.layer;
-
// this gives us only the "orientation" component of the transform
const State& s(getDrawingState());
auto blendMode = HWC2::BlendMode::None;
@@ -510,12 +520,6 @@
blendMode =
mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
}
- auto error = hwcLayer->setBlendMode(blendMode);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set blend mode %s:"
- " %s (%d)",
- mName.string(), to_string(blendMode).c_str(), to_string(error).c_str(),
- static_cast<int32_t>(error));
getBE().compositionInfo.hwc.blendMode = blendMode;
// apply the layer's transform, followed by the display's global transform
@@ -561,39 +565,14 @@
}
const ui::Transform& tr = display->getTransform();
Rect transformedFrame = tr.transform(frame);
- error = hwcLayer->setDisplayFrame(transformedFrame);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)", mName.string(),
- transformedFrame.left, transformedFrame.top, transformedFrame.right,
- transformedFrame.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
- } else {
- hwcInfo.displayFrame = transformedFrame;
- }
getBE().compositionInfo.hwc.displayFrame = transformedFrame;
FloatRect sourceCrop = computeCrop(display);
- error = hwcLayer->setSourceCrop(sourceCrop);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
- "%s (%d)",
- mName.string(), sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom,
- to_string(error).c_str(), static_cast<int32_t>(error));
- } else {
- hwcInfo.sourceCrop = sourceCrop;
- }
getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
float alpha = static_cast<float>(getAlpha());
- error = hwcLayer->setPlaneAlpha(alpha);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set plane alpha %.3f: "
- "%s (%d)",
- mName.string(), alpha, to_string(error).c_str(), static_cast<int32_t>(error));
getBE().compositionInfo.hwc.alpha = alpha;
- error = hwcLayer->setZOrder(z);
- ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z,
- to_string(error).c_str(), static_cast<int32_t>(error));
getBE().compositionInfo.hwc.z = z;
int type = s.type;
@@ -607,10 +586,6 @@
}
}
- error = hwcLayer->setInfo(type, appId);
- ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", mName.string(),
- static_cast<int32_t>(error));
-
getBE().compositionInfo.hwc.type = type;
getBE().compositionInfo.hwc.appId = appId;
@@ -650,16 +625,9 @@
if (orientation & ui::Transform::ROT_INVALID) {
// we can only handle simple transformation
hwcInfo.forceClientComposition = true;
- getBE().mHwcLayers[displayId].compositionType = HWC2::Composition::Client;
} else {
auto transform = static_cast<HWC2::Transform>(orientation);
hwcInfo.transform = transform;
- auto error = hwcLayer->setTransform(transform);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set transform %s: "
- "%s (%d)",
- mName.string(), to_string(transform).c_str(), to_string(error).c_str(),
- static_cast<int32_t>(error));
getBE().compositionInfo.hwc.transform = transform;
}
}
@@ -745,28 +713,20 @@
}
void Layer::clearWithOpenGL(const RenderArea& renderArea) const {
- clearWithOpenGL(renderArea, 0, 0, 0, 0);
+ getBE().compositionInfo.firstClear = true;
+ computeGeometry(renderArea, getBE().mMesh, false);
}
-void Layer::setCompositionType(int32_t displayId, HWC2::Composition type, bool callIntoHwc) {
+void Layer::setCompositionType(int32_t displayId, HWC2::Composition type, bool /*callIntoHwc*/) {
if (getBE().mHwcLayers.count(displayId) == 0) {
ALOGE("setCompositionType called without a valid HWC layer");
return;
- }
- auto& hwcInfo = getBE().mHwcLayers[displayId];
- auto& hwcLayer = hwcInfo.layer;
- ALOGV("setCompositionType(%" PRIx64 ", %s, %d)", (hwcLayer)->getId(), to_string(type).c_str(),
- static_cast<int>(callIntoHwc));
- if (hwcInfo.compositionType != type) {
- ALOGV(" actually setting");
- hwcInfo.compositionType = type;
- if (callIntoHwc) {
- auto error = (hwcLayer)->setCompositionType(type);
- ALOGE_IF(error != HWC2::Error::None,
- "[%s] Failed to set "
- "composition type %s: %s (%d)",
- mName.string(), to_string(type).c_str(), to_string(error).c_str(),
- static_cast<int32_t>(error));
+ } else {
+ if (getBE().mHwcLayers[displayId].compositionType != type) {
+ ALOGV("setCompositionType: Changing compositionType from %s to %s",
+ to_string(getBE().mHwcLayers[displayId].compositionType).c_str(),
+ to_string(type).c_str());
+ getBE().mHwcLayers[displayId].compositionType = type;
}
}
}
diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp
index 9c6534e..f389b57 100644
--- a/services/surfaceflinger/LayerBE.cpp
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -43,7 +43,9 @@
}
void LayerBE::onLayerDisplayed(const sp<Fence>& releaseFence) {
- mLayer->onLayerDisplayed(releaseFence);
+ if (mLayer) {
+ mLayer->onLayerDisplayed(releaseFence);
+ }
}
void LayerBE::clear(RE::RenderEngine& engine) {
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
index 21e7b5c..531cdcd 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -34,13 +34,14 @@
struct CompositionInfo {
std::string layerName;
- HWC2::Composition compositionType;
+ HWC2::Composition compositionType = HWC2::Composition::Invalid;
bool firstClear = false;
sp<GraphicBuffer> mBuffer = nullptr;
int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
std::shared_ptr<LayerBE> layer;
struct {
std::shared_ptr<HWC2::Layer> hwcLayer;
+ bool skipGeometry = true;
int32_t displayId = -1;
sp<Fence> fence;
HWC2::BlendMode blendMode = HWC2::BlendMode::Invalid;
@@ -93,8 +94,8 @@
void clear(RE::RenderEngine& renderEngine);
Mesh& getMesh() { return mMesh; }
- Layer*const mLayer;
private:
+ Layer*const mLayer;
// The mesh used to draw the layer in GLES composition mode
Mesh mMesh;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e4b7cb4..563ca5a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1461,8 +1461,13 @@
preComposition();
rebuildLayerStacks();
calculateWorkingSet();
+
for (const auto& [token, display] : mDisplays) {
+ const auto displayId = display->getId();
beginFrame(display);
+ for (auto& compositionInfo : getBE().mCompositionInfo[displayId]) {
+ setUpHWComposer(compositionInfo);
+ }
prepareFrame(display);
doDebugFlashRegions(display, repaintEverything);
doComposition(display, repaintEverything);
@@ -1990,6 +1995,125 @@
display->getBestColorMode(bestDataSpace, intent, outDataSpace, outMode, outRenderIntent);
}
+void SurfaceFlinger::configureSidebandComposition(const CompositionInfo& compositionInfo) const
+{
+ HWC2::Error error;
+ LOG_ALWAYS_FATAL_IF(compositionInfo.hwc.sidebandStream == nullptr,
+ "CompositionType is sideband, but sideband stream is nullptr");
+ error = (compositionInfo.hwc.hwcLayer)
+ ->setSidebandStream(compositionInfo.hwc.sidebandStream->handle());
+ if (error != HWC2::Error::None) {
+ ALOGE("[SF] Failed to set sideband stream %p: %s (%d)",
+ compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
+}
+
+void SurfaceFlinger::configureHwcCommonData(const CompositionInfo& compositionInfo) const
+{
+ HWC2::Error error;
+
+ if (!compositionInfo.hwc.skipGeometry) {
+ error = (compositionInfo.hwc.hwcLayer)->setBlendMode(compositionInfo.hwc.blendMode);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set blend mode %s:"
+ " %s (%d)",
+ to_string(compositionInfo.hwc.blendMode).c_str(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)->setDisplayFrame(compositionInfo.hwc.displayFrame);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set the display frame [%d, %d, %d, %d] %s (%d)",
+ compositionInfo.hwc.displayFrame.left,
+ compositionInfo.hwc.displayFrame.right,
+ compositionInfo.hwc.displayFrame.top,
+ compositionInfo.hwc.displayFrame.bottom,
+ to_string(error).c_str(), static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)->setSourceCrop(compositionInfo.hwc.sourceCrop);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: %s (%d)",
+ compositionInfo.hwc.sourceCrop.left,
+ compositionInfo.hwc.sourceCrop.right,
+ compositionInfo.hwc.sourceCrop.top,
+ compositionInfo.hwc.sourceCrop.bottom,
+ to_string(error).c_str(), static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)->setPlaneAlpha(compositionInfo.hwc.alpha);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set plane alpha %.3f: "
+ "%s (%d)",
+ compositionInfo.hwc.alpha,
+ to_string(error).c_str(), static_cast<int32_t>(error));
+
+
+ error = (compositionInfo.hwc.hwcLayer)->setZOrder(compositionInfo.hwc.z);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set Z %u: %s (%d)",
+ compositionInfo.hwc.z,
+ to_string(error).c_str(), static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)
+ ->setInfo(compositionInfo.hwc.type, compositionInfo.hwc.appId);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set info (%d)",
+ static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)->setTransform(compositionInfo.hwc.transform);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set transform %s: "
+ "%s (%d)",
+ to_string(compositionInfo.hwc.transform).c_str(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
+
+ error = (compositionInfo.hwc.hwcLayer)->setCompositionType(compositionInfo.compositionType);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set composition type: %s (%d)",
+ to_string(error).c_str(), static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)->setDataspace(compositionInfo.hwc.dataspace);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set dataspace: %s (%d)",
+ to_string(error).c_str(), static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)->setPerFrameMetadata(
+ compositionInfo.hwc.supportedPerFrameMetadata, compositionInfo.hwc.hdrMetadata);
+ ALOGE_IF(error != HWC2::Error::None && error != HWC2::Error::Unsupported,
+ "[SF] Failed to set hdrMetadata: %s (%d)",
+ to_string(error).c_str(), static_cast<int32_t>(error));
+
+ if (compositionInfo.compositionType == HWC2::Composition::SolidColor) {
+ error = (compositionInfo.hwc.hwcLayer)->setColor(compositionInfo.hwc.color);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set color: %s (%d)",
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+
+ error = (compositionInfo.hwc.hwcLayer)->setVisibleRegion(compositionInfo.hwc.visibleRegion);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set visible region: %s (%d)",
+ to_string(error).c_str(), static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)->setSurfaceDamage(compositionInfo.hwc.surfaceDamage);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set surface damage: %s (%d)",
+ to_string(error).c_str(), static_cast<int32_t>(error));
+}
+
+void SurfaceFlinger::configureDeviceComposition(const CompositionInfo& compositionInfo) const
+{
+ HWC2::Error error;
+
+ if (compositionInfo.hwc.fence) {
+ error = (compositionInfo.hwc.hwcLayer)->setBuffer(compositionInfo.mBufferSlot,
+ compositionInfo.mBuffer, compositionInfo.hwc.fence);
+ ALOGE_IF(error != HWC2::Error::None,
+ "[SF] Failed to set buffer: %s (%d)",
+ to_string(error).c_str(), static_cast<int32_t>(error));
+ }
+}
+
void SurfaceFlinger::beginFrame(const sp<DisplayDevice>& display)
{
bool dirty = !display->getDirtyRegion(false).isEmpty();
@@ -2035,6 +2159,33 @@
display->getId(), result, strerror(-result));
}
+void SurfaceFlinger::setUpHWComposer(const CompositionInfo& compositionInfo) {
+ ATRACE_CALL();
+ ALOGV("setUpHWComposer");
+
+ switch (compositionInfo.compositionType)
+ {
+ case HWC2::Composition::Invalid:
+ case HWC2::Composition::Client:
+ break;
+
+ case HWC2::Composition::Sideband:
+ configureHwcCommonData(compositionInfo);
+ configureSidebandComposition(compositionInfo);
+ break;
+
+ case HWC2::Composition::SolidColor:
+ configureHwcCommonData(compositionInfo);
+ break;
+
+ case HWC2::Composition::Device:
+ case HWC2::Composition::Cursor:
+ configureHwcCommonData(compositionInfo);
+ configureDeviceComposition(compositionInfo);
+ break;
+ }
+}
+
void SurfaceFlinger::doComposition(const sp<DisplayDevice>& display, bool repaintEverything) {
ATRACE_CALL();
ALOGV("doComposition");
@@ -2077,15 +2228,14 @@
}
display->onSwapBuffersCompleted();
display->makeCurrent();
- for (auto& layer : display->getVisibleLayersSortedByZ()) {
+ for (auto& compositionInfo : getBE().mCompositionInfo[displayId]) {
sp<Fence> releaseFence = Fence::NO_FENCE;
-
// The layer buffer from the previous frame (if any) is released
// by HWC only when the release fence from this frame (if any) is
// signaled. Always get the release fence from HWC first.
- auto hwcLayer = layer->getHwcLayer(displayId);
- if (displayId >= 0) {
- releaseFence = getBE().mHwc->getLayerReleaseFence(displayId, hwcLayer);
+ auto hwcLayer = compositionInfo.hwc.hwcLayer;
+ if ((displayId >= 0) && hwcLayer) {
+ releaseFence = getBE().mHwc->getLayerReleaseFence(displayId, hwcLayer.get());
}
// If the layer was client composited in the previous frame, we
@@ -2093,12 +2243,14 @@
// Since we do not track that, always merge with the current
// client target acquire fence when it is available, even though
// this is suboptimal.
- if (layer->getCompositionType(displayId) == HWC2::Composition::Client) {
+ if (compositionInfo.compositionType == HWC2::Composition::Client) {
releaseFence = Fence::merge("LayerRelease", releaseFence,
display->getClientTargetAcquireFence());
}
- layer->getBE().onLayerDisplayed(releaseFence);
+ if (compositionInfo.layer) {
+ compositionInfo.layer->onLayerDisplayed(releaseFence);
+ }
}
// We've got a list of layers needing fences, that are disjoint with
@@ -2973,7 +3125,7 @@
opaque && (state.color.a == 1.0f) && hasClientComposition) {
// never clear the very first layer since we're
// guaranteed the FB is already cleared
- compositionInfo.layer->mLayer->clearWithOpenGL(renderArea);
+ compositionInfo.layer->clear(getRenderEngine());
}
break;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ed9e212..3dbceae 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -684,6 +684,7 @@
* to prepare the hardware composer
*/
void prepareFrame(const sp<DisplayDevice>& display);
+ void setUpHWComposer(const CompositionInfo& compositionInfo);
void doComposition(const sp<DisplayDevice>& display, bool repainEverything);
void doDebugFlashRegions(const sp<DisplayDevice>& display, bool repaintEverything);
void doTracing(const char* where);
@@ -803,6 +804,11 @@
// access must be protected by mInvalidateLock
volatile int32_t mRepaintEverything;
+ // helper methods
+ void configureHwcCommonData(const CompositionInfo& compositionInfo) const;
+ void configureDeviceComposition(const CompositionInfo& compositionInfo) const;
+ void configureSidebandComposition(const CompositionInfo& compositionInfo) const;
+
// constant members (no synchronization needed for access)
nsecs_t mBootTime;
bool mGpuToCpuSupported;