SF: Use compositionInfo after HWC changedTypes
Bug: 112259502
Test: cts -m CtsViewTestCases
SurfaceFlinger_test
vrflinger_test
Change-Id: I908f439eedfab9ee8241f8ac594465527f93408a
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index d0ccabb..44305df 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -138,8 +138,6 @@
bool useIdentityTransform) {
ATRACE_CALL();
- CompositionInfo& compositionInfo = getBE().compositionInfo;
-
if (CC_UNLIKELY(mActiveBuffer == 0)) {
// the texture has not been created yet, this Layer has
// in fact never been drawn into. This happens frequently with
@@ -221,7 +219,6 @@
mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
mTexture.setFiltering(useFiltering);
mTexture.setMatrix(textureMatrix);
- compositionInfo.re.texture = mTexture;
engine.setupLayerTexturing(mTexture);
} else {
@@ -231,23 +228,6 @@
engine.disableTexturing();
}
-void BufferLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) {
- CompositionInfo& compositionInfo = getBE().compositionInfo;
- auto& engine(mFlinger->getRenderEngine());
-
- draw(renderArea, useIdentityTransform);
-
- engine.setupLayerTexturing(compositionInfo.re.texture);
- engine.setupLayerBlending(compositionInfo.re.preMultipliedAlpha, compositionInfo.re.opaque,
- false, compositionInfo.re.color);
- engine.setSourceDataSpace(compositionInfo.hwc.dataspace);
- engine.setSourceY410BT2020(compositionInfo.re.Y410BT2020);
- engine.drawMesh(getBE().getMesh());
- engine.disableBlending();
- engine.disableTexturing();
- engine.setSourceY410BT2020(false);
-}
-
bool BufferLayer::isHdrY410() const {
// pixel format is HDR Y410 masquerading as RGBA_1010102
return (mCurrentDataSpace == ui::Dataspace::BT2020_ITU_PQ &&
@@ -340,6 +320,7 @@
bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
const std::shared_ptr<FenceTime>& presentFence,
const CompositorTiming& compositorTiming) {
+
// mFrameLatencyNeeded is true when a new frame was latched for the
// composition.
if (!mFrameLatencyNeeded) return false;
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 3319a98..3d06ded 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -77,7 +77,6 @@
// onDraw - draws the surface.
void onDraw(const RenderArea& renderArea, const Region& clip,
bool useIdentityTransform) override;
- void drawNow(const RenderArea& renderArea, bool useIdentityTransform);
bool isHdrY410() const override;
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index c29698b..24e3d94 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -45,27 +45,17 @@
bool useIdentityTransform) {
half4 color = getColor();
if (color.a > 0) {
- computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
- getBE().compositionInfo.re.preMultipliedAlpha = getPremultipledAlpha();
- getBE().compositionInfo.re.opaque = false;
- getBE().compositionInfo.re.disableTexture = true;
- getBE().compositionInfo.re.color = color;
+ Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
+ computeGeometry(renderArea, mesh, useIdentityTransform);
+ auto& engine(mFlinger->getRenderEngine());
+ engine.setupLayerBlending(getPremultipledAlpha(), false /* opaque */,
+ true /* disableTexture */, color);
+ engine.setSourceDataSpace(mCurrentDataSpace);
+ engine.drawMesh(mesh);
+ engine.disableBlending();
}
}
-void ColorLayer::drawNow(const RenderArea& renderArea, bool useIdentityTransform) {
- CompositionInfo& compositionInfo = getBE().compositionInfo;
- auto& engine(mFlinger->getRenderEngine());
-
- draw(renderArea, useIdentityTransform);
-
- engine.setupLayerBlending(compositionInfo.re.preMultipliedAlpha, compositionInfo.re.opaque,
- compositionInfo.re.disableTexture, compositionInfo.re.color);
- engine.setSourceDataSpace(compositionInfo.hwc.dataspace);
- engine.drawMesh(getBE().getMesh());
- engine.disableBlending();
-}
-
bool ColorLayer::isVisible() const {
return !isHiddenByPolicy() && getAlpha() > 0.0f;
}
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 429ad79..aa6b049 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -32,7 +32,6 @@
virtual const char* getTypeId() const { return "ColorLayer"; }
virtual void onDraw(const RenderArea& renderArea, const Region& clip,
bool useIdentityTransform);
- void drawNow(const RenderArea&, bool);
bool isVisible() const override;
void setPerFrameData(const sp<const DisplayDevice>& display) override;
diff --git a/services/surfaceflinger/ContainerLayer.cpp b/services/surfaceflinger/ContainerLayer.cpp
index 5ad5d56..e9f3059 100644
--- a/services/surfaceflinger/ContainerLayer.cpp
+++ b/services/surfaceflinger/ContainerLayer.cpp
@@ -30,8 +30,6 @@
void ContainerLayer::onDraw(const RenderArea&, const Region& /* clip */, bool) {}
-void ContainerLayer::drawNow(const RenderArea&, bool) {}
-
bool ContainerLayer::isVisible() const {
return !isHiddenByPolicy();
}
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 051e765..0b4a181 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -32,7 +32,6 @@
const char* getTypeId() const override { return "ContainerLayer"; }
void onDraw(const RenderArea& renderArea, const Region& clip,
bool useIdentityTransform) override;
- void drawNow(const RenderArea& renderArea, bool useIdentityTransform) override;
bool isVisible() const override;
void setPerFrameData(const sp<const DisplayDevice>& display) override;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 0fbd459..aab6c22 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -334,8 +334,9 @@
return mDisplaySurface->beginFrame(mustRecompose);
}
-status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
- status_t error = hwc.prepare(*this);
+status_t DisplayDevice::prepareFrame(HWComposer& hwc,
+ std::vector<CompositionInfo>& compositionData) {
+ status_t error = hwc.prepare(*this, compositionData);
if (error != NO_ERROR) {
return error;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index da0931e..0ce56fe 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -50,6 +50,7 @@
class Layer;
class SurfaceFlinger;
class HWComposer;
+struct CompositionInfo;
class DisplayDevice : public LightRefBase<DisplayDevice>
{
@@ -142,7 +143,7 @@
// We pass in mustRecompose so we can keep VirtualDisplaySurface's state
// machine happy without actually queueing a buffer if nothing has changed
status_t beginFrame(bool mustRecompose) const;
- status_t prepareFrame(HWComposer& hwc);
+ status_t prepareFrame(HWComposer& hwc, std::vector<CompositionInfo>& compositionInfo);
bool hasWideColorGamut() const { return mHasWideColorGamut; }
// Whether h/w composer has native support for specific HDR type.
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 630cc0b..873de25 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -417,7 +417,8 @@
return NO_ERROR;
}
-status_t HWComposer::prepare(DisplayDevice& display) {
+status_t HWComposer::prepare(DisplayDevice& display,
+ std::vector<CompositionInfo>& compositionData) {
ATRACE_CALL();
Mutex::Autolock _l(mDisplayLock);
@@ -488,18 +489,19 @@
displayData.hasClientComposition = false;
displayData.hasDeviceComposition = false;
- for (auto& layer : display.getVisibleLayersSortedByZ()) {
- auto hwcLayer = layer->getHwcLayer(displayId);
+ for (auto& compositionInfo : compositionData) {
+ auto hwcLayer = compositionInfo.hwc.hwcLayer;
- if (changedTypes.count(hwcLayer) != 0) {
+ if (changedTypes.count(&*hwcLayer) != 0) {
// We pass false so we only update our state and don't call back
// into the HWC device
- validateChange(layer->getCompositionType(displayId),
- changedTypes[hwcLayer]);
- layer->setCompositionType(displayId, changedTypes[hwcLayer], false);
+ validateChange(compositionInfo.compositionType,
+ changedTypes[&*hwcLayer]);
+ compositionInfo.compositionType = changedTypes[&*hwcLayer];
+ compositionInfo.layer->mLayer->setCompositionType(displayId, compositionInfo.compositionType, false);
}
- switch (layer->getCompositionType(displayId)) {
+ switch (compositionInfo.compositionType) {
case HWC2::Composition::Client:
displayData.hasClientComposition = true;
break;
@@ -513,17 +515,17 @@
break;
}
- if (layerRequests.count(hwcLayer) != 0 &&
- layerRequests[hwcLayer] ==
+ if (layerRequests.count(&*hwcLayer) != 0 &&
+ layerRequests[&*hwcLayer] ==
HWC2::LayerRequest::ClearClientTarget) {
- layer->setClearClientTarget(displayId, true);
+ compositionInfo.hwc.clearClientTarget = true;
} else {
- if (layerRequests.count(hwcLayer) != 0) {
+ if (layerRequests.count(&*hwcLayer) != 0) {
LOG_DISPLAY_ERROR(displayId,
- ("Unknown layer request " + to_string(layerRequests[hwcLayer]))
+ ("Unknown layer request " + to_string(layerRequests[&*hwcLayer]))
.c_str());
}
- layer->setClearClientTarget(displayId, false);
+ compositionInfo.hwc.clearClientTarget = false;
}
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 9e01626..cca1f3b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -61,6 +61,7 @@
class Region;
class String8;
class TestableSurfaceFlinger;
+struct CompositionInfo;
namespace Hwc2 {
class Composer;
@@ -92,7 +93,8 @@
void destroyLayer(int32_t displayId, HWC2::Layer* layer);
// Asks the HAL what it can do
- status_t prepare(DisplayDevice& display);
+ status_t prepare(DisplayDevice& display,
+ std::vector<CompositionInfo>& compositionData);
status_t setClientTarget(int32_t displayId, uint32_t slot,
const sp<Fence>& acquireFence,
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 443f410..604ec65 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -76,6 +76,7 @@
static int32_t sSequence;
public:
+ friend class LayerBE;
LayerBE& getBE() { return mBE; }
LayerBE& getBE() const { return mBE; }
mutable bool contentDirty;
@@ -415,16 +416,6 @@
void draw(const RenderArea& renderArea);
/*
- * drawNow uses the renderEngine to draw the layer. This is different than the
- * draw function as with the FE/BE split, the draw function runs in the FE and
- * sets up state for the BE to do the actual drawing. drawNow is used to tell
- * the layer to skip the state setup and just go ahead and draw the layer. This
- * is used for screen captures which happens separately from the frame
- * compositing path.
- */
- virtual void drawNow(const RenderArea& renderArea, bool useIdentityTransform) = 0;
-
- /*
* doTransaction - process the transaction. This is a good place to figure
* out which attributes of the surface have changed.
*/
diff --git a/services/surfaceflinger/LayerBE.cpp b/services/surfaceflinger/LayerBE.cpp
index 3e04f26..9c6534e 100644
--- a/services/surfaceflinger/LayerBE.cpp
+++ b/services/surfaceflinger/LayerBE.cpp
@@ -46,6 +46,11 @@
mLayer->onLayerDisplayed(releaseFence);
}
+void LayerBE::clear(RE::RenderEngine& engine) {
+ engine.setupFillWithColor(0, 0, 0, 0);
+ engine.drawMesh(mMesh);
+}
+
void CompositionInfo::dump(const char* tag) const
{
std::string logString;
@@ -89,22 +94,12 @@
result += base::StringPrintf("[%s]RenderEngine parameters:\n", tag);
}
- Mesh& mesh = layer->getMesh();
result += base::StringPrintf("\tblackoutLayer=%d\n", re.blackoutLayer);
result += base::StringPrintf("\tclearArea=%d\n", re.clearArea);
result += base::StringPrintf("\tpreMultipliedAlpha=%d\n", re.preMultipliedAlpha);
result += base::StringPrintf("\topaque=%d\n", re.opaque);
result += base::StringPrintf("\tdisableTexture=%d\n", re.disableTexture);
- result += base::StringPrintf("\ttexture:name(%d), target(%d), size(%d/%d)\n", re.texture.getTextureName(), re.texture.getTextureTarget(), (unsigned int)re.texture.getWidth(), (unsigned int)re.texture.getHeight());
result += base::StringPrintf("\tuseIdentityTransform=%d\n", re.useIdentityTransform);
- Mesh::VertexArray<vec2> positions(mesh.getPositionArray<vec2>());
- result += base::StringPrintf("\tpositions[(%6.1f,%6.1f), (%6.1f,%6.1f), (%6.1f,%6.1f), (%6.1f,%6.1f)]\n",
- positions[0][0], positions[0][1], positions[1][0], positions[1][1],
- positions[2][0], positions[2][1], positions[3][0], positions[3][1]);
- Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>());
- result += base::StringPrintf("\ttexCoords[(%6.1f,%6.1f), (%6.1f,%6.1f),(%6.1f,%6.1f),(%6.1f,%6.1f)]\n",
- texCoords[0][0], texCoords[0][1], texCoords[1][0], texCoords[1][1],
- texCoords[2][0], texCoords[2][1], texCoords[3][0], texCoords[3][1]);
}
void CompositionInfo::dump(std::string& result, const char* tag) const
@@ -134,6 +129,4 @@
}
}
-
-
}; // namespace android
diff --git a/services/surfaceflinger/LayerBE.h b/services/surfaceflinger/LayerBE.h
index e5110b7..21e7b5c 100644
--- a/services/surfaceflinger/LayerBE.h
+++ b/services/surfaceflinger/LayerBE.h
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <renderengine/Mesh.h>
+#include <renderengine/RenderEngine.h>
#include <renderengine/Texture.h>
#include <ui/Region.h>
@@ -34,6 +35,7 @@
struct CompositionInfo {
std::string layerName;
HWC2::Composition compositionType;
+ bool firstClear = false;
sp<GraphicBuffer> mBuffer = nullptr;
int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
std::shared_ptr<LayerBE> layer;
@@ -59,14 +61,12 @@
HdrMetadata hdrMetadata;
} hwc;
struct {
- Mesh* mesh;
bool blackoutLayer = false;
bool clearArea = false;
bool preMultipliedAlpha = false;
bool opaque = false;
bool disableTexture = false;
half4 color;
- Texture texture;
bool useIdentityTransform = false;
bool Y410BT2020 = false;
} re;
@@ -90,10 +90,11 @@
explicit LayerBE(const LayerBE& layer);
void onLayerDisplayed(const sp<Fence>& releaseFence);
+ void clear(RE::RenderEngine& renderEngine);
Mesh& getMesh() { return mMesh; }
-private:
Layer*const mLayer;
+private:
// 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 37d0146..e4b7cb4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1594,6 +1594,7 @@
void SurfaceFlinger::doDebugFlashRegions(const sp<DisplayDevice>& display, bool repaintEverything)
{
+ const auto displayId = display->getId();
// is debugging enabled
if (CC_LIKELY(!mDebugRegion))
return;
@@ -1621,7 +1622,8 @@
}
if (display->isPoweredOn()) {
- status_t result = display->prepareFrame(*getBE().mHwc);
+ status_t result = display->prepareFrame(
+ *getBE().mHwc, getBE().mCompositionInfo[displayId]);
ALOGE_IF(result != NO_ERROR,
"prepareFrame for display %d failed:"
" %d (%s)",
@@ -2020,11 +2022,13 @@
void SurfaceFlinger::prepareFrame(const sp<DisplayDevice>& display)
{
+ const auto displayId = display->getId();
if (!display->isPoweredOn()) {
return;
}
- status_t result = display->prepareFrame(*getBE().mHwc);
+ status_t result = display->prepareFrame(
+ *getBE().mHwc, getBE().mCompositionInfo[displayId]);
ALOGE_IF(result != NO_ERROR,
"prepareFrame for display %d failed:"
" %d (%s)",
@@ -2952,29 +2956,29 @@
ALOGV("Rendering client layers");
const ui::Transform& displayTransform = display->getTransform();
bool firstLayer = true;
- for (auto& layer : display->getVisibleLayersSortedByZ()) {
+ for (auto& compositionInfo : getBE().mCompositionInfo[displayId]) {
+ const Region bounds(display->bounds());
const Region clip(bounds.intersect(
- displayTransform.transform(layer->visibleRegion)));
- ALOGV("Layer: %s", layer->getName().string());
- ALOGV(" Composition type: %s", to_string(layer->getCompositionType(displayId)).c_str());
+ displayTransform.transform(compositionInfo.layer->mLayer->visibleRegion)));
+ ALOGV("Layer: %s", compositionInfo.layerName.c_str());
if (!clip.isEmpty()) {
- switch (layer->getCompositionType(displayId)) {
+ switch (compositionInfo.compositionType) {
case HWC2::Composition::Cursor:
case HWC2::Composition::Device:
case HWC2::Composition::Sideband:
case HWC2::Composition::SolidColor: {
- const Layer::State& state(layer->getDrawingState());
- if (layer->getClearClientTarget(displayId) && !firstLayer &&
- layer->isOpaque(state) && (layer->getAlpha() == 1.0f) &&
- hasClientComposition) {
+ const Layer::State& state(compositionInfo.layer->mLayer->getDrawingState());
+ const bool opaque = compositionInfo.layer->mLayer->isOpaque(state);
+ if (compositionInfo.hwc.clearClientTarget && !firstLayer &&
+ opaque && (state.color.a == 1.0f) && hasClientComposition) {
// never clear the very first layer since we're
// guaranteed the FB is already cleared
- layer->clearWithOpenGL(renderArea);
+ compositionInfo.layer->mLayer->clearWithOpenGL(renderArea);
}
break;
}
case HWC2::Composition::Client: {
- layer->draw(renderArea, clip);
+ compositionInfo.layer->mLayer->draw(renderArea, clip);
break;
}
default:
@@ -5222,7 +5226,7 @@
traverseLayers([&](Layer* layer) {
if (filtering) layer->setFiltering(true);
- layer->drawNow(renderArea, useIdentityTransform);
+ layer->draw(renderArea, useIdentityTransform);
if (filtering) layer->setFiltering(false);
});
}