Merge "EGL: add color space validation"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 089e66c..2f8840b 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -126,7 +126,8 @@
static const std::string kDumpstateBoardPath = "/bugreports/";
static const std::string kDumpstateBoardFiles[] = {
"dumpstate_board.txt",
- "dumpstate_board.bin"
+ // TODO: rename to dumpstate_board.bin once vendors can handle it
+ "modem_log_all.tar"
};
static const int NUM_OF_DUMPS = arraysize(kDumpstateBoardFiles);
diff --git a/include/gui b/include/gui
new file mode 120000
index 0000000..3b796f3
--- /dev/null
+++ b/include/gui
@@ -0,0 +1 @@
+../libs/gui/include/gui
\ No newline at end of file
diff --git a/include/private/gui b/include/private/gui
new file mode 120000
index 0000000..99de2dc
--- /dev/null
+++ b/include/private/gui
@@ -0,0 +1 @@
+../../libs/gui/include/private/gui
\ No newline at end of file
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 204fdb5..3a353c2 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -15,6 +15,7 @@
cc_library_headers {
name: "libbinder_headers",
export_include_dirs: ["include"],
+ vendor_available: true,
}
cc_library {
@@ -74,13 +75,18 @@
"libcutils",
"libutils",
],
+
+ header_libs: [
+ "libbinder_headers",
+ ],
+
export_shared_lib_headers: [
"libbase",
"libutils",
],
- export_include_dirs: [
- "include",
+ export_header_lib_headers: [
+ "libbinder_headers",
],
clang: true,
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index c0ae3d7..afa046d 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -11,9 +11,15 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
+cc_library_headers {
+ name: "libgui_headers",
+ vendor_available: true,
+ export_include_dirs: ["include"],
+}
cc_library_shared {
name: "libgui",
+ vendor_available: true,
clang: true,
cppflags: [
@@ -57,7 +63,7 @@
brillo: {
cflags: ["-DHAVE_NO_SURFACE_FLINGER"],
},
- debuggable: {
+ eng: {
cppflags: [
"-UDEBUG_ONLY_CODE",
"-DDEBUG_ONLY_CODE=1",
@@ -119,6 +125,7 @@
header_libs: [
"libnativebase_headers",
+ "libgui_headers",
],
export_shared_lib_headers: [
@@ -129,6 +136,10 @@
"android.hardware.graphics.bufferqueue@1.0",
],
+ export_header_lib_headers: [
+ "libgui_headers",
+ ],
+
export_include_dirs: [
"include",
],
diff --git a/include/gui/BufferItem.h b/libs/gui/include/gui/BufferItem.h
similarity index 100%
rename from include/gui/BufferItem.h
rename to libs/gui/include/gui/BufferItem.h
diff --git a/include/gui/BufferItemConsumer.h b/libs/gui/include/gui/BufferItemConsumer.h
similarity index 100%
rename from include/gui/BufferItemConsumer.h
rename to libs/gui/include/gui/BufferItemConsumer.h
diff --git a/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h
similarity index 100%
rename from include/gui/BufferQueue.h
rename to libs/gui/include/gui/BufferQueue.h
diff --git a/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h
similarity index 100%
rename from include/gui/BufferQueueConsumer.h
rename to libs/gui/include/gui/BufferQueueConsumer.h
diff --git a/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
similarity index 100%
rename from include/gui/BufferQueueCore.h
rename to libs/gui/include/gui/BufferQueueCore.h
diff --git a/include/gui/BufferQueueDefs.h b/libs/gui/include/gui/BufferQueueDefs.h
similarity index 100%
rename from include/gui/BufferQueueDefs.h
rename to libs/gui/include/gui/BufferQueueDefs.h
diff --git a/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h
similarity index 100%
rename from include/gui/BufferQueueProducer.h
rename to libs/gui/include/gui/BufferQueueProducer.h
diff --git a/include/gui/BufferSlot.h b/libs/gui/include/gui/BufferSlot.h
similarity index 100%
rename from include/gui/BufferSlot.h
rename to libs/gui/include/gui/BufferSlot.h
diff --git a/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h
similarity index 100%
rename from include/gui/ConsumerBase.h
rename to libs/gui/include/gui/ConsumerBase.h
diff --git a/include/gui/CpuConsumer.h b/libs/gui/include/gui/CpuConsumer.h
similarity index 100%
rename from include/gui/CpuConsumer.h
rename to libs/gui/include/gui/CpuConsumer.h
diff --git a/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
similarity index 100%
rename from include/gui/DisplayEventReceiver.h
rename to libs/gui/include/gui/DisplayEventReceiver.h
diff --git a/include/gui/FrameTimestamps.h b/libs/gui/include/gui/FrameTimestamps.h
similarity index 100%
rename from include/gui/FrameTimestamps.h
rename to libs/gui/include/gui/FrameTimestamps.h
diff --git a/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h
similarity index 100%
rename from include/gui/GLConsumer.h
rename to libs/gui/include/gui/GLConsumer.h
diff --git a/include/gui/GuiConfig.h b/libs/gui/include/gui/GuiConfig.h
similarity index 100%
rename from include/gui/GuiConfig.h
rename to libs/gui/include/gui/GuiConfig.h
diff --git a/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h
similarity index 100%
rename from include/gui/IConsumerListener.h
rename to libs/gui/include/gui/IConsumerListener.h
diff --git a/include/gui/IDisplayEventConnection.h b/libs/gui/include/gui/IDisplayEventConnection.h
similarity index 100%
rename from include/gui/IDisplayEventConnection.h
rename to libs/gui/include/gui/IDisplayEventConnection.h
diff --git a/include/gui/IGraphicBufferConsumer.h b/libs/gui/include/gui/IGraphicBufferConsumer.h
similarity index 100%
rename from include/gui/IGraphicBufferConsumer.h
rename to libs/gui/include/gui/IGraphicBufferConsumer.h
diff --git a/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
similarity index 100%
rename from include/gui/IGraphicBufferProducer.h
rename to libs/gui/include/gui/IGraphicBufferProducer.h
diff --git a/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h
similarity index 100%
rename from include/gui/IProducerListener.h
rename to libs/gui/include/gui/IProducerListener.h
diff --git a/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
similarity index 100%
rename from include/gui/ISurfaceComposer.h
rename to libs/gui/include/gui/ISurfaceComposer.h
diff --git a/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
similarity index 100%
rename from include/gui/ISurfaceComposerClient.h
rename to libs/gui/include/gui/ISurfaceComposerClient.h
diff --git a/include/gui/OccupancyTracker.h b/libs/gui/include/gui/OccupancyTracker.h
similarity index 100%
rename from include/gui/OccupancyTracker.h
rename to libs/gui/include/gui/OccupancyTracker.h
diff --git a/include/gui/StreamSplitter.h b/libs/gui/include/gui/StreamSplitter.h
similarity index 100%
rename from include/gui/StreamSplitter.h
rename to libs/gui/include/gui/StreamSplitter.h
diff --git a/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
similarity index 100%
rename from include/gui/Surface.h
rename to libs/gui/include/gui/Surface.h
diff --git a/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
similarity index 100%
rename from include/gui/SurfaceComposerClient.h
rename to libs/gui/include/gui/SurfaceComposerClient.h
diff --git a/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
similarity index 100%
rename from include/gui/SurfaceControl.h
rename to libs/gui/include/gui/SurfaceControl.h
diff --git a/include/gui/bufferqueue/1.0/B2HProducerListener.h b/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h
similarity index 100%
rename from include/gui/bufferqueue/1.0/B2HProducerListener.h
rename to libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h
diff --git a/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
similarity index 100%
rename from include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
rename to libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
diff --git a/include/gui/view/Surface.h b/libs/gui/include/gui/view/Surface.h
similarity index 100%
rename from include/gui/view/Surface.h
rename to libs/gui/include/gui/view/Surface.h
diff --git a/include/private/gui/ComposerService.h b/libs/gui/include/private/gui/ComposerService.h
similarity index 100%
rename from include/private/gui/ComposerService.h
rename to libs/gui/include/private/gui/ComposerService.h
diff --git a/include/private/gui/LayerState.h b/libs/gui/include/private/gui/LayerState.h
similarity index 100%
rename from include/private/gui/LayerState.h
rename to libs/gui/include/private/gui/LayerState.h
diff --git a/include/private/gui/SyncFeatures.h b/libs/gui/include/private/gui/SyncFeatures.h
similarity index 100%
rename from include/private/gui/SyncFeatures.h
rename to libs/gui/include/private/gui/SyncFeatures.h
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index d9cfed7..6630d90 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -89,6 +89,7 @@
header_libs: [
"libnativebase_headers",
+ "libhardware_headers",
],
export_include_dirs: ["include"],
@@ -100,6 +101,7 @@
export_header_lib_headers: [
"libnativebase_headers",
+ "libhardware_headers",
],
}
diff --git a/opengl/Android.bp b/opengl/Android.bp
index c520bda..aec5a95 100644
--- a/opengl/Android.bp
+++ b/opengl/Android.bp
@@ -52,6 +52,12 @@
license: "include/KHR/NOTICE",
}
+cc_library_headers {
+ name: "gl_headers",
+ vendor_available: true,
+ export_include_dirs: ["include"],
+}
+
subdirs = [
"*",
]
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 4e275db..a344636 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -64,6 +64,16 @@
"liblog",
"libdl",
],
+ static_libs: [
+ "libarect",
+ ],
+ header_libs: [
+ "gl_headers",
+ "libsystem_headers",
+ "libhardware_headers",
+ "libnativebase_headers",
+ ],
+ export_header_lib_headers: ["gl_headers"],
// we need to access the private Bionic header <bionic_tls.h>
include_dirs: ["bionic/libc/private"],
@@ -75,6 +85,7 @@
cc_defaults {
name: "egl_libs_defaults",
defaults: ["gl_libs_defaults"],
+ vendor_available: true,
cflags: [
"-DLOG_TAG=\"libEGL\"",
],
@@ -85,6 +96,11 @@
"libnativewindow",
"libbacktrace",
],
+ target: {
+ vendor: {
+ exclude_shared_libs: ["libgraphicsenv"],
+ },
+ },
}
cc_library_static {
@@ -129,6 +145,7 @@
cc_defaults {
name: "gles_libs_defaults",
defaults: ["gl_libs_defaults"],
+ vendor_available: true,
arch: {
arm: {
instruction_set: "arm",
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 6e5c510..32f8caa 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -28,7 +28,9 @@
#include <cutils/properties.h>
#include <log/log.h>
+#ifndef __ANDROID_VNDK__
#include <graphicsenv/GraphicsEnv.h>
+#endif
#include <vndksupport/linker.h>
#include "egl_trace.h"
@@ -477,10 +479,12 @@
ATRACE_CALL();
void* dso = nullptr;
+#ifndef __ANDROID_VNDK__
android_namespace_t* ns = android_getDriverNamespace();
if (ns) {
dso = load_updated_driver(kind, ns);
}
+#endif
if (!dso) {
dso = load_system_driver(kind);
if (!dso)
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index deccb7d..c5feb89 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -2053,8 +2053,15 @@
EGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer *buffer) {
clearError();
+ // AHardwareBuffer_to_ANativeWindowBuffer is a platform-only symbol and thus
+ // this function cannot be implemented when this libEGL is built for
+ // vendors.
+#ifndef __ANDROID_VNDK__
if (!buffer) return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
return const_cast<ANativeWindowBuffer *>(AHardwareBuffer_to_ANativeWindowBuffer(buffer));
+#else
+ return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0);
+#endif
}
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index dc1a4af..579e422 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -26,6 +26,7 @@
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <thread>
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index fad046c..bfe4c09 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -477,7 +477,14 @@
// separately before the next batch of events.
for (int j = 0; j < numEventsDropped; ++j) {
if (scratch[j].type == SENSOR_TYPE_META_DATA) {
- FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
+ ssize_t index = mSensorInfo.indexOfKey(scratch[j].meta_data.sensor);
+ if (index < 0) {
+ ALOGW("%s: sensor 0x%x is not found in connection",
+ __func__, scratch[j].meta_data.sensor);
+ continue;
+ }
+
+ FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
flushInfo.mPendingFlushEventsToSend++;
ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
flushInfo.mPendingFlushEventsToSend);
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index ae628e1..e34fa16 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -553,6 +553,29 @@
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)
{
@@ -770,7 +793,8 @@
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",
@@ -821,6 +845,9 @@
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;
@@ -949,6 +976,15 @@
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();
@@ -1058,6 +1094,16 @@
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 68d6e6f..96dd833 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -93,6 +93,9 @@
// 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 @@
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 @@
std::vector<Layer> releasedLayers;
std::vector<int> releaseFences;
+
+ uint32_t presentOrValidateState;
};
std::vector<CommandError> mErrors;
@@ -202,6 +208,11 @@
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 263ff00..270a732 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -695,6 +695,34 @@
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;
+}
+
+void Display::discardCommands()
+{
+ mDevice.mComposer->resetCommands();
+}
+
// 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 b7376d0..404bb28 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -255,6 +255,15 @@
[[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);
+
+ // Most methods in this class write a command to a command buffer. The
+ // command buffer is implicitly submitted in validate, present, and
+ // presentOrValidate. This method provides a way to discard the commands,
+ // which can be used to discard stale commands.
+ void discardCommands();
// Other Display methods
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 42be935..ac2dde2 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -455,7 +455,34 @@
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) &&
+ !displayData.hasClientComposition) {
+ 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 +619,18 @@
auto& displayData = mDisplayData[displayId];
auto& hwcDisplay = displayData.hwcDisplay;
+
+ if (displayData.validateWasSkipped) {
+ hwcDisplay->discardCommands();
+ 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 3eb968d..7463362 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -202,6 +202,9 @@
// protected by mVsyncLock
HWC2::Vsync vsyncEnabled;
+
+ bool validateWasSkipped;
+ HWC2::Error presentError;
};
std::unique_ptr<HWC2::Device> mHwcDevice;