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

Commit 9837ce82 authored by Fabien Sanglard's avatar Fabien Sanglard Committed by android-build-merger
Browse files

Skip Validate

am: 249c0ae8

Change-Id: I55a564d600a422915f43111f4e02a10857512fcf
parents 7f683a8b 249c0ae8
Loading
Loading
Loading
Loading
+47 −1
Original line number Diff line number Diff line
@@ -546,6 +546,29 @@ Error Composer::validateDisplay(Display display, uint32_t* outNumTypes,
    return Error::NONE;
}

Error Composer::presentOrValidateDisplay(Display display, uint32_t* outNumTypes,
                               uint32_t* outNumRequests, int* outPresentFence, uint32_t* state) {
   mWriter.selectDisplay(display);
   mWriter.presentOrvalidateDisplay();

   Error error = execute();
   if (error != Error::NONE) {
       return error;
   }

   mReader.takePresentOrValidateStage(display, state);

   if (*state == 1) { // Present succeeded
       mReader.takePresentFence(display, outPresentFence);
   }

   if (*state == 0) { // Validate succeeded.
       mReader.hasChanges(display, outNumTypes, outNumRequests);
   }

   return Error::NONE;
}

Error Composer::setCursorPosition(Display display, Layer layer,
        int32_t x, int32_t y)
{
@@ -763,7 +786,8 @@ Error Composer::execute()
            auto command = mWriter.getCommand(cmdErr.location);

            if (command == IComposerClient::Command::VALIDATE_DISPLAY ||
                command == IComposerClient::Command::PRESENT_DISPLAY) {
                command == IComposerClient::Command::PRESENT_DISPLAY ||
                command == IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY) {
                error = cmdErr.error;
            } else {
                ALOGW("command 0x%x generated error %d",
@@ -814,6 +838,9 @@ Error CommandReader::parse()
        case IComposerClient::Command::SET_RELEASE_FENCES:
            parsed = parseSetReleaseFences(length);
            break;
        case IComposerClient::Command ::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT:
            parsed = parseSetPresentOrValidateDisplayResult(length);
            break;
        default:
            parsed = false;
            break;
@@ -942,6 +969,15 @@ bool CommandReader::parseSetReleaseFences(uint16_t length)
    return true;
}

bool CommandReader::parseSetPresentOrValidateDisplayResult(uint16_t length)
{
    if (length != CommandWriterBase::kPresentOrValidateDisplayResultLength || !mCurrentReturnData) {
        return false;
    }
    mCurrentReturnData->presentOrValidateState = read();
    return true;
}

void CommandReader::resetData()
{
    mErrors.clear();
@@ -1051,6 +1087,16 @@ void CommandReader::takePresentFence(Display display, int* outPresentFence)
    data.presentFence = -1;
}

void CommandReader::takePresentOrValidateStage(Display display, uint32_t* state) {
    auto found = mReturnData.find(display);
    if (found == mReturnData.end()) {
        *state= -1;
        return;
    }
    ReturnData& data = found->second;
    *state = data.presentOrValidateState;
}

} // namespace Hwc2

} // namespace android
+11 −0
Original line number Diff line number Diff line
@@ -93,6 +93,9 @@ public:
    // Get and clear saved present fence.
    void takePresentFence(Display display, int* outPresentFence);

    // Get what stage succeeded during PresentOrValidate: Present or Validate
    void takePresentOrValidateStage(Display display, uint32_t * state);

private:
    void resetData();

@@ -102,6 +105,7 @@ private:
    bool parseSetDisplayRequests(uint16_t length);
    bool parseSetPresentFence(uint16_t length);
    bool parseSetReleaseFences(uint16_t length);
    bool parseSetPresentOrValidateDisplayResult(uint16_t length);

    struct ReturnData {
        uint32_t displayRequests = 0;
@@ -116,6 +120,8 @@ private:

        std::vector<Layer> releasedLayers;
        std::vector<int> releaseFences;

        uint32_t presentOrValidateState;
    };

    std::vector<CommandError> mErrors;
