Loading services/surfaceflinger/BufferLayer.cpp +135 −40 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ namespace android { BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) : Layer(flinger, client, name, w, h, flags), mSurfaceFlingerConsumer(nullptr), mTextureName(-1U), mFormat(PIXEL_FORMAT_NONE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), Loading Loading @@ -99,6 +100,18 @@ BufferLayer::~BufferLayer() { #endif } void BufferLayer::useSurfaceDamage() { if (mFlinger->mForceFullDamage) { surfaceDamageRegion = Region::INVALID_REGION; } else { surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); } } void BufferLayer::useEmptyDamage() { surfaceDamageRegion.clear(); } bool BufferLayer::isProtected() const { const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); Loading Loading @@ -252,6 +265,54 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, engine.disableTexturing(); } #ifdef USE_HWC2 void BufferLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { if (mHwcLayers.empty()) { return; } mSurfaceFlingerConsumer->setReleaseFence(releaseFence); } #else void BufferLayer::onLayerDisplayed(const sp<const DisplayDevice>& /*hw*/, HWComposer::HWCLayerInterface* layer) { if (layer) { layer->onDisplayed(); mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); } } #endif void BufferLayer::abandon() { mSurfaceFlingerConsumer->abandon(); } bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const { if (mSidebandStreamChanged || mAutoRefresh) { return true; } Mutex::Autolock lock(mQueueItemLock); if (mQueueItems.empty()) { return false; } auto timestamp = mQueueItems[0].mTimestamp; nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); // Ignore timestamps more than a second in the future bool isPlausible = timestamp < (expectedPresent + s2ns(1)); ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible " "relative to expectedPresent %" PRId64, mName.string(), timestamp, expectedPresent); bool isDue = timestamp < expectedPresent; return isDue || !isPlausible; } void BufferLayer::setTransformHint(uint32_t orientation) const { mSurfaceFlingerConsumer->setTransformHint(orientation); } bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { if (mBufferLatched) { Mutex::Autolock lock(mFrameEventHistoryMutex); Loading @@ -260,6 +321,60 @@ bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { mRefreshPending = false; return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; } 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; // Update mFrameEventHistory. { Mutex::Autolock lock(mFrameEventHistoryMutex); mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, compositorTiming); } // Update mFrameTracker. nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); mFrameTracker.setDesiredPresentTime(desiredPresentTime); std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime(); if (frameReadyFence->isValid()) { mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); } else { // There was no fence for this frame, so assume that it was ready // to be presented at the desired present time. mFrameTracker.setFrameReadyTime(desiredPresentTime); } if (presentFence->isValid()) { mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence)); } else { // The HWC doesn't support present fences, so use the refresh // timestamp instead. mFrameTracker.setActualPresentTime( mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY)); } mFrameTracker.advanceFrame(); mFrameLatencyNeeded = false; return true; } std::vector<OccupancyTracker::Segment> BufferLayer::getOccupancyHistory(bool forceFlush) { std::vector<OccupancyTracker::Segment> history; status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history); if (result != NO_ERROR) { ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result); return {}; } return history; } bool BufferLayer::getTransformToDisplayInverse() const { return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); } #ifdef USE_HWC2 void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { Loading Loading @@ -485,6 +600,10 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime return outDirtyRegion; } void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) { mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); } #ifdef USE_HWC2 void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { // Apply this display's projection's viewport to the visible region Loading Loading @@ -529,28 +648,6 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) return; } // SolidColor layers if (mActiveBuffer == nullptr) { setCompositionType(hwcId, HWC2::Composition::SolidColor); // For now, we only support black for DimLayer error = hwcLayer->setColor({0, 0, 0, 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)); } // 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)); } return; } // Device or Cursor layers if (mPotentialCursor) { ALOGV("[%s] Requesting Cursor composition", mName.string()); Loading Loading @@ -580,26 +677,24 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) } #else void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& hw, void BufferLayer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, HWComposer::HWCLayerInterface& layer) { // we have to set the visible region on every frame because // we currently free it during onLayerDisplayed(), which is called // after HWComposer::commit() -- every frame. // Apply this display's projection's viewport to the visible region // before giving it to the HWC HAL. const Transform& tr = hw->getTransform(); Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); layer.setVisibleRegionScreen(visible); layer.setSurfaceDamage(surfaceDamageRegion); mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER); int fenceFd = -1; if (mSidebandStream.get()) { layer.setSidebandStream(mSidebandStream); } else { // NOTE: buffer can be NULL if the client never drew into this // layer yet, or if we ran out of memory layer.setBuffer(mActiveBuffer); // TODO: there is a possible optimization here: we only need to set the // acquire fence the first time a new buffer is acquired on EACH display. if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) { sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); if (fence->isValid()) { fenceFd = fence->dup(); if (fenceFd == -1) { ALOGW("failed to dup layer fence, skipping sync: %d", errno); } } } layer.setAcquireFenceFd(fenceFd); } #endif Loading services/surfaceflinger/BufferLayer.h +30 −3 Original line number Diff line number Diff line Loading @@ -64,6 +64,12 @@ public: ~BufferLayer() override; // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with // one empty rect. void useSurfaceDamage(); void useEmptyDamage(); // ----------------------------------------------------------------------- // Overriden from Layer // ----------------------------------------------------------------------- Loading Loading @@ -99,6 +105,23 @@ public: void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const override; #ifdef USE_HWC2 void onLayerDisplayed(const sp<Fence>& releaseFence) override; #else void onLayerDisplayed(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface* layer) override; #endif void abandon() override; bool shouldPresentNow(const DispSync& dispSync) const override; void setTransformHint(uint32_t orientation) const override; bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, const std::shared_ptr<FenceTime>& presentFence, const CompositorTiming& compositorTiming) override; std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override; bool getTransformToDisplayInverse() const override; public: bool onPreComposition(nsecs_t refreshStartTime) override; #ifdef USE_HWC2 Loading @@ -114,13 +137,15 @@ public: */ Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override; bool isBufferLatched() const override { return mRefreshPending; } void setDefaultBufferSize(uint32_t w, uint32_t h) override; #ifdef USE_HWC2 void setPerFrameData(const sp<const DisplayDevice>& displayDevice); void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override; #else void setPerFrameData(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer); void setAcquireFence(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer) override; #endif bool isOpaque(const Layer::State& s) const override; private: Loading Loading @@ -160,6 +185,8 @@ public: sp<IGraphicBufferProducer> getProducer() const; private: sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer; // Check all of the local sync points to ensure that all transactions // which need to have been applied prior to the frame which is about to // be latched have signaled Loading services/surfaceflinger/ColorLayer.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,36 @@ bool ColorLayer::isVisible() const { return !isHiddenByPolicy() && s.color.a; } #ifdef USE_HWC2 void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { const Transform& tr = displayDevice->getTransform(); const auto& viewport = displayDevice->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); auto hwcId = displayDevice->getHwcDisplayId(); auto& hwcInfo = mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; auto error = hwcLayer->setVisibleRegion(visible); setCompositionType(hwcId, HWC2::Composition::SolidColor); 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)); } // 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)); } } #endif // --------------------------------------------------------------------------- }; // namespace android services/surfaceflinger/ColorLayer.h +21 −0 Original line number Diff line number Diff line Loading @@ -46,8 +46,29 @@ public: void releasePendingBuffer(nsecs_t) override {} #endif Region latchBuffer(bool&, nsecs_t) override { return Region(); } void useSurfaceDamage() override {} void useEmptyDamage() override {} bool isBufferLatched() const override { return false; } bool onPreComposition(nsecs_t) override { return true; } void abandon() override {} #ifdef USE_HWC2 void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override; #else void setAcquireFence(const sp<const DisplayDevice>& /*hw*/, HWComposer::HWCLayerInterface& /*layer*/) override {} #endif void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) override {} bool shouldPresentNow(const DispSync& /*dispSync*/) const override { return false; } bool onPostComposition(const std::shared_ptr<FenceTime>& /*glDoneFence*/, const std::shared_ptr<FenceTime>& /*presentFence*/, const CompositorTiming& /*compositorTiming*/) override { return false; } void setTransformHint(uint32_t /*orientation*/) const override {} std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool /*forceFlush*/) override { return {}; } bool getTransformToDisplayInverse() const override { return false; } }; // --------------------------------------------------------------------------- Loading services/surfaceflinger/Layer.cpp +13 −235 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/surfaceflinger/BufferLayer.cpp +135 −40 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ namespace android { BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags) : Layer(flinger, client, name, w, h, flags), mSurfaceFlingerConsumer(nullptr), mTextureName(-1U), mFormat(PIXEL_FORMAT_NONE), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), Loading Loading @@ -99,6 +100,18 @@ BufferLayer::~BufferLayer() { #endif } void BufferLayer::useSurfaceDamage() { if (mFlinger->mForceFullDamage) { surfaceDamageRegion = Region::INVALID_REGION; } else { surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage(); } } void BufferLayer::useEmptyDamage() { surfaceDamageRegion.clear(); } bool BufferLayer::isProtected() const { const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); Loading Loading @@ -252,6 +265,54 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip, engine.disableTexturing(); } #ifdef USE_HWC2 void BufferLayer::onLayerDisplayed(const sp<Fence>& releaseFence) { if (mHwcLayers.empty()) { return; } mSurfaceFlingerConsumer->setReleaseFence(releaseFence); } #else void BufferLayer::onLayerDisplayed(const sp<const DisplayDevice>& /*hw*/, HWComposer::HWCLayerInterface* layer) { if (layer) { layer->onDisplayed(); mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); } } #endif void BufferLayer::abandon() { mSurfaceFlingerConsumer->abandon(); } bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const { if (mSidebandStreamChanged || mAutoRefresh) { return true; } Mutex::Autolock lock(mQueueItemLock); if (mQueueItems.empty()) { return false; } auto timestamp = mQueueItems[0].mTimestamp; nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync); // Ignore timestamps more than a second in the future bool isPlausible = timestamp < (expectedPresent + s2ns(1)); ALOGW_IF(!isPlausible, "[%s] Timestamp %" PRId64 " seems implausible " "relative to expectedPresent %" PRId64, mName.string(), timestamp, expectedPresent); bool isDue = timestamp < expectedPresent; return isDue || !isPlausible; } void BufferLayer::setTransformHint(uint32_t orientation) const { mSurfaceFlingerConsumer->setTransformHint(orientation); } bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { if (mBufferLatched) { Mutex::Autolock lock(mFrameEventHistoryMutex); Loading @@ -260,6 +321,60 @@ bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) { mRefreshPending = false; return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh; } 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; // Update mFrameEventHistory. { Mutex::Autolock lock(mFrameEventHistoryMutex); mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence, compositorTiming); } // Update mFrameTracker. nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); mFrameTracker.setDesiredPresentTime(desiredPresentTime); std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime(); if (frameReadyFence->isValid()) { mFrameTracker.setFrameReadyFence(std::move(frameReadyFence)); } else { // There was no fence for this frame, so assume that it was ready // to be presented at the desired present time. mFrameTracker.setFrameReadyTime(desiredPresentTime); } if (presentFence->isValid()) { mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence)); } else { // The HWC doesn't support present fences, so use the refresh // timestamp instead. mFrameTracker.setActualPresentTime( mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY)); } mFrameTracker.advanceFrame(); mFrameLatencyNeeded = false; return true; } std::vector<OccupancyTracker::Segment> BufferLayer::getOccupancyHistory(bool forceFlush) { std::vector<OccupancyTracker::Segment> history; status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history); if (result != NO_ERROR) { ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result); return {}; } return history; } bool BufferLayer::getTransformToDisplayInverse() const { return mSurfaceFlingerConsumer->getTransformToDisplayInverse(); } #ifdef USE_HWC2 void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) { Loading Loading @@ -485,6 +600,10 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime return outDirtyRegion; } void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) { mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); } #ifdef USE_HWC2 void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { // Apply this display's projection's viewport to the visible region Loading Loading @@ -529,28 +648,6 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) return; } // SolidColor layers if (mActiveBuffer == nullptr) { setCompositionType(hwcId, HWC2::Composition::SolidColor); // For now, we only support black for DimLayer error = hwcLayer->setColor({0, 0, 0, 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)); } // 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)); } return; } // Device or Cursor layers if (mPotentialCursor) { ALOGV("[%s] Requesting Cursor composition", mName.string()); Loading Loading @@ -580,26 +677,24 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) } #else void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& hw, void BufferLayer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, HWComposer::HWCLayerInterface& layer) { // we have to set the visible region on every frame because // we currently free it during onLayerDisplayed(), which is called // after HWComposer::commit() -- every frame. // Apply this display's projection's viewport to the visible region // before giving it to the HWC HAL. const Transform& tr = hw->getTransform(); Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); layer.setVisibleRegionScreen(visible); layer.setSurfaceDamage(surfaceDamageRegion); mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER); int fenceFd = -1; if (mSidebandStream.get()) { layer.setSidebandStream(mSidebandStream); } else { // NOTE: buffer can be NULL if the client never drew into this // layer yet, or if we ran out of memory layer.setBuffer(mActiveBuffer); // TODO: there is a possible optimization here: we only need to set the // acquire fence the first time a new buffer is acquired on EACH display. if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) { sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); if (fence->isValid()) { fenceFd = fence->dup(); if (fenceFd == -1) { ALOGW("failed to dup layer fence, skipping sync: %d", errno); } } } layer.setAcquireFenceFd(fenceFd); } #endif Loading
services/surfaceflinger/BufferLayer.h +30 −3 Original line number Diff line number Diff line Loading @@ -64,6 +64,12 @@ public: ~BufferLayer() override; // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with // one empty rect. void useSurfaceDamage(); void useEmptyDamage(); // ----------------------------------------------------------------------- // Overriden from Layer // ----------------------------------------------------------------------- Loading Loading @@ -99,6 +105,23 @@ public: void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform) const override; #ifdef USE_HWC2 void onLayerDisplayed(const sp<Fence>& releaseFence) override; #else void onLayerDisplayed(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface* layer) override; #endif void abandon() override; bool shouldPresentNow(const DispSync& dispSync) const override; void setTransformHint(uint32_t orientation) const override; bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence, const std::shared_ptr<FenceTime>& presentFence, const CompositorTiming& compositorTiming) override; std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override; bool getTransformToDisplayInverse() const override; public: bool onPreComposition(nsecs_t refreshStartTime) override; #ifdef USE_HWC2 Loading @@ -114,13 +137,15 @@ public: */ Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override; bool isBufferLatched() const override { return mRefreshPending; } void setDefaultBufferSize(uint32_t w, uint32_t h) override; #ifdef USE_HWC2 void setPerFrameData(const sp<const DisplayDevice>& displayDevice); void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override; #else void setPerFrameData(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer); void setAcquireFence(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer) override; #endif bool isOpaque(const Layer::State& s) const override; private: Loading Loading @@ -160,6 +185,8 @@ public: sp<IGraphicBufferProducer> getProducer() const; private: sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer; // Check all of the local sync points to ensure that all transactions // which need to have been applied prior to the frame which is about to // be latched have signaled Loading
services/surfaceflinger/ColorLayer.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,36 @@ bool ColorLayer::isVisible() const { return !isHiddenByPolicy() && s.color.a; } #ifdef USE_HWC2 void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { const Transform& tr = displayDevice->getTransform(); const auto& viewport = displayDevice->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); auto hwcId = displayDevice->getHwcDisplayId(); auto& hwcInfo = mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; auto error = hwcLayer->setVisibleRegion(visible); setCompositionType(hwcId, HWC2::Composition::SolidColor); 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)); } // 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)); } } #endif // --------------------------------------------------------------------------- }; // namespace android
services/surfaceflinger/ColorLayer.h +21 −0 Original line number Diff line number Diff line Loading @@ -46,8 +46,29 @@ public: void releasePendingBuffer(nsecs_t) override {} #endif Region latchBuffer(bool&, nsecs_t) override { return Region(); } void useSurfaceDamage() override {} void useEmptyDamage() override {} bool isBufferLatched() const override { return false; } bool onPreComposition(nsecs_t) override { return true; } void abandon() override {} #ifdef USE_HWC2 void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override; #else void setAcquireFence(const sp<const DisplayDevice>& /*hw*/, HWComposer::HWCLayerInterface& /*layer*/) override {} #endif void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) override {} bool shouldPresentNow(const DispSync& /*dispSync*/) const override { return false; } bool onPostComposition(const std::shared_ptr<FenceTime>& /*glDoneFence*/, const std::shared_ptr<FenceTime>& /*presentFence*/, const CompositorTiming& /*compositorTiming*/) override { return false; } void setTransformHint(uint32_t /*orientation*/) const override {} std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool /*forceFlush*/) override { return {}; } bool getTransformToDisplayInverse() const override { return false; } }; // --------------------------------------------------------------------------- Loading
services/surfaceflinger/Layer.cpp +13 −235 File changed.Preview size limit exceeded, changes collapsed. Show changes