Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7be518c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move mSurfaceFlingerConsumer into BufferLayer"

parents 817112a0 eb085e0c
Loading
Loading
Loading
Loading
+135 −40
Original line number Diff line number Diff line
@@ -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),
@@ -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);
@@ -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);
@@ -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) {
@@ -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
@@ -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());
@@ -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

+30 −3
Original line number Diff line number Diff line
@@ -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
    // -----------------------------------------------------------------------
@@ -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
@@ -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:
@@ -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
+30 −0
Original line number Diff line number Diff line
@@ -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
+21 −0
Original line number Diff line number Diff line
@@ -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; }
};

// ---------------------------------------------------------------------------
+13 −235

File changed.

Preview size limit exceeded, changes collapsed.

Loading