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

Commit 0f3e99bf authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 13872691 from e4937a76 to 25Q4-release

Change-Id: Ic25144dd4d1aee4b9db5bb8d618c3d3ab5a28db9
parents d2fddec0 e4937a76
Loading
Loading
Loading
Loading
+13 −27
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#pragma once

#include <binder/unique_fd.h>
#include <binder/Functional.h>
#include <poll.h>

#include "Constants.h"
@@ -76,10 +77,16 @@ status_t interruptableReadOrWrite(
    size_t enomemWaitUs = 0;
    size_t enomemTotalUs = 0;

    size_t numSysCalls = 0;
    auto syscallBugCatcher = binder::impl::make_scope_guard([&]() {
        if (numSysCalls > 1000) {
            ALOGE("Too many calls to %s! Spinning? %zu", funName, numSysCalls);
        }
    });

    bool havePolled = false;
    while (true) {
        ssize_t processSize = -1;
        bool skipPollingAndContinue = false; // set when we should retry immediately

        // This block dynamically adjusts packet sizes down to work around a
        // limitation in the vsock driver where large packets are sometimes
@@ -110,6 +117,8 @@ status_t interruptableReadOrWrite(
                                    "chunkRemaining never zero - see EMPTY IOVEC ISSUE above");
            }

            ++numSysCalls;

            // MAIN ACTION
            if (MAYBE_TRUE_IN_FLAKE_MODE) {
                LOG_RPC_DETAIL("Injecting ENOMEM.");
@@ -127,15 +136,6 @@ status_t interruptableReadOrWrite(
                niovs = old_niovs;         // (A) - restored
                iovs[i].iov_len = old_len; // (B) - restored
            }

            // altPoll may introduce long waiting since it assumes if it cannot write
            // data, that it needs to wait to send more to give time for the producer
            // consumer problem to be solved - otherwise it will busy loop. However,
            // for this workaround, we are breaking up the transaction intentionally,
            // not because the transaction won't fit, but to avoid a bug in the kernel
            // for how it combines messages. So, when we artificially simulate a
            // limited send, don't poll and just keep on sending data.
            skipPollingAndContinue = !canSendFullTransaction;
        }

        // HANDLE RESULT OF SEND OR RECEIVE
@@ -170,14 +170,6 @@ status_t interruptableReadOrWrite(
                    LOG_RPC_DETAIL("Sleeping %zuus due to ENOMEM.", enomemWaitUs);
                    usleep(enomemWaitUs);
                }

                // Need to survey socket code to see if polling in this situation is
                // guaranteed to be non-blocking.
                // NOTE: if the other side needs to deallocate memory, and that is the
                // only deallocatable memory in the entire system, but we need altPoll
                // to drain commands to unstick it so it can do that, then this could
                // cause a deadlock, but this is not realistic on Android.
                skipPollingAndContinue = true;
            } else if (havePolled || (savedErrno != EAGAIN && savedErrno != EWOULDBLOCK)) {
                // Still return the error on later passes, since it would expose
                // a problem with polling
@@ -215,21 +207,15 @@ status_t interruptableReadOrWrite(
        }

        // METHOD OF POLLING
        if (skipPollingAndContinue) {
            // Since we aren't polling, manually check if we should shutdown. This ensures any bug
            // leading to an infinite loop can still be recovered from.
            if (fdTrigger->isTriggered()) {
                return DEAD_OBJECT;
            }
            // continue;
        } else if (altPoll) {
        if (altPoll) {
            if (status_t status = (*altPoll)(); status != OK) return status;
            if (fdTrigger->isTriggered()) { // altPoll may not check this
                return DEAD_OBJECT;
            }
        } else {
            if (status_t status = fdTrigger->triggerablePoll(socket, event); status != OK)
            if (status_t status = fdTrigger->triggerablePoll(socket, event); status != OK) {
                return status;
            }
            if (!havePolled) havePolled = true;
        }
    }
+7 −6
Original line number Diff line number Diff line
@@ -197,22 +197,23 @@ const std::string& SurfaceControl::getName() const {
    return mName;
}

std::shared_ptr<Choreographer> SurfaceControl::getChoreographer() {
Choreographer* SurfaceControl::getChoreographer() {
    if (mChoreographer) {
        return mChoreographer;
        return mChoreographer.get();
    }
    sp<Looper> looper = Looper::getForThread();
    if (!looper.get()) {
        ALOGE("%s: No looper prepared for thread", __func__);
        return nullptr;
    }
    mChoreographer = std::make_shared<Choreographer>(looper, getHandle());
    status_t result = mChoreographer->initialize();
    auto choreographer = sp<Choreographer>::make(looper, getHandle());
    status_t result = choreographer->initialize();
    if (result != OK) {
        ALOGE("Failed to initialize choreographer");
        mChoreographer = nullptr;
        return nullptr;
    }
    return mChoreographer;
    mChoreographer = std::move(choreographer);
    return mChoreographer.get();
}

sp<IGraphicBufferProducer> SurfaceControl::getIGraphicBufferProducer()
+3 −3
Original line number Diff line number Diff line
@@ -79,9 +79,6 @@ public:
    };
    static Context gChoreographers;

    explicit Choreographer(const sp<Looper>& looper, const sp<IBinder>& layerHandle = nullptr)
            EXCLUDES(gChoreographers.lock);

    void postFrameCallbackDelayed(AChoreographer_frameCallback cb,
                                  AChoreographer_frameCallback64 cb64,
                                  AChoreographer_vsyncCallback vsyncCallback, void* data,
@@ -114,6 +111,9 @@ public:

private:
    Choreographer(const Choreographer&) = delete;
    explicit Choreographer(const sp<Looper>& looper, const sp<IBinder>& layerHandle = nullptr)
            EXCLUDES(gChoreographers.lock);
    friend class sp<Choreographer>;

    void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
                       VsyncEventData vsyncEventData) override;
+3 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

#include <android/gui/ISurfaceComposerClient.h>

#include <gui/Choreographer.h>
#include <ui/FrameStats.h>
#include <ui/PixelFormat.h>
#include <ui/Region.h>
@@ -36,7 +37,6 @@ namespace android {

// ---------------------------------------------------------------------------

class Choreographer;
class IGraphicBufferProducer;
class Surface;
class SurfaceComposerClient;
@@ -82,7 +82,7 @@ public:
    const std::string& getName() const;

    // TODO(b/267195698): Consider renaming.
    std::shared_ptr<Choreographer> getChoreographer();
    Choreographer* getChoreographer();

    sp<IGraphicBufferProducer> getIGraphicBufferProducer();

@@ -134,7 +134,7 @@ private:
    PixelFormat mFormat = PIXEL_FORMAT_NONE;
    uint32_t mCreateFlags = 0;
    uint64_t mFallbackFrameNumber = 100;
    std::shared_ptr<Choreographer> mChoreographer;
    sp<Choreographer> mChoreographer;
};

}; // namespace android
+39 −7
Original line number Diff line number Diff line
@@ -33,11 +33,11 @@ use ffi::{
    AHardwareBuffer, AHardwareBuffer_Desc, AHardwareBuffer_Plane, AHardwareBuffer_Planes,
    AHardwareBuffer_readFromParcel, AHardwareBuffer_writeToParcel, ARect,
};
use std::ffi::c_void;
use std::fmt::{self, Debug, Formatter};
use std::mem::{forget, ManuallyDrop};
use std::os::fd::{AsRawFd, BorrowedFd, FromRawFd, OwnedFd};
use std::ptr::{self, null, null_mut, NonNull};
use std::{ffi::c_void, rc::Rc};