@@ -202,6 +208,11 @@ public:
    Error validateDisplay(Display display, uint32_t* outNumTypes,
            uint32_t* outNumRequests);

    Error presentOrValidateDisplay(Display display, uint32_t* outNumTypes,
                                   uint32_t* outNumRequests,
                                   int* outPresentFence,
                                   uint32_t* state);

    Error setCursorPosition(Display display, Layer layer,
            int32_t x, int32_t y);
    /* see setClientTarget for the purpose of slot */
+22 −0
Original line number Diff line number Diff line
@@ -695,6 +695,28 @@ Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
    return error;
}

Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
                                 sp<android::Fence>* outPresentFence, uint32_t* state) {

    uint32_t numTypes = 0;
    uint32_t numRequests = 0;
    int32_t presentFenceFd = -1;
    auto intError = mDevice.mComposer->presentOrValidateDisplay(mId, &numTypes, &numRequests, &presentFenceFd, state);
    auto error = static_cast<Error>(intError);
    if (error != Error::None && error != Error::HasChanges) {
        return error;
    }

    if (*state == 1) {
        *outPresentFence = new Fence(presentFenceFd);
    }

    if (*state == 0) {
        *outNumTypes = numTypes;
        *outNumRequests = numRequests;
    }
    return error;
}
// For use by Device

int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
+3 −0
Original line number Diff line number Diff line
@@ -255,6 +255,9 @@ public:
    [[clang::warn_unused_result]] Error setVsyncEnabled(Vsync enabled);
    [[clang::warn_unused_result]] Error validate(uint32_t* outNumTypes,
            uint32_t* outNumRequests);
    [[clang::warn_unused_result]] Error presentOrValidate(uint32_t* outNumTypes,
                                                 uint32_t* outNumRequests,
                                                          android::sp<android::Fence>* outPresentFence, uint32_t* state);

    // Other Display methods

+38 −1
Original line number Diff line number Diff line
@@ -455,7 +455,33 @@ status_t HWComposer::prepare(DisplayDevice& displayDevice) {

    uint32_t numTypes = 0;
    uint32_t numRequests = 0;
    auto error = hwcDisplay->validate(&numTypes, &numRequests);

    HWC2::Error error = HWC2::Error::None;

    // First try to skip validate altogether if the HWC supports it.
    displayData.validateWasSkipped = false;
    if (hasCapability(HWC2::Capability::SkipValidate)) {
        sp<android::Fence> outPresentFence;
        uint32_t state = UINT32_MAX;
        error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
        if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
            ALOGV("skipValidate: Failed to Present or Validate");
            return UNKNOWN_ERROR;
        }
        if (state == 1) { //Present Succeeded.
            std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>> releaseFences;
            error = hwcDisplay->getReleaseFences(&releaseFences);
            displayData.releaseFences = std::move(releaseFences);
            displayData.lastPresentFence = outPresentFence;
            displayData.validateWasSkipped = true;
            displayData.presentError = error;
            return NO_ERROR;
        }
        // Present failed but Validate ran.
    } else {
        error = hwcDisplay->validate(&numTypes, &numRequests);
    }
    ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
    if (error != HWC2::Error::None && error != HWC2::Error::HasChanges) {
        ALOGE("prepare: validate failed for display %d: %s (%d)", displayId,
                to_string(error).c_str(), static_cast<int32_t>(error));
@@ -592,6 +618,17 @@ status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) {

    auto& displayData = mDisplayData[displayId];
    auto& hwcDisplay = displayData.hwcDisplay;

    if (displayData.validateWasSkipped) {
        auto error = displayData.presentError;
        if (error != HWC2::Error::None) {
            ALOGE("skipValidate: failed for display %d: %s (%d)",
                  displayId, to_string(error).c_str(), static_cast<int32_t>(error));
            return UNKNOWN_ERROR;
        }
        return NO_ERROR;
    }

    auto error = hwcDisplay->present(&displayData.lastPresentFence);
    if (error != HWC2::Error::None) {
        ALOGE("presentAndGetReleaseFences: failed for display %d: %s (%d)",
Loading