Loading services/surfaceflinger/FrontEnd/LayerSnapshot.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -122,6 +122,8 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState { ReachableByRelativeParent ReachableByRelativeParent }; }; Reachablilty reachablilty; Reachablilty reachablilty; // True when the surfaceDamage is recognized as a small area update. bool isSmallDirty = false; static bool isOpaqueFormat(PixelFormat format); static bool isOpaqueFormat(PixelFormat format); static bool isTransformValid(const ui::Transform& t); static bool isTransformValid(const ui::Transform& t); Loading services/surfaceflinger/Layer.cpp +14 −3 Original line number Original line Diff line number Diff line Loading @@ -3364,7 +3364,7 @@ bool Layer::setSurfaceDamageRegion(const Region& surfaceDamage) { mDrawingState.surfaceDamageRegion = surfaceDamage; mDrawingState.surfaceDamageRegion = surfaceDamage; mDrawingState.modified = true; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); setTransactionFlags(eTransactionNeeded); setIsSmallDirty(); setIsSmallDirty(surfaceDamage, getTransform()); return true; return true; } } Loading Loading @@ -4411,7 +4411,9 @@ void Layer::updateLastLatchTime(nsecs_t latchTime) { mLastLatchTime = latchTime; mLastLatchTime = latchTime; } } void Layer::setIsSmallDirty() { void Layer::setIsSmallDirty(const Region& damageRegion, const ui::Transform& layerToDisplayTransform) { mSmallDirty = false; if (!mFlinger->mScheduler->supportSmallDirtyDetection()) { if (!mFlinger->mScheduler->supportSmallDirtyDetection()) { return; return; } } Loading @@ -4420,17 +4422,26 @@ void Layer::setIsSmallDirty() { mWindowType != WindowInfo::Type::BASE_APPLICATION) { mWindowType != WindowInfo::Type::BASE_APPLICATION) { return; return; } } Rect bounds = mDrawingState.surfaceDamageRegion.getBounds(); Rect bounds = damageRegion.getBounds(); if (!bounds.isValid()) { if (!bounds.isValid()) { return; return; } } // Transform to screen space. bounds = layerToDisplayTransform.transform(bounds); // If the damage region is a small dirty, this could give the hint for the layer history that // If the damage region is a small dirty, this could give the hint for the layer history that // it could suppress the heuristic rate when calculating. // it could suppress the heuristic rate when calculating. mSmallDirty = mFlinger->mScheduler->isSmallDirtyArea(mOwnerAppId, mSmallDirty = mFlinger->mScheduler->isSmallDirtyArea(mOwnerAppId, bounds.getWidth() * bounds.getHeight()); bounds.getWidth() * bounds.getHeight()); } } void Layer::setIsSmallDirty(frontend::LayerSnapshot* snapshot) { setIsSmallDirty(snapshot->surfaceDamage, snapshot->localTransform); snapshot->isSmallDirty = mSmallDirty; } } // namespace android } // namespace android #if defined(__gl_h_) #if defined(__gl_h_) Loading services/surfaceflinger/Layer.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -937,7 +937,8 @@ public: const sp<SurfaceFlinger> mFlinger; const sp<SurfaceFlinger> mFlinger; // Check if the damage region is a small dirty. // Check if the damage region is a small dirty. void setIsSmallDirty(); void setIsSmallDirty(const Region& damageRegion, const ui::Transform& layerToDisplayTransform); void setIsSmallDirty(frontend::LayerSnapshot* snapshot); protected: protected: // For unit tests // For unit tests Loading services/surfaceflinger/SurfaceFlinger.cpp +24 −15 Original line number Original line Diff line number Diff line Loading @@ -2213,8 +2213,29 @@ void SurfaceFlinger::updateLayerHistory(nsecs_t now) { continue; continue; } } if (!snapshot->changes.any(Changes::FrameRate | Changes::Buffer | Changes::Animation) && const bool updateSmallDirty = mScheduler->supportSmallDirtyDetection() && (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) == 0) { ((snapshot->clientChanges & layer_state_t::eSurfaceDamageRegionChanged) || snapshot->changes.any(Changes::Geometry)); const bool hasChanges = snapshot->changes.any(Changes::FrameRate | Changes::Buffer | Changes::Animation) || (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) != 0; if (!updateSmallDirty && !hasChanges) { continue; } auto it = mLegacyLayers.find(snapshot->sequence); LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldn't find layer object for %s", snapshot->getDebugString().c_str()); if (updateSmallDirty) { // Update small dirty flag while surface damage region or geometry changed it->second->setIsSmallDirty(snapshot.get()); } if (!hasChanges) { continue; continue; } } Loading @@ -2224,12 +2245,9 @@ void SurfaceFlinger::updateLayerHistory(nsecs_t now) { .transform = snapshot->geomLayerTransform, .transform = snapshot->geomLayerTransform, .setFrameRateVote = snapshot->frameRate, .setFrameRateVote = snapshot->frameRate, .frameRateSelectionPriority = snapshot->frameRateSelectionPriority, .frameRateSelectionPriority = snapshot->frameRateSelectionPriority, .isSmallDirty = snapshot->isSmallDirty, }; }; auto it = mLegacyLayers.find(snapshot->sequence); LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s", snapshot->getDebugString().c_str()); if (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) { if (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) { mScheduler->setDefaultFrameRateCompatibility(snapshot->sequence, mScheduler->setDefaultFrameRateCompatibility(snapshot->sequence, snapshot->defaultFrameRateCompatibility); snapshot->defaultFrameRateCompatibility); Loading Loading @@ -8513,15 +8531,6 @@ void SurfaceFlinger::sample() { void SurfaceFlinger::onActiveDisplaySizeChanged(const DisplayDevice& activeDisplay) { void SurfaceFlinger::onActiveDisplaySizeChanged(const DisplayDevice& activeDisplay) { mScheduler->onActiveDisplayAreaChanged(activeDisplay.getWidth() * activeDisplay.getHeight()); mScheduler->onActiveDisplayAreaChanged(activeDisplay.getWidth() * activeDisplay.getHeight()); getRenderEngine().onActiveDisplaySizeChanged(activeDisplay.getSize()); getRenderEngine().onActiveDisplaySizeChanged(activeDisplay.getSize()); // Notify layers to update small dirty flag. if (mScheduler->supportSmallDirtyDetection()) { mCurrentState.traverse([&](Layer* layer) { if (layer->getLayerStack() == activeDisplay.getLayerStack()) { layer->setIsSmallDirty(); } }); } } } sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const { sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const { Loading services/surfaceflinger/tests/unittests/LayerHierarchyTest.h +24 −0 Original line number Original line Diff line number Diff line Loading @@ -421,6 +421,17 @@ protected: mLifecycleManager.applyTransactions(transactions); mLifecycleManager.applyTransactions(transactions); } } void setDamageRegion(uint32_t id, const Region& damageRegion) { std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eSurfaceDamageRegionChanged; transactions.back().states.front().layerId = id; transactions.back().states.front().state.surfaceDamageRegion = damageRegion; mLifecycleManager.applyTransactions(transactions); } void setDataspace(uint32_t id, ui::Dataspace dataspace) { void setDataspace(uint32_t id, ui::Dataspace dataspace) { std::vector<TransactionState> transactions; std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.emplace_back(); Loading @@ -432,6 +443,19 @@ protected: mLifecycleManager.applyTransactions(transactions); mLifecycleManager.applyTransactions(transactions); } } void setMatrix(uint32_t id, float dsdx, float dtdx, float dtdy, float dsdy) { layer_state_t::matrix22_t matrix{dsdx, dtdx, dtdy, dsdy}; std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eMatrixChanged; transactions.back().states.front().layerId = id; transactions.back().states.front().state.matrix = matrix; mLifecycleManager.applyTransactions(transactions); } void setShadowRadius(uint32_t id, float shadowRadius) { void setShadowRadius(uint32_t id, float shadowRadius) { std::vector<TransactionState> transactions; std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.emplace_back(); Loading Loading
services/surfaceflinger/FrontEnd/LayerSnapshot.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -122,6 +122,8 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState { ReachableByRelativeParent ReachableByRelativeParent }; }; Reachablilty reachablilty; Reachablilty reachablilty; // True when the surfaceDamage is recognized as a small area update. bool isSmallDirty = false; static bool isOpaqueFormat(PixelFormat format); static bool isOpaqueFormat(PixelFormat format); static bool isTransformValid(const ui::Transform& t); static bool isTransformValid(const ui::Transform& t); Loading
services/surfaceflinger/Layer.cpp +14 −3 Original line number Original line Diff line number Diff line Loading @@ -3364,7 +3364,7 @@ bool Layer::setSurfaceDamageRegion(const Region& surfaceDamage) { mDrawingState.surfaceDamageRegion = surfaceDamage; mDrawingState.surfaceDamageRegion = surfaceDamage; mDrawingState.modified = true; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); setTransactionFlags(eTransactionNeeded); setIsSmallDirty(); setIsSmallDirty(surfaceDamage, getTransform()); return true; return true; } } Loading Loading @@ -4411,7 +4411,9 @@ void Layer::updateLastLatchTime(nsecs_t latchTime) { mLastLatchTime = latchTime; mLastLatchTime = latchTime; } } void Layer::setIsSmallDirty() { void Layer::setIsSmallDirty(const Region& damageRegion, const ui::Transform& layerToDisplayTransform) { mSmallDirty = false; if (!mFlinger->mScheduler->supportSmallDirtyDetection()) { if (!mFlinger->mScheduler->supportSmallDirtyDetection()) { return; return; } } Loading @@ -4420,17 +4422,26 @@ void Layer::setIsSmallDirty() { mWindowType != WindowInfo::Type::BASE_APPLICATION) { mWindowType != WindowInfo::Type::BASE_APPLICATION) { return; return; } } Rect bounds = mDrawingState.surfaceDamageRegion.getBounds(); Rect bounds = damageRegion.getBounds(); if (!bounds.isValid()) { if (!bounds.isValid()) { return; return; } } // Transform to screen space. bounds = layerToDisplayTransform.transform(bounds); // If the damage region is a small dirty, this could give the hint for the layer history that // If the damage region is a small dirty, this could give the hint for the layer history that // it could suppress the heuristic rate when calculating. // it could suppress the heuristic rate when calculating. mSmallDirty = mFlinger->mScheduler->isSmallDirtyArea(mOwnerAppId, mSmallDirty = mFlinger->mScheduler->isSmallDirtyArea(mOwnerAppId, bounds.getWidth() * bounds.getHeight()); bounds.getWidth() * bounds.getHeight()); } } void Layer::setIsSmallDirty(frontend::LayerSnapshot* snapshot) { setIsSmallDirty(snapshot->surfaceDamage, snapshot->localTransform); snapshot->isSmallDirty = mSmallDirty; } } // namespace android } // namespace android #if defined(__gl_h_) #if defined(__gl_h_) Loading
services/surfaceflinger/Layer.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -937,7 +937,8 @@ public: const sp<SurfaceFlinger> mFlinger; const sp<SurfaceFlinger> mFlinger; // Check if the damage region is a small dirty. // Check if the damage region is a small dirty. void setIsSmallDirty(); void setIsSmallDirty(const Region& damageRegion, const ui::Transform& layerToDisplayTransform); void setIsSmallDirty(frontend::LayerSnapshot* snapshot); protected: protected: // For unit tests // For unit tests Loading
services/surfaceflinger/SurfaceFlinger.cpp +24 −15 Original line number Original line Diff line number Diff line Loading @@ -2213,8 +2213,29 @@ void SurfaceFlinger::updateLayerHistory(nsecs_t now) { continue; continue; } } if (!snapshot->changes.any(Changes::FrameRate | Changes::Buffer | Changes::Animation) && const bool updateSmallDirty = mScheduler->supportSmallDirtyDetection() && (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) == 0) { ((snapshot->clientChanges & layer_state_t::eSurfaceDamageRegionChanged) || snapshot->changes.any(Changes::Geometry)); const bool hasChanges = snapshot->changes.any(Changes::FrameRate | Changes::Buffer | Changes::Animation) || (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) != 0; if (!updateSmallDirty && !hasChanges) { continue; } auto it = mLegacyLayers.find(snapshot->sequence); LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldn't find layer object for %s", snapshot->getDebugString().c_str()); if (updateSmallDirty) { // Update small dirty flag while surface damage region or geometry changed it->second->setIsSmallDirty(snapshot.get()); } if (!hasChanges) { continue; continue; } } Loading @@ -2224,12 +2245,9 @@ void SurfaceFlinger::updateLayerHistory(nsecs_t now) { .transform = snapshot->geomLayerTransform, .transform = snapshot->geomLayerTransform, .setFrameRateVote = snapshot->frameRate, .setFrameRateVote = snapshot->frameRate, .frameRateSelectionPriority = snapshot->frameRateSelectionPriority, .frameRateSelectionPriority = snapshot->frameRateSelectionPriority, .isSmallDirty = snapshot->isSmallDirty, }; }; auto it = mLegacyLayers.find(snapshot->sequence); LOG_ALWAYS_FATAL_IF(it == mLegacyLayers.end(), "Couldnt find layer object for %s", snapshot->getDebugString().c_str()); if (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) { if (snapshot->clientChanges & layer_state_t::eDefaultFrameRateCompatibilityChanged) { mScheduler->setDefaultFrameRateCompatibility(snapshot->sequence, mScheduler->setDefaultFrameRateCompatibility(snapshot->sequence, snapshot->defaultFrameRateCompatibility); snapshot->defaultFrameRateCompatibility); Loading Loading @@ -8513,15 +8531,6 @@ void SurfaceFlinger::sample() { void SurfaceFlinger::onActiveDisplaySizeChanged(const DisplayDevice& activeDisplay) { void SurfaceFlinger::onActiveDisplaySizeChanged(const DisplayDevice& activeDisplay) { mScheduler->onActiveDisplayAreaChanged(activeDisplay.getWidth() * activeDisplay.getHeight()); mScheduler->onActiveDisplayAreaChanged(activeDisplay.getWidth() * activeDisplay.getHeight()); getRenderEngine().onActiveDisplaySizeChanged(activeDisplay.getSize()); getRenderEngine().onActiveDisplaySizeChanged(activeDisplay.getSize()); // Notify layers to update small dirty flag. if (mScheduler->supportSmallDirtyDetection()) { mCurrentState.traverse([&](Layer* layer) { if (layer->getLayerStack() == activeDisplay.getLayerStack()) { layer->setIsSmallDirty(); } }); } } } sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const { sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const { Loading
services/surfaceflinger/tests/unittests/LayerHierarchyTest.h +24 −0 Original line number Original line Diff line number Diff line Loading @@ -421,6 +421,17 @@ protected: mLifecycleManager.applyTransactions(transactions); mLifecycleManager.applyTransactions(transactions); } } void setDamageRegion(uint32_t id, const Region& damageRegion) { std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eSurfaceDamageRegionChanged; transactions.back().states.front().layerId = id; transactions.back().states.front().state.surfaceDamageRegion = damageRegion; mLifecycleManager.applyTransactions(transactions); } void setDataspace(uint32_t id, ui::Dataspace dataspace) { void setDataspace(uint32_t id, ui::Dataspace dataspace) { std::vector<TransactionState> transactions; std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.emplace_back(); Loading @@ -432,6 +443,19 @@ protected: mLifecycleManager.applyTransactions(transactions); mLifecycleManager.applyTransactions(transactions); } } void setMatrix(uint32_t id, float dsdx, float dtdx, float dtdy, float dsdy) { layer_state_t::matrix22_t matrix{dsdx, dtdx, dtdy, dsdy}; std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.back().states.push_back({}); transactions.back().states.front().state.what = layer_state_t::eMatrixChanged; transactions.back().states.front().layerId = id; transactions.back().states.front().state.matrix = matrix; mLifecycleManager.applyTransactions(transactions); } void setShadowRadius(uint32_t id, float shadowRadius) { void setShadowRadius(uint32_t id, float shadowRadius) { std::vector<TransactionState> transactions; std::vector<TransactionState> transactions; transactions.emplace_back(); transactions.emplace_back(); Loading