summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-06-22 07:12:51 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-06-22 07:12:51 +0000
commitaec57fad0dc908019ef2ab23c9b4ae86e32a1f32 (patch)
treeea560d0f5a647273c6f7d182bb2137087fb674a0
parent8c778c4ba35242a15ac6f94c82de1a297643ed62 (diff)
parent249c0ae80a6e5690d091294c4447cb3facafbc37 (diff)
downloadnative-aec57fad0dc908019ef2ab23c9b4ae86e32a1f32.tar.gz
release-request-767e2998-9243-43e0-b656-1acb30ac5115-for-git_oc-release-4124637 snap-temp-L74200000076595014
Change-Id: I37efc0a115c061c312d02bc010c0855aefacc621
-rw-r--r--services/surfaceflinger/DisplayHardware/ComposerHal.cpp48
-rw-r--r--services/surfaceflinger/DisplayHardware/ComposerHal.h11
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.cpp22
-rw-r--r--services/surfaceflinger/DisplayHardware/HWC2.h3
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp39
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h3
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;