/// Wrapper around a C `AHardwareBuffer_Desc`.
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -349,15 +349,20 @@ impl HardwareBuffer {
            ffi::AHardwareBuffer_lockPlanes(self.0.as_ptr(), usage.0, fence, rect, &mut planes)
        };
        status_result(status)?;

        // `AHardwareBuffer_unlock` unlocks all the planes together, so we use a shared guard.
        let guard = Rc::new(HardwareBufferGuard {
            buffer: self,
            address: NonNull::new(planes.planes[0].data)
                .expect("AHardwareBuffer_lockPlanes set a null plane data"),
        });
        let plane_count = planes.planeCount.try_into().unwrap();
        Ok(planes.planes[..plane_count]
            .iter()
            .map(|plane| PlaneGuard {
                guard: HardwareBufferGuard {
                    buffer: self,
                _guard: guard.clone(),
                address: NonNull::new(plane.data)
                        .expect("AHardwareBuffer_lockAndGetInfo set a null outVirtualAddress"),
                },
                    .expect("AHardwareBuffer_lockPlanes set a null plane data"),
                pixel_stride: plane.pixelStride,
                row_stride: plane.rowStride,
            })
@@ -566,7 +571,9 @@ pub struct LockedBufferInfo<'a> {
#[derive(Debug)]
pub struct PlaneGuard<'a> {
    /// The locked buffer guard.
    pub guard: HardwareBufferGuard<'a>,
    _guard: Rc<HardwareBufferGuard<'a>>,
    /// The address of the buffer plane in memory.
    pub address: NonNull<c_void>,
    /// The stride in bytes between the color channel for one pixel to the next pixel.
    pub pixel_stride: u32,
    /// The stride in bytes between rows in the buffer.
@@ -830,4 +837,29 @@ mod test {
        assert_eq!(info.stride, WIDTH * 4);
        drop(info);
    }

    #[test]
    fn lock_planes() {
        let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
            1024,
            512,
            1,
            AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420,
            AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
            0,
        ))
        .expect("Failed to create buffer");

        // SAFETY: No other threads or processes have access to the buffer.
        let plane_guards = unsafe {
            buffer.lock_planes(
                AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
                None,
                None,
            )
        }
        .unwrap();

        drop(plane_guards);
    }
}
Loading