diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-22 07:12:51 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-06-22 07:12:51 +0000 |
commit | aec57fad0dc908019ef2ab23c9b4ae86e32a1f32 (patch) | |
tree | ea560d0f5a647273c6f7d182bb2137087fb674a0 | |
parent | 8c778c4ba35242a15ac6f94c82de1a297643ed62 (diff) | |
parent | 249c0ae80a6e5690d091294c4447cb3facafbc37 (diff) | |
download | native-aec57fad0dc908019ef2ab23c9b4ae86e32a1f32.tar.gz |
release-request-767e2998-9243-43e0-b656-1acb30ac5115-for-git_oc-release-4124637 snap-temp-L74200000076595014
Change-Id: I37efc0a115c061c312d02bc010c0855aefacc621
6 files changed, 124 insertions, 2 deletions
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 439adc4729..9d16044395 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -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 diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 68d6e6fa13..96dd833cd5 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -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 */ diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index 0366630d94..95689d9c6f 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -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) diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 7f26e56a63..4d9155c249 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -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 diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 42be935c71..913c43f281 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -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)", diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 3eb968d7ce..7463362c35 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -202,6 +202,9 @@ private: // protected by mVsyncLock HWC2::Vsync vsyncEnabled; + + bool validateWasSkipped; + HWC2::Error presentError; }; std::unique_ptr<HWC2::Device> mHwcDevice; |