Merge "SF: Abstract and mock HWC2::Layer"
diff --git a/cmds/dumpstate/README.md b/cmds/dumpstate/README.md
index 273a5a6..1bf55e4 100644
--- a/cmds/dumpstate/README.md
+++ b/cmds/dumpstate/README.md
@@ -23,7 +23,7 @@
## To build, deploy, and take a bugreport
```
-mmm -j frameworks/native/cmds/dumpstate && adb push ${OUT}/system/bin/dumpstate system/bin && adb shell am bug-report
+mmm -j frameworks/native/cmds/dumpstate && adb push ${OUT}/system/bin/dumpstate system/bin && adb push ${OUT}/system/lib64/*dumpstate*.so /system/lib64/ && adb shell am bug-report
```
Make sure that the device is remounted before running the above command.
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index db8848a..2a28627 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -113,6 +113,7 @@
#define LOGPERSIST_DATA_DIR "/data/misc/logd"
#define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
#define PROFILE_DATA_DIR_REF "/data/misc/profiles/ref"
+#define XFRM_STAT_PROC_FILE "/proc/net/xfrm_stat"
#define WLUTIL "/vendor/xbin/wlutil"
#define WMTRACE_DATA_DIR "/data/misc/wmtrace"
@@ -1455,15 +1456,24 @@
add_mountinfo();
DumpIpTablesAsRoot();
- // Capture any IPSec policies in play. No keys are exposed here.
+ // Capture any IPSec policies in play. No keys are exposed here.
RunCommand("IP XFRM POLICY", {"ip", "xfrm", "policy"}, CommandOptions::WithTimeout(10).Build());
+ // Dump IPsec stats. No keys are exposed here.
+ DumpFile("XFRM STATS", XFRM_STAT_PROC_FILE);
+
// Run ss as root so we can see socket marks.
RunCommand("DETAILED SOCKET STATE", {"ss", "-eionptu"}, CommandOptions::WithTimeout(10).Build());
// Run iotop as root to show top 100 IO threads
RunCommand("IOTOP", {"iotop", "-n", "1", "-m", "100"});
+ // Gather shared memory buffer info if the product implements it
+ struct stat st;
+ if (!stat("/product/bin/dmabuf_dump", &st)) {
+ RunCommand("Dmabuf dump", {"/product/bin/dmabuf_dump"});
+ }
+
if (!DropRootUser()) {
return false;
}
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 75fe2d3..a07627a 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -157,10 +157,11 @@
}
void GraphicsEnv::setGpuStats(const std::string& driverPackageName,
- const std::string& driverVersionName,
- const uint64_t driverVersionCode, const std::string& appPackageName) {
+ const std::string& driverVersionName, uint64_t driverVersionCode,
+ const std::string& appPackageName) {
ATRACE_CALL();
+ std::lock_guard<std::mutex> lock(mStatsLock);
ALOGV("setGpuStats:\n"
"\tdriverPackageName[%s]\n"
"\tdriverVersionName[%s]\n"
@@ -169,15 +170,89 @@
driverPackageName.c_str(), driverVersionName.c_str(),
(unsigned long long)driverVersionCode, appPackageName.c_str());
- mGpuStats = {
- .driverPackageName = driverPackageName,
- .driverVersionName = driverVersionName,
- .driverVersionCode = driverVersionCode,
- .appPackageName = appPackageName,
- };
+ mGpuStats.driverPackageName = driverPackageName;
+ mGpuStats.driverVersionName = driverVersionName;
+ mGpuStats.driverVersionCode = driverVersionCode;
+ mGpuStats.appPackageName = appPackageName;
}
-void GraphicsEnv::sendGpuStats() {
+void GraphicsEnv::setDriverToLoad(GraphicsEnv::Driver driver) {
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ switch (driver) {
+ case GraphicsEnv::Driver::GL:
+ case GraphicsEnv::Driver::GL_UPDATED:
+ case GraphicsEnv::Driver::ANGLE: {
+ if (mGpuStats.glDriverToLoad == GraphicsEnv::Driver::NONE) {
+ mGpuStats.glDriverToLoad = driver;
+ break;
+ }
+
+ if (mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE) {
+ mGpuStats.glDriverFallback = driver;
+ }
+ break;
+ }
+ case Driver::VULKAN:
+ case Driver::VULKAN_UPDATED: {
+ if (mGpuStats.vkDriverToLoad == GraphicsEnv::Driver::NONE) {
+ mGpuStats.vkDriverToLoad = driver;
+ break;
+ }
+
+ if (mGpuStats.vkDriverFallback == GraphicsEnv::Driver::NONE) {
+ mGpuStats.vkDriverFallback = driver;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void GraphicsEnv::setDriverLoaded(GraphicsEnv::Api api, bool isLoaded, int64_t driverLoadingTime) {
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ GraphicsEnv::Driver driver = GraphicsEnv::Driver::NONE;
+ bool isIntendedDriverLoaded = false;
+ if (api == GraphicsEnv::Api::API_GL) {
+ driver = mGpuStats.glDriverToLoad;
+ isIntendedDriverLoaded = isLoaded &&
+ ((mGpuStats.glDriverFallback == GraphicsEnv::Driver::NONE) ||
+ (mGpuStats.glDriverToLoad == mGpuStats.glDriverFallback));
+ } else {
+ driver = mGpuStats.vkDriverToLoad;
+ isIntendedDriverLoaded =
+ isLoaded && (mGpuStats.vkDriverFallback == GraphicsEnv::Driver::NONE);
+ }
+
+ sendGpuStatsLocked(driver, isIntendedDriverLoaded, driverLoadingTime);
+}
+
+void GraphicsEnv::clearDriverLoadingInfo(GraphicsEnv::Api api) {
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ if (api == GraphicsEnv::Api::API_GL) {
+ mGpuStats.glDriverToLoad = GraphicsEnv::Driver::NONE;
+ mGpuStats.glDriverFallback = GraphicsEnv::Driver::NONE;
+ }
+}
+
+static sp<IGpuService> getGpuService() {
+ const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
+ if (!binder) {
+ ALOGE("Failed to get gpu service");
+ return nullptr;
+ }
+
+ return interface_cast<IGpuService>(binder);
+}
+
+void GraphicsEnv::sendGpuStatsLocked(GraphicsEnv::Driver driver, bool isDriverLoaded,
+ int64_t driverLoadingTime) {
ATRACE_CALL();
// Do not sendGpuStats for those skipping the GraphicsEnvironment setup
@@ -187,20 +262,20 @@
"\tdriverPackageName[%s]\n"
"\tdriverVersionName[%s]\n"
"\tdriverVersionCode[%llu]\n"
- "\tappPackageName[%s]\n",
+ "\tappPackageName[%s]\n"
+ "\tdriver[%d]\n"
+ "\tisDriverLoaded[%d]\n"
+ "\tdriverLoadingTime[%lld]",
mGpuStats.driverPackageName.c_str(), mGpuStats.driverVersionName.c_str(),
- (unsigned long long)mGpuStats.driverVersionCode, mGpuStats.appPackageName.c_str());
+ (unsigned long long)mGpuStats.driverVersionCode, mGpuStats.appPackageName.c_str(),
+ static_cast<int32_t>(driver), isDriverLoaded, (long long)driverLoadingTime);
- const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu"));
- if (!binder) {
- ALOGE("Failed to get gpu service for [%s]", mGpuStats.appPackageName.c_str());
- return;
+ const sp<IGpuService> gpuService = getGpuService();
+ if (gpuService) {
+ gpuService->setGpuStats(mGpuStats.driverPackageName, mGpuStats.driverVersionName,
+ mGpuStats.driverVersionCode, mGpuStats.appPackageName, driver,
+ isDriverLoaded, driverLoadingTime);
}
-
- interface_cast<IGpuService>(binder)->setGpuStats(mGpuStats.driverPackageName,
- mGpuStats.driverVersionName,
- mGpuStats.driverVersionCode,
- mGpuStats.appPackageName);
}
void* GraphicsEnv::loadLibrary(std::string name) {
diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp
index 762a27b..2a57caf 100644
--- a/libs/graphicsenv/IGpuService.cpp
+++ b/libs/graphicsenv/IGpuService.cpp
@@ -28,8 +28,9 @@
explicit BpGpuService(const sp<IBinder>& impl) : BpInterface<IGpuService>(impl) {}
virtual void setGpuStats(const std::string& driverPackageName,
- const std::string& driverVersionName, const uint64_t driverVersionCode,
- const std::string& appPackageName) {
+ const std::string& driverVersionName, uint64_t driverVersionCode,
+ const std::string& appPackageName, GraphicsEnv::Driver driver,
+ bool isDriverLoaded, int64_t driverLoadingTime) {
Parcel data, reply;
data.writeInterfaceToken(IGpuService::getInterfaceDescriptor());
@@ -37,6 +38,9 @@
data.writeUtf8AsUtf16(driverVersionName);
data.writeUint64(driverVersionCode);
data.writeUtf8AsUtf16(appPackageName);
+ data.writeInt32(static_cast<int32_t>(driver));
+ data.writeBool(isDriverLoaded);
+ data.writeInt64(driverLoadingTime);
remote()->transact(BnGpuService::SET_GPU_STATS, data, &reply);
}
@@ -65,7 +69,18 @@
std::string appPackageName;
if ((status = data.readUtf8FromUtf16(&appPackageName)) != OK) return status;
- setGpuStats(driverPackageName, driverVersionName, driverVersionCode, appPackageName);
+ int32_t driver;
+ if ((status = data.readInt32(&driver)) != OK) return status;
+
+ bool isDriverLoaded;
+ if ((status = data.readBool(&isDriverLoaded)) != OK) return status;
+
+ int64_t driverLoadingTime;
+ if ((status = data.readInt64(&driverLoadingTime)) != OK) return status;
+
+ setGpuStats(driverPackageName, driverVersionName, driverVersionCode, appPackageName,
+ static_cast<GraphicsEnv::Driver>(driver), isDriverLoaded,
+ driverLoadingTime);
return OK;
}
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index c4482b7..d88a5c1 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -28,11 +28,41 @@
struct NativeLoaderNamespace;
class GraphicsEnv {
+public:
+ enum Api {
+ API_GL = 0,
+ API_VK = 1,
+ };
+
+ enum Driver {
+ NONE = 0,
+ GL = 1,
+ GL_UPDATED = 2,
+ VULKAN = 3,
+ VULKAN_UPDATED = 4,
+ ANGLE = 5,
+ };
+
+private:
struct GpuStats {
std::string driverPackageName;
std::string driverVersionName;
uint64_t driverVersionCode;
std::string appPackageName;
+ Driver glDriverToLoad;
+ Driver glDriverFallback;
+ Driver vkDriverToLoad;
+ Driver vkDriverFallback;
+
+ GpuStats()
+ : driverPackageName(""),
+ driverVersionName(""),
+ driverVersionCode(0),
+ appPackageName(""),
+ glDriverToLoad(Driver::NONE),
+ glDriverFallback(Driver::NONE),
+ vkDriverToLoad(Driver::NONE),
+ vkDriverFallback(Driver::NONE) {}
};
public:
@@ -48,8 +78,11 @@
void setDriverPath(const std::string path);
android_namespace_t* getDriverNamespace();
void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
- const uint64_t versionCode, const std::string& appPackageName);
- void sendGpuStats();
+ uint64_t versionCode, const std::string& appPackageName);
+ void setDriverToLoad(Driver driver);
+ void setDriverLoaded(Api api, bool isDriverLoaded, int64_t driverLoadingTime);
+ void clearDriverLoadingInfo(Api api);
+ void sendGpuStatsLocked(Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
bool shouldUseAngle(std::string appName);
bool shouldUseAngle();
@@ -82,6 +115,7 @@
GraphicsEnv() = default;
std::string mDriverPath;
+ std::mutex mStatsLock;
GpuStats mGpuStats;
std::string mAnglePath;
std::string mAngleAppName;
diff --git a/libs/graphicsenv/include/graphicsenv/IGpuService.h b/libs/graphicsenv/include/graphicsenv/IGpuService.h
index 1e74d60..bfde76f 100644
--- a/libs/graphicsenv/include/graphicsenv/IGpuService.h
+++ b/libs/graphicsenv/include/graphicsenv/IGpuService.h
@@ -18,6 +18,7 @@
#include <binder/IInterface.h>
#include <cutils/compiler.h>
+#include <graphicsenv/GraphicsEnv.h>
#include <vector>
@@ -29,12 +30,13 @@
*/
class IGpuService : public IInterface {
public:
- DECLARE_META_INTERFACE(GpuService);
+ DECLARE_META_INTERFACE(GpuService)
// set GPU stats from GraphicsEnvironment.
virtual void setGpuStats(const std::string& driverPackageName,
- const std::string& driverVersionName, const uint64_t driverVersionCode,
- const std::string& appPackageName) = 0;
+ const std::string& driverVersionName, uint64_t driverVersionCode,
+ const std::string& appPackageName, GraphicsEnv::Driver driver,
+ bool isDriverLoaded, int64_t driverLoadingTime) = 0;
};
class BnGpuService : public BnInterface<IGpuService> {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 46b9128..bf2a03d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -383,6 +383,7 @@
other.mListenerCallbacks.clear();
mInputWindowCommands.merge(other.mInputWindowCommands);
+ other.mInputWindowCommands.clear();
return *this;
}
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 8ef4896..994e953 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -122,6 +122,54 @@
return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence);
}
+int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
+ int32_t fence, const ARect* rect, AHardwareBuffer_Planes* outPlanes) {
+ if (!buffer || !outPlanes) return BAD_VALUE;
+
+ if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
+ AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) {
+ ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only "
+ " AHARDWAREBUFFER_USAGE_CPU_* flags are allowed");
+ return BAD_VALUE;
+ }
+
+ usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
+ GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+ Rect bounds;
+ if (!rect) {
+ bounds.set(Rect(gBuffer->getWidth(), gBuffer->getHeight()));
+ } else {
+ bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
+ }
+ int format = AHardwareBuffer_convertFromPixelFormat(uint32_t(gBuffer->getPixelFormat()));
+ memset(outPlanes->planes, 0, sizeof(outPlanes->planes));
+ if (AHardwareBuffer_formatIsYuv(format)) {
+ android_ycbcr yuvData;
+ int result = gBuffer->lockAsyncYCbCr(usage, bounds, &yuvData, fence);
+ if (result == 0) {
+ outPlanes->planeCount = 3;
+ outPlanes->planes[0].data = yuvData.y;
+ outPlanes->planes[0].pixelStride = 1;
+ outPlanes->planes[0].rowStride = yuvData.ystride;
+ outPlanes->planes[1].data = yuvData.cb;
+ outPlanes->planes[1].pixelStride = yuvData.chroma_step;
+ outPlanes->planes[1].rowStride = yuvData.cstride;
+ outPlanes->planes[2].data = yuvData.cr;
+ outPlanes->planes[2].pixelStride = yuvData.chroma_step;
+ outPlanes->planes[2].rowStride = yuvData.cstride;
+ } else {
+ outPlanes->planeCount = 0;
+ }
+ return result;
+ } else {
+ const uint32_t pixelStride = AHardwareBuffer_bytesPerPixel(format);
+ outPlanes->planeCount = 1;
+ outPlanes->planes[0].pixelStride = pixelStride;
+ outPlanes->planes[0].rowStride = gBuffer->getStride() * pixelStride;
+ return gBuffer->lockAsync(usage, usage, bounds, &outPlanes->planes[0].data, fence);
+ }
+}
+
int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) {
if (!buffer) return BAD_VALUE;
@@ -375,6 +423,19 @@
ALOGE_IF(log, "AHARDWAREBUFFER_FORMAT_BLOB cannot be encoded as video");
return false;
}
+ } else if (AHardwareBuffer_formatIsYuv(desc->format)) {
+ if (desc->layers != 1) {
+ ALOGE_IF(log, "Layers must be 1 for YUV formats.");
+ return false;
+ }
+ const uint64_t yuvInvalidGpuMask =
+ AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE |
+ AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
+ if (desc->usage & yuvInvalidGpuMask) {
+ ALOGE_IF(log, "Invalid usage flags specified for YUV format; "
+ "mip-mapping and cube-mapping are not allowed.");
+ return false;
+ }
} else {
if (desc->usage & AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA) {
ALOGE_IF(log, "AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA requires AHARDWAREBUFFER_FORMAT_BLOB");
@@ -474,6 +535,7 @@
case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
case AHARDWAREBUFFER_FORMAT_S8_UINT:
+ case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
// VNDK formats only -- unfortunately we can't differentiate from where we're called
case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM:
case AHARDWAREBUFFER_FORMAT_YV12:
@@ -484,7 +546,6 @@
case AHARDWAREBUFFER_FORMAT_RAW12:
case AHARDWAREBUFFER_FORMAT_RAW_OPAQUE:
case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
- case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
case AHARDWAREBUFFER_FORMAT_YCbCr_422_SP:
case AHARDWAREBUFFER_FORMAT_YCrCb_420_SP:
case AHARDWAREBUFFER_FORMAT_YCbCr_422_I:
@@ -495,6 +556,40 @@
}
}
+bool AHardwareBuffer_formatIsYuv(uint32_t format) {
+ switch (format) {
+ case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
+ case AHARDWAREBUFFER_FORMAT_YV12:
+ case AHARDWAREBUFFER_FORMAT_Y8:
+ case AHARDWAREBUFFER_FORMAT_Y16:
+ case AHARDWAREBUFFER_FORMAT_YCbCr_422_SP:
+ case AHARDWAREBUFFER_FORMAT_YCrCb_420_SP:
+ case AHARDWAREBUFFER_FORMAT_YCbCr_422_I:
+ return true;
+ default:
+ return false;
+ }
+}
+
+uint32_t AHardwareBuffer_bytesPerPixel(uint32_t format) {
+ switch (format) {
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+ case AHARDWAREBUFFER_FORMAT_D16_UNORM:
+ return 2;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM:
+ return 3;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+ case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t hal_format) {
return hal_format;
}
diff --git a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
index bf688f8..ddfd1d1 100644
--- a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
+++ b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
@@ -40,6 +40,12 @@
// whether this AHardwareBuffer format is valid
bool AHardwareBuffer_isValidPixelFormat(uint32_t ahardwarebuffer_format);
+// whether this is a YUV type format
+bool AHardwareBuffer_formatIsYuv(uint32_t format);
+
+// number of bytes per pixel or 0 if unknown or multi-planar
+uint32_t AHardwareBuffer_bytesPerPixel(uint32_t format);
+
// convert AHardwareBuffer format to HAL format (note: this is a no-op)
uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format);
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 2796c75..02c7c1b 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -150,6 +150,14 @@
* OpenGL ES: GL_STENCIL_INDEX8
*/
AHARDWAREBUFFER_FORMAT_S8_UINT = 0x35,
+
+ /**
+ * YUV 420 888 format.
+ * Must have an even width and height. Can be accessed in OpenGL
+ * shaders through an external sampler. Does not support mip-maps
+ * cube-maps or multi-layered textures.
+ */
+ AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,
};
/**
@@ -302,6 +310,24 @@
} AHardwareBuffer_Desc;
/**
+ * Holds data for a single image plane.
+ */
+typedef struct AHardwareBuffer_Plane {
+ void* data; ///< Points to first byte in plane
+ uint32_t pixelStride; ///< Distance in bytes from the color channel of one pixel to the next
+ uint32_t rowStride; ///< Distance in bytes from the first value of one row of the image to
+ /// the first value of the next row.
+} AHardwareBuffer_Plane;
+
+/**
+ * Holds all image planes that contain the pixel data.
+ */
+typedef struct AHardwareBuffer_Planes {
+ uint32_t planeCount; ///< Number of distinct planes
+ AHardwareBuffer_Plane planes[4]; ///< Array of image planes
+} AHardwareBuffer_Planes;
+
+/**
* Opaque handle for a native hardware buffer.
*/
typedef struct AHardwareBuffer AHardwareBuffer;
@@ -323,7 +349,7 @@
AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
/**
* Acquire a reference on the given AHardwareBuffer object.
- *
+ *
* This prevents the object from being deleted until the last reference
* is removed.
*/
@@ -396,6 +422,34 @@
int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
/**
+ * Lock a potentially multi-planar AHardwareBuffer for direct CPU access.
+ *
+ * This function is similar to AHardwareBuffer_lock, but can lock multi-planar
+ * formats. The locked planes are returned in the \a outPlanes argument. Note,
+ * that multi-planar should not be confused with multi-layer images, which this
+ * locking function does not support.
+ *
+ * YUV formats are always represented by three separate planes of data, one for
+ * each color plane. The order of planes in the array is guaranteed such that
+ * plane #0 is always Y, plane #1 is always U (Cb), and plane #2 is always V
+ * (Cr). All other formats are represented by a single plane.
+ *
+ * Additional information always accompanies the buffers, describing the row
+ * stride and the pixel stride for each plane.
+ *
+ * In case the buffer cannot be locked, \a outPlanes will contain zero planes.
+ *
+ * See the AHardwareBuffer_lock documentation for all other locking semantics.
+ *
+ * \return 0 on success. -EINVAL if \a buffer is NULL, the usage flags
+ * are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or the buffer
+ * has more than one layer. Error number if the lock fails for any other
+ * reason.
+ */
+int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
+ int32_t fence, const ARect* rect, AHardwareBuffer_Planes* outPlanes) __INTRODUCED_IN(29);
+
+/**
* Unlock the AHardwareBuffer from direct CPU access.
*
* Must be called after all changes to the buffer are completed by the
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 6c9ec34..3392d7f 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -73,8 +73,6 @@
AHARDWAREBUFFER_FORMAT_RAW_OPAQUE = 0x24,
/* same as HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED */
AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED = 0x22,
- /* same as HAL_PIXEL_FORMAT_YCBCR_420_888 */
- AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,
/* same as HAL_PIXEL_FORMAT_YCBCR_422_SP */
AHARDWAREBUFFER_FORMAT_YCbCr_422_SP = 0x10,
/* same as HAL_PIXEL_FORMAT_YCRCB_420_SP */
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index 604665b..da91a97 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -78,15 +78,14 @@
BufferHubStatus ret;
sp<IBufferClient> client;
BufferTraits bufferTraits;
- IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& status, const auto& outClient,
- const auto& outTraits) {
+ IBufferHub::allocateBuffer_cb allocCb = [&](const auto& status, const auto& outClient,
+ const auto& outTraits) {
ret = status;
client = std::move(outClient);
bufferTraits = std::move(outTraits);
};
- if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), alloc_cb)
- .isOk()) {
+ if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), allocCb).isOk()) {
ALOGE("%s: allocateBuffer transaction failed!", __FUNCTION__);
return;
} else if (ret != BufferHubStatus::NO_ERROR) {
@@ -115,8 +114,8 @@
BufferHubStatus ret;
sp<IBufferClient> client;
BufferTraits bufferTraits;
- IBufferHub::importBuffer_cb import_cb = [&](const auto& status, const auto& outClient,
- const auto& outTraits) {
+ IBufferHub::importBuffer_cb importCb = [&](const auto& status, const auto& outClient,
+ const auto& outTraits) {
ret = status;
client = std::move(outClient);
bufferTraits = std::move(outTraits);
@@ -124,7 +123,7 @@
// hidl_handle(native_handle_t*) simply creates a raw pointer reference withouth ownership
// transfer.
- if (!bufferhub->importBuffer(hidl_handle(token.get()->handle()), import_cb).isOk()) {
+ if (!bufferhub->importBuffer(hidl_handle(token.get()->handle()), importCb).isOk()) {
ALOGE("%s: importBuffer transaction failed!", __FUNCTION__);
return;
} else if (ret != BufferHubStatus::NO_ERROR) {
@@ -210,9 +209,9 @@
// Populate shortcuts to the atomics in metadata.
auto metadataHeader = mMetadata.metadataHeader();
- mBufferState = &metadataHeader->buffer_state;
- mFenceState = &metadataHeader->fence_state;
- mActiveClientsBitMask = &metadataHeader->active_clients_bit_mask;
+ mBufferState = &metadataHeader->bufferState;
+ mFenceState = &metadataHeader->fenceState;
+ mActiveClientsBitMask = &metadataHeader->activeClientsBitMask;
// The C++ standard recommends (but does not require) that lock-free atomic operations are
// also address-free, that is, suitable for communication between processes using shared
// memory.
@@ -230,7 +229,7 @@
mClientStateMask = clientBitMask;
// TODO(b/112012161) Set up shared fences.
- ALOGD("%s: id=%d, buffer_state=%" PRIx32 ".", __FUNCTION__, mId,
+ ALOGD("%s: id=%d, mBufferState=%" PRIx32 ".", __FUNCTION__, mId,
mBufferState->load(std::memory_order_acquire));
return 0;
}
@@ -336,12 +335,12 @@
hidl_handle token;
BufferHubStatus ret;
- IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
+ IBufferClient::duplicate_cb dupCb = [&](const auto& outToken, const auto& status) {
token = std::move(outToken);
ret = status;
};
- if (!mBufferClient->duplicate(dup_cb).isOk()) {
+ if (!mBufferClient->duplicate(dupCb).isOk()) {
ALOGE("%s: duplicate transaction failed!", __FUNCTION__);
return nullptr;
} else if (ret != BufferHubStatus::NO_ERROR) {
diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h
index 5c09032..5ba189c 100644
--- a/libs/ui/include/ui/BufferHubBuffer.h
+++ b/libs/ui/include/ui/BufferHubBuffer.h
@@ -57,7 +57,7 @@
const BufferHubEventFd& eventFd() const { return mEventFd; }
- // Returns the current value of MetadataHeader::buffer_state.
+ // Returns the current value of MetadataHeader::bufferState.
uint32_t bufferState() const { return mBufferState->load(std::memory_order_acquire); }
// A state mask which is unique to a buffer hub client among all its siblings sharing the same
diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h
index 722a060..10f274f 100644
--- a/libs/ui/include/ui/BufferHubDefs.h
+++ b/libs/ui/include/ui/BufferHubDefs.h
@@ -32,7 +32,7 @@
// Single buffer clients (up to 16) ownership signal.
// 32-bit atomic unsigned int.
// Each client takes 2 bits. The first bit locates in the first 16 bits of
-// buffer_state; the second bit locates in the last 16 bits of buffer_state.
+// bufferState; the second bit locates in the last 16 bits of bufferState.
// Client states:
// Gained state 11. Exclusive write state.
// Posted state 10.
@@ -64,9 +64,9 @@
// Returns true if any of the client is in gained state.
static inline bool isAnyClientGained(uint32_t state) {
- uint32_t high_bits = state >> kMaxNumberOfClients;
- uint32_t low_bits = state & kLowbitsMask;
- return high_bits == low_bits && low_bits != 0U;
+ uint32_t highBits = state >> kMaxNumberOfClients;
+ uint32_t lowBits = state & kLowbitsMask;
+ return highBits == lowBits && lowBits != 0U;
}
// Returns true if the input client is in gained state.
@@ -76,34 +76,34 @@
// Returns true if any of the client is in posted state.
static inline bool isAnyClientPosted(uint32_t state) {
- uint32_t high_bits = state >> kMaxNumberOfClients;
- uint32_t low_bits = state & kLowbitsMask;
- uint32_t posted_or_acquired = high_bits ^ low_bits;
- return posted_or_acquired & high_bits;
+ uint32_t highBits = state >> kMaxNumberOfClients;
+ uint32_t lowBits = state & kLowbitsMask;
+ uint32_t postedOrAcquired = highBits ^ lowBits;
+ return postedOrAcquired & highBits;
}
// Returns true if the input client is in posted state.
static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
- uint32_t client_bits = state & client_bit_mask;
- if (client_bits == 0U) return false;
- uint32_t low_bits = client_bits & kLowbitsMask;
- return low_bits == 0U;
+ uint32_t clientBits = state & client_bit_mask;
+ if (clientBits == 0U) return false;
+ uint32_t lowBits = clientBits & kLowbitsMask;
+ return lowBits == 0U;
}
// Return true if any of the client is in acquired state.
static inline bool isAnyClientAcquired(uint32_t state) {
- uint32_t high_bits = state >> kMaxNumberOfClients;
- uint32_t low_bits = state & kLowbitsMask;
- uint32_t posted_or_acquired = high_bits ^ low_bits;
- return posted_or_acquired & low_bits;
+ uint32_t highBits = state >> kMaxNumberOfClients;
+ uint32_t lowBits = state & kLowbitsMask;
+ uint32_t postedOrAcquired = highBits ^ lowBits;
+ return postedOrAcquired & lowBits;
}
// Return true if the input client is in acquired state.
static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
- uint32_t client_bits = state & client_bit_mask;
- if (client_bits == 0U) return false;
- uint32_t high_bits = client_bits & kHighBitsMask;
- return high_bits == 0U;
+ uint32_t clientBits = state & client_bit_mask;
+ if (clientBits == 0U) return false;
+ uint32_t highBits = clientBits & kHighBitsMask;
+ return highBits == 0U;
}
// Returns true if the input client is in released state.
@@ -114,12 +114,12 @@
// Returns the next available buffer client's client_state_masks.
// @params union_bits. Union of all existing clients' client_state_masks.
static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
- uint32_t low_union = union_bits & kLowbitsMask;
- if (low_union == kLowbitsMask) return 0U;
- uint32_t incremented = low_union + 1U;
- uint32_t difference = incremented ^ low_union;
- uint32_t new_low_bit = (difference + 1U) >> 1;
- return new_low_bit + (new_low_bit << kMaxNumberOfClients);
+ uint32_t lowUnion = union_bits & kLowbitsMask;
+ if (lowUnion == kLowbitsMask) return 0U;
+ uint32_t incremented = lowUnion + 1U;
+ uint32_t difference = incremented ^ lowUnion;
+ uint32_t newLowBit = (difference + 1U) >> 1;
+ return newLowBit + (newLowBit << kMaxNumberOfClients);
}
struct __attribute__((aligned(8))) MetadataHeader {
@@ -129,22 +129,22 @@
// platform (include Apps and vendor HAL).
// Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
- // buffer_state.
- std::atomic<uint32_t> buffer_state;
+ // bufferState.
+ std::atomic<uint32_t> bufferState;
- // Every client takes up one bit in fence_state. Only the lower 32 bits are valid. The upper 32
+ // Every client takes up one bit in fenceState. Only the lower 32 bits are valid. The upper 32
// bits are there for easier manipulation, but the value should be ignored.
- std::atomic<uint32_t> fence_state;
+ std::atomic<uint32_t> fenceState;
// Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
- // active_clients_bit_mask.
- std::atomic<uint32_t> active_clients_bit_mask;
+ // activeClientsBitMask.
+ std::atomic<uint32_t> activeClientsBitMask;
// Explicit padding 4 bytes.
uint32_t padding;
// The index of the buffer queue where the buffer belongs to.
- uint64_t queue_index;
+ uint64_t queueIndex;
// Public data format, which should be updated with caution. See more details in dvr_api.h
DvrNativeBufferMetadata metadata;
diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp
index 634bce1..efc1a80 100644
--- a/libs/ui/tests/BufferHubBuffer_test.cpp
+++ b/libs/ui/tests/BufferHubBuffer_test.cpp
@@ -214,8 +214,8 @@
native_handle_t* token = native_handle_create(/*numFds=*/0, /*numInts=*/1);
token->data[0] = 0;
- auto b1 = BufferHubBuffer::import(NativeHandle::create(token, /*ownHandle=*/true));
- native_handle_delete(token);
+ sp<NativeHandle> tokenHandle = NativeHandle::create(token, /*ownHandle=*/true);
+ auto b1 = BufferHubBuffer::import(tokenHandle);
EXPECT_THAT(b1, IsNull());
}
diff --git a/libs/ui/tests/BufferHubMetadata_test.cpp b/libs/ui/tests/BufferHubMetadata_test.cpp
index f02c4fc..eb978ca 100644
--- a/libs/ui/tests/BufferHubMetadata_test.cpp
+++ b/libs/ui/tests/BufferHubMetadata_test.cpp
@@ -51,7 +51,7 @@
// Check if the newly allocated buffer is initialized in released state (i.e.
// state equals to 0U).
- EXPECT_TRUE(mh1->buffer_state.load() == 0U);
+ EXPECT_TRUE(mh1->bufferState.load() == 0U);
EXPECT_TRUE(m2.isValid());
BufferHubDefs::MetadataHeader* mh2 = m2.metadataHeader();
@@ -59,7 +59,7 @@
// Check if the newly allocated buffer is initialized in released state (i.e.
// state equals to 0U).
- EXPECT_TRUE(mh2->buffer_state.load() == 0U);
+ EXPECT_TRUE(mh2->bufferState.load() == 0U);
}
TEST_F(BufferHubMetadataTest, MoveMetadataInvalidatesOldOne) {
diff --git a/libs/vr/libbufferhub/buffer_hub_base.cpp b/libs/vr/libbufferhub/buffer_hub_base.cpp
index b28d101..17930b4 100644
--- a/libs/vr/libbufferhub/buffer_hub_base.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_base.cpp
@@ -122,15 +122,15 @@
// are mapped from shared memory as an atomic object. The std::atomic's
// constructor will not be called so that the original value stored in the
// memory region will be preserved.
- buffer_state_ = &metadata_header_->buffer_state;
+ buffer_state_ = &metadata_header_->bufferState;
ALOGD_IF(TRACE,
"BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx32 ".",
id(), buffer_state_->load(std::memory_order_acquire));
- fence_state_ = &metadata_header_->fence_state;
+ fence_state_ = &metadata_header_->fenceState;
ALOGD_IF(TRACE,
"BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx32 ".", id(),
fence_state_->load(std::memory_order_acquire));
- active_clients_bit_mask_ = &metadata_header_->active_clients_bit_mask;
+ active_clients_bit_mask_ = &metadata_header_->activeClientsBitMask;
ALOGD_IF(
TRACE,
"BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx32
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
index fa39d08..8a490d9 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
@@ -97,8 +97,8 @@
uint32_t usage() const { return buffer_.usage(); }
uint32_t layer_count() const { return buffer_.layer_count(); }
- uint64_t GetQueueIndex() const { return metadata_header_->queue_index; }
- void SetQueueIndex(uint64_t index) { metadata_header_->queue_index = index; }
+ uint64_t GetQueueIndex() const { return metadata_header_->queueIndex; }
+ void SetQueueIndex(uint64_t index) { metadata_header_->queueIndex = index; }
protected:
explicit BufferHubBase(LocalChannelHandle channel);
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 4cafe2b..259242b 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -27,6 +27,7 @@
#include <android/dlext.h>
#include <cutils/properties.h>
#include <log/log.h>
+#include <utils/Timers.h>
#ifndef __ANDROID_VNDK__
#include <graphicsenv/GraphicsEnv.h>
@@ -217,6 +218,7 @@
void* Loader::open(egl_connection_t* cnx)
{
ATRACE_CALL();
+ const nsecs_t openTime = systemTime();
void* dso;
driver_t* hnd = nullptr;
@@ -234,6 +236,8 @@
if (dso) {
hnd = new driver_t(dso);
} else {
+ android::GraphicsEnv::getInstance().clearDriverLoadingInfo(
+ android::GraphicsEnv::Api::API_GL);
// Always load EGL first
dso = load_driver("EGL", cnx, EGL);
if (dso) {
@@ -243,19 +247,30 @@
}
}
+ if (!hnd) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL,
+ false, systemTime() - openTime);
+ }
+
LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation");
cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so");
cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so");
cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so");
+ if (!cnx->libEgl || !cnx->libGles2 || !cnx->libGles1) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL,
+ false, systemTime() - openTime);
+ }
+
LOG_ALWAYS_FATAL_IF(!cnx->libEgl,
"couldn't load system EGL wrapper libraries");
LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1,
"couldn't load system OpenGL ES wrapper libraries");
- android::GraphicsEnv::getInstance().sendGpuStats();
+ android::GraphicsEnv::getInstance().setDriverLoaded(android::GraphicsEnv::Api::API_GL, true,
+ systemTime() - openTime);
return (void*)hnd;
}
@@ -591,17 +606,21 @@
void* dso = nullptr;
android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
if (ns) {
+ android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::ANGLE);
dso = load_angle(kind, ns, cnx);
}
#ifndef __ANDROID_VNDK__
if (!dso) {
android_namespace_t* ns = android::GraphicsEnv::getInstance().getDriverNamespace();
if (ns) {
+ android::GraphicsEnv::getInstance().setDriverToLoad(
+ android::GraphicsEnv::Driver::GL_UPDATED);
dso = load_updated_driver(kind, ns);
}
}
#endif
if (!dso) {
+ android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
dso = load_system_driver(kind);
if (!dso)
return nullptr;
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index ade08e7..7a3472f 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -241,8 +241,8 @@
MetadataHeader* metadataHeader =
const_cast<BufferHubMetadata*>(&node->metadata())->metadataHeader();
- const uint32_t state = metadataHeader->buffer_state.load(std::memory_order_acquire);
- const uint64_t index = metadataHeader->queue_index;
+ const uint32_t state = metadataHeader->bufferState.load(std::memory_order_acquire);
+ const uint64_t index = metadataHeader->queueIndex;
stream << std::right;
stream << std::setw(6) << /*Id=*/node->id();
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp
index 1efb27e..04ca649 100644
--- a/services/bufferhub/BufferNode.cpp
+++ b/services/bufferhub/BufferNode.cpp
@@ -15,9 +15,9 @@
// Using placement new here to reuse shared memory instead of new allocation
// Initialize the atomic variables to zero.
BufferHubDefs::MetadataHeader* metadataHeader = mMetadata.metadataHeader();
- mBufferState = new (&metadataHeader->buffer_state) std::atomic<uint32_t>(0);
- mFenceState = new (&metadataHeader->fence_state) std::atomic<uint32_t>(0);
- mActiveClientsBitMask = new (&metadataHeader->active_clients_bit_mask) std::atomic<uint32_t>(0);
+ mBufferState = new (&metadataHeader->bufferState) std::atomic<uint32_t>(0);
+ mFenceState = new (&metadataHeader->fenceState) std::atomic<uint32_t>(0);
+ mActiveClientsBitMask = new (&metadataHeader->activeClientsBitMask) std::atomic<uint32_t>(0);
// The C++ standard recommends (but does not require) that lock-free atomic operations are
// also address-free, that is, suitable for communication between processes using shared
// memory.
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index 68c185c..8a9778a 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -38,8 +38,9 @@
GpuService::GpuService() = default;
void GpuService::setGpuStats(const std::string& driverPackageName,
- const std::string& driverVersionName, const uint64_t driverVersionCode,
- const std::string& appPackageName) {
+ const std::string& driverVersionName, uint64_t driverVersionCode,
+ const std::string& appPackageName, GraphicsEnv::Driver driver,
+ bool isDriverLoaded, int64_t driverLoadingTime) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mStateLock);
@@ -47,9 +48,13 @@
"\tdriverPackageName[%s]\n"
"\tdriverVersionName[%s]\n"
"\tdriverVersionCode[%llu]\n"
- "\tappPackageName[%s]\n",
+ "\tappPackageName[%s]\n"
+ "\tdriver[%d]\n"
+ "\tisDriverLoaded[%d]\n"
+ "\tdriverLoadingTime[%lld]",
driverPackageName.c_str(), driverVersionName.c_str(),
- (unsigned long long)driverVersionCode, appPackageName.c_str());
+ (unsigned long long)driverVersionCode, appPackageName.c_str(),
+ static_cast<int32_t>(driver), isDriverLoaded, (long long)driverLoadingTime);
}
status_t GpuService::shellCommand(int /*in*/, int out, int err, std::vector<String16>& args) {
diff --git a/services/gpuservice/GpuService.h b/services/gpuservice/GpuService.h
index 5304fa1..2756557 100644
--- a/services/gpuservice/GpuService.h
+++ b/services/gpuservice/GpuService.h
@@ -38,7 +38,8 @@
private:
// IGpuService interface
void setGpuStats(const std::string& driverPackageName, const std::string& driverVersionName,
- const uint64_t driverVersionCode, const std::string& appPackageName);
+ uint64_t driverVersionCode, const std::string& appPackageName,
+ GraphicsEnv::Driver driver, bool isDriverLoaded, int64_t driverLoadingTime);
// GpuStats access must be protected by mStateLock
std::mutex mStateLock;
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 9702fb2..7ff8b20 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2673,7 +2673,7 @@
policyFlags |= POLICY_FLAG_TRUSTED;
android::base::Timer t;
- mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
+ mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
std::to_string(t.duration().count()).c_str());
@@ -2821,6 +2821,7 @@
size_t pointerCount = motionEvent->getPointerCount();
const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
int32_t actionButton = motionEvent->getActionButton();
+ int32_t displayId = motionEvent->getDisplayId();
if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
return INPUT_EVENT_INJECTION_FAILED;
}
@@ -2828,7 +2829,7 @@
if (!(policyFlags & POLICY_FLAG_FILTERED)) {
nsecs_t eventTime = motionEvent->getEventTime();
android::base::Timer t;
- mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
+ mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
std::to_string(t.duration().count()).c_str());
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 2d8df5c..595b01d 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -245,7 +245,8 @@
* This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
* should be dispatched to applications.
*/
- virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
+ virtual void interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
+ uint32_t& policyFlags) = 0;
/* Allows the policy a chance to intercept a key before dispatching. */
virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token,
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index f84aa34..1a1ae21 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -4550,7 +4550,8 @@
mPointerController->setButtonState(mCurrentRawState.buttonState);
mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords,
mCurrentCookedState.cookedPointerData.idToIndex,
- mCurrentCookedState.cookedPointerData.touchingIdBits);
+ mCurrentCookedState.cookedPointerData.touchingIdBits,
+ mViewport.displayId);
}
if (!mCurrentMotionAborted) {
@@ -5314,7 +5315,8 @@
if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
mPointerController->setSpots(mPointerGesture.currentGestureCoords,
mPointerGesture.currentGestureIdToIndex,
- mPointerGesture.currentGestureIdBits);
+ mPointerGesture.currentGestureIdBits,
+ mPointerController->getDisplayId());
}
} else {
mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index bc0f1f9..0ff28e4 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -94,7 +94,7 @@
* pressed (not hovering).
*/
virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
- BitSet32 spotIdBits) = 0;
+ BitSet32 spotIdBits, int32_t displayId) = 0;
/* Removes all spots. */
virtual void clearSpots() = 0;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 0f987c3..3b6fe52 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -138,7 +138,7 @@
virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
}
- virtual void interceptMotionBeforeQueueing(nsecs_t, uint32_t&) {
+ virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
}
virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 84c5ad6..fbacb9b 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -103,6 +103,10 @@
return mDisplayId;
}
+ const std::map<int32_t, std::vector<int32_t>>& getSpots() {
+ return mSpotsByDisplay;
+ }
+
private:
virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
*outMinX = mMinX;
@@ -130,11 +134,22 @@
virtual void setPresentation(Presentation) {
}
- virtual void setSpots(const PointerCoords*, const uint32_t*, BitSet32) {
+ virtual void setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
+ int32_t displayId) {
+ std::vector<int32_t> newSpots;
+ // Add spots for fingers that are down.
+ for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ newSpots.push_back(id);
+ }
+
+ mSpotsByDisplay[displayId] = newSpots;
}
virtual void clearSpots() {
}
+
+ std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay;
};
@@ -228,6 +243,10 @@
mConfig.pointerCapture = enabled;
}
+ void setShowTouches(bool enabled) {
+ mConfig.showTouches = enabled;
+ }
+
private:
DisplayViewport createDisplayViewport(int32_t displayId, int32_t width, int32_t height,
int32_t orientation, const std::string& uniqueId, std::optional<uint8_t> physicalPort,
@@ -6315,4 +6334,85 @@
ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
}
+TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
+ // Setup the first touch screen device.
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ prepareAxes(POSITION | ID | SLOT);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ addMapperAndConfigure(mapper);
+
+ // Create the second touch screen device, and enable multi fingers.
+ const std::string USB2 = "USB2";
+ const int32_t SECOND_DEVICE_ID = 2;
+ InputDeviceIdentifier identifier;
+ identifier.name = DEVICE_NAME;
+ identifier.location = USB2;
+ InputDevice* device2 = new InputDevice(mFakeContext, SECOND_DEVICE_ID, DEVICE_GENERATION,
+ DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
+ mFakeEventHub->addDevice(SECOND_DEVICE_ID, DEVICE_NAME, 0 /*classes*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
+ 0 /*flat*/, 0 /*fuzz*/);
+ mFakeEventHub->setAbsoluteAxisValue(SECOND_DEVICE_ID, ABS_MT_SLOT, 0 /*value*/);
+ mFakeEventHub->addConfigurationProperty(SECOND_DEVICE_ID, String8("touch.deviceType"),
+ String8("touchScreen"));
+
+ // Setup the second touch screen device.
+ MultiTouchInputMapper* mapper2 = new MultiTouchInputMapper(device2);
+ device2->addMapper(mapper2);
+ device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/);
+ device2->reset(ARBITRARY_TIME);
+
+ // Setup PointerController.
+ sp<FakePointerController> fakePointerController = new FakePointerController();
+ mFakePolicy->setPointerController(mDevice->getId(), fakePointerController);
+ mFakePolicy->setPointerController(SECOND_DEVICE_ID, fakePointerController);
+
+ // Setup policy for associated displays and show touches.
+ const uint8_t hdmi1 = 0;
+ const uint8_t hdmi2 = 1;
+ mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
+ mFakePolicy->addInputPortAssociation(USB2, hdmi2);
+ mFakePolicy->setShowTouches(true);
+
+ // Create displays.
+ prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
+ prepareSecondaryDisplay(ViewportType::VIEWPORT_EXTERNAL, hdmi2);
+
+ // Default device will reconfigure above, need additional reconfiguration for another device.
+ device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+ InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+ // Two fingers down at default display.
+ int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
+ processPosition(mapper, x1, y1);
+ processId(mapper, 1);
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processId(mapper, 2);
+ processSync(mapper);
+
+ std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
+ fakePointerController->getSpots().find(DISPLAY_ID);
+ ASSERT_TRUE(iter != fakePointerController->getSpots().end());
+ ASSERT_EQ(size_t(2), iter->second.size());
+
+ // Two fingers down at second display.
+ processPosition(mapper2, x1, y1);
+ processId(mapper2, 1);
+ processSlot(mapper2, 1);
+ processPosition(mapper2, x2, y2);
+ processId(mapper2, 2);
+ processSync(mapper2);
+
+ iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
+ ASSERT_TRUE(iter != fakePointerController->getSpots().end());
+ ASSERT_EQ(size_t(2), iter->second.size());
+}
+
} // namespace android
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index c077b68..b4952aa 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -380,8 +380,7 @@
return true;
}
-bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
- const sp<Fence>& releaseFence) {
+bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) {
ATRACE_CALL();
bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);
@@ -420,7 +419,7 @@
return false;
}
- status_t err = updateTexImage(recomputeVisibleRegions, latchTime, releaseFence);
+ status_t err = updateTexImage(recomputeVisibleRegions, latchTime);
if (err != NO_ERROR) {
return false;
}
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index d358bae..e3b10fc 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -93,11 +93,7 @@
// the visible regions need to be recomputed (this is a fairly heavy
// operation, so this should be set only if needed). Typically this is used
// to figure out if the content or size of a surface has changed.
- // If there was a GL composition step rendering the previous frame, then
- // releaseFence will be populated with a native fence that fires when
- // composition has completed.
- bool latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
- const sp<Fence>& releaseFence) override;
+ bool latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override;
bool isBufferLatched() const override { return mRefreshPending; }
@@ -142,8 +138,7 @@
virtual void setFilteringEnabled(bool enabled) = 0;
virtual status_t bindTextureImage() = 0;
- virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
- const sp<Fence>& flushFence) = 0;
+ virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) = 0;
virtual status_t updateActiveBuffer() = 0;
virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index 7ed8184..6866e5c 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -100,8 +100,7 @@
status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, nsecs_t expectedPresentTime,
bool* autoRefresh, bool* queuedBuffer,
- uint64_t maxFrameNumber,
- const sp<Fence>& releaseFence) {
+ uint64_t maxFrameNumber) {
ATRACE_CALL();
BLC_LOGV("updateTexImage");
Mutex::Autolock lock(mMutex);
@@ -146,7 +145,7 @@
}
// Release the previous buffer.
- err = updateAndReleaseLocked(item, &mPendingRelease, releaseFence);
+ err = updateAndReleaseLocked(item, &mPendingRelease);
if (err != NO_ERROR) {
return err;
}
@@ -224,25 +223,11 @@
}
status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item,
- PendingRelease* pendingRelease,
- const sp<Fence>& releaseFence) {
+ PendingRelease* pendingRelease) {
status_t err = NO_ERROR;
int slot = item.mSlot;
- // Do whatever sync ops we need to do before releasing the old slot.
- if (slot != mCurrentTexture) {
- err = syncForReleaseLocked(releaseFence);
- if (err != NO_ERROR) {
- // Release the buffer we just acquired. It's not safe to
- // release the old buffer, so instead we just drop the new frame.
- // As we are still under lock since acquireBuffer, it is safe to
- // release by slot.
- releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer);
- return err;
- }
- }
-
BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture,
mCurrentTextureBuffer != nullptr ? mCurrentTextureBuffer->handle : 0, slot,
mSlots[slot].mGraphicBuffer->handle);
@@ -298,30 +283,6 @@
return mRE.bindExternalTextureBuffer(mTexName, mCurrentTextureBuffer, mCurrentFence, false);
}
-status_t BufferLayerConsumer::syncForReleaseLocked(const sp<Fence>& releaseFence) {
- BLC_LOGV("syncForReleaseLocked");
-
- if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
- if (mRE.useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
- // TODO(alecmouri): fail further upstream if the fence is invalid
- if (!releaseFence->isValid()) {
- BLC_LOGE("syncForReleaseLocked: failed to flush RenderEngine");
- return UNKNOWN_ERROR;
- }
- status_t err =
- addReleaseFenceLocked(mCurrentTexture, mCurrentTextureBuffer, releaseFence);
- if (err != OK) {
- BLC_LOGE("syncForReleaseLocked: error adding release fence: "
- "%s (%d)",
- strerror(-err), err);
- return err;
- }
- }
- }
-
- return OK;
-}
-
void BufferLayerConsumer::getTransformMatrix(float mtx[16]) {
Mutex::Autolock lock(mMutex);
memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix));
diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h
index e2ef399..e2a6d2e 100644
--- a/services/surfaceflinger/BufferLayerConsumer.h
+++ b/services/surfaceflinger/BufferLayerConsumer.h
@@ -92,8 +92,7 @@
// used to reject the newly acquired buffer. It also does not bind the
// RenderEngine texture until bindTextureImage is called.
status_t updateTexImage(BufferRejecter* rejecter, nsecs_t expectedPresentTime,
- bool* autoRefresh, bool* queuedBuffer, uint64_t maxFrameNumber,
- const sp<Fence>& releaseFence);
+ bool* autoRefresh, bool* queuedBuffer, uint64_t maxFrameNumber);
// See BufferLayerConsumer::bindTextureImageLocked().
status_t bindTextureImage();
@@ -212,8 +211,7 @@
// completion of the method will instead be returned to the caller, so that
// it may call releaseBufferLocked itself later.
status_t updateAndReleaseLocked(const BufferItem& item,
- PendingRelease* pendingRelease = nullptr,
- const sp<Fence>& releaseFence = Fence::NO_FENCE);
+ PendingRelease* pendingRelease = nullptr);
// Binds mTexName and the current buffer to TEXTURE_EXTERNAL target.
// If the bind succeeds, this calls doFenceWait.
@@ -244,12 +242,6 @@
// access the current texture buffer.
status_t doFenceWaitLocked() const;
- // syncForReleaseLocked performs the synchronization needed to release the
- // current slot from RenderEngine. If needed it will set the current
- // slot's fence to guard against a producer accessing the buffer before
- // the outstanding accesses have completed.
- status_t syncForReleaseLocked(const sp<Fence>& releaseFence);
-
// The default consumer usage flags that BufferLayerConsumer always sets on its
// BufferQueue instance; these will be OR:d with any additional flags passed
// from the BufferLayerConsumer user. In particular, BufferLayerConsumer will always
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index cdcbcd9..b3e2a4b 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -225,8 +225,7 @@
return mConsumer->bindTextureImage();
}
-status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
- const sp<Fence>& releaseFence) {
+status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) {
// This boolean is used to make sure that SurfaceFlinger's shadow copy
// of the buffer queue isn't modified when the buffer queue is returning
// BufferItem's that weren't actually queued. This can happen in shared
@@ -237,9 +236,11 @@
getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
getTransformToDisplayInverse(), mFreezeGeometryUpdates);
- const nsecs_t expectedPresentTime = mFlinger->mUseScheduler
- ? mFlinger->mScheduler->expectedPresentTime()
- : mFlinger->mPrimaryDispSync->expectedPresentTime();
+ nsecs_t expectedPresentTime = mFlinger->mScheduler->expectedPresentTime();
+
+ if (isRemovedFromCurrentState()) {
+ expectedPresentTime = 0;
+ }
// updateTexImage() below might drop the some buffers at the head of the queue if there is a
// buffer behind them which is timely to be presented. However this buffer may not be signaled
@@ -259,9 +260,9 @@
}
const uint64_t maxFrameNumberToAcquire =
std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber);
- status_t updateResult =
- mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
- maxFrameNumberToAcquire, releaseFence);
+
+ status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh,
+ &queuedBuffer, maxFrameNumberToAcquire);
if (updateResult == BufferQueue::PRESENT_LATER) {
// Producer doesn't want buffer to be displayed yet. Signal a
// layer update so we check again at the next opportunity.
@@ -388,7 +389,7 @@
void BufferQueueLayer::fakeVsync() {
mRefreshPending = false;
bool ignored = false;
- latchBuffer(ignored, systemTime(), Fence::NO_FENCE);
+ latchBuffer(ignored, systemTime());
usleep(16000);
releasePendingBuffer(systemTime());
}
@@ -397,10 +398,8 @@
// Add this buffer from our internal queue tracker
{ // Autolock scope
// Report the requested present time to the Scheduler.
- if (mFlinger->mUseScheduler) {
- mFlinger->mScheduler->addFramePresentTimeForLayer(item.mTimestamp,
- item.mIsAutoTimestamp, mName.c_str());
- }
+ mFlinger->mScheduler->addFramePresentTimeForLayer(item.mTimestamp, item.mIsAutoTimestamp,
+ mName.c_str());
Mutex::Autolock lock(mQueueItemLock);
// Reset the frame number tracker when we receive the first buffer after
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index 30107e2..fbb8c14 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -91,8 +91,7 @@
void setFilteringEnabled(bool enabled) override;
status_t bindTextureImage() override;
- status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
- const sp<Fence>& releaseFence) override;
+ status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) override;
status_t updateActiveBuffer() override;
status_t updateFrameNumber(nsecs_t latchTime) override;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index a3d5b89..e48c41e 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -473,8 +473,7 @@
return engine.bindExternalTextureBuffer(mTextureName, s.buffer, s.acquireFence, false);
}
-status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
- const sp<Fence>& releaseFence) {
+status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime) {
const State& s(getDrawingState());
if (!s.buffer) {
@@ -516,59 +515,7 @@
handle->latchTime = latchTime;
}
- // Handle sync fences
- if (SyncFeatures::getInstance().useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
- // TODO(alecmouri): Fail somewhere upstream if the fence is invalid.
- if (!releaseFence->isValid()) {
- mFlinger->mTimeStats->onDestroy(layerID);
- return UNKNOWN_ERROR;
- }
-
- // Check status of fences first because merging is expensive.
- // Merging an invalid fence with any other fence results in an
- // invalid fence.
- auto currentStatus = s.acquireFence->getStatus();
- if (currentStatus == Fence::Status::Invalid) {
- ALOGE("Existing fence has invalid state");
- mFlinger->mTimeStats->onDestroy(layerID);
- return BAD_VALUE;
- }
-
- auto incomingStatus = releaseFence->getStatus();
- if (incomingStatus == Fence::Status::Invalid) {
- ALOGE("New fence has invalid state");
- mDrawingState.acquireFence = releaseFence;
- mFlinger->mTimeStats->onDestroy(layerID);
- return BAD_VALUE;
- }
-
- // If both fences are signaled or both are unsignaled, we need to merge
- // them to get an accurate timestamp.
- if (currentStatus == incomingStatus) {
- char fenceName[32] = {};
- snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber);
- sp<Fence> mergedFence =
- Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence);
- if (!mergedFence.get()) {
- ALOGE("failed to merge release fences");
- // synchronization is broken, the best we can do is hope fences
- // signal in order so the new fence will act like a union
- mDrawingState.acquireFence = releaseFence;
- mFlinger->mTimeStats->onDestroy(layerID);
- return BAD_VALUE;
- }
- mDrawingState.acquireFence = mergedFence;
- } else if (incomingStatus == Fence::Status::Unsignaled) {
- // If one fence has signaled and the other hasn't, the unsignaled
- // fence will approximately correspond with the correct timestamp.
- // There's a small race if both fences signal at about the same time
- // and their statuses are retrieved with unfortunate timing. However,
- // by this point, they will have both signaled and only the timestamp
- // will be slightly off; any dependencies after this point will
- // already have been met.
- mDrawingState.acquireFence = releaseFence;
- }
- } else {
+ if (!SyncFeatures::getInstance().useNativeFenceSync()) {
// Bind the new buffer to the GL texture.
//
// Older devices require the "implicit" synchronization provided
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index a97f0a4..0b03f49 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -125,8 +125,7 @@
void setFilteringEnabled(bool enabled) override;
status_t bindTextureImage() override;
- status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
- const sp<Fence>& releaseFence) override;
+ status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) override;
status_t updateActiveBuffer() override;
status_t updateFrameNumber(nsecs_t latchTime) override;
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 0ca3759..e54b460 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -17,7 +17,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include <binder/PermissionCache.h>
#include <binder/IPCThreadState.h>
#include <private/android_filesystem_config.h>
diff --git a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
index 6e6f3c0..130ab1d 100644
--- a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
@@ -303,7 +303,7 @@
}
// add all known HDR combinations
- for (auto intent : sHdrRenderIntents) {
+ for (auto intent : hdrRenderIntents) {
for (auto mode : sHdrColorModes) {
addColorMode(hwcColorModes, mode, intent);
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
index d20fdda..9215884 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
@@ -146,6 +146,8 @@
return ProfileFactory()
.setHasWideColorGamut(true)
.addHdrType(Hdr::HDR10)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE)
.addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, VendorRenderIntent)
.build();
}
@@ -154,6 +156,8 @@
return ProfileFactory()
.setHasWideColorGamut(true)
.addHdrType(Hdr::HDR10)
+ .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::COLORIMETRIC)
+ .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::ENHANCE)
.addColorModeRenderIntent(ColorMode::SRGB, VendorRenderIntent)
.build();
}
@@ -166,6 +170,16 @@
.build();
}
+ static impl::DisplayColorProfile createProfileWithDisplayP3ColorModeSupport() {
+ return ProfileFactory()
+ .setHasWideColorGamut(true)
+ .addHdrType(Hdr::HLG)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_P3, RenderIntent::ENHANCE)
+ .addColorModeRenderIntent(ColorMode::DISPLAY_P3, VendorRenderIntent)
+ .build();
+ }
+
private:
bool mHasWideColorGamut = false;
std::vector<Hdr> mSupportedHdrTypes;
@@ -348,7 +362,7 @@
auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
- EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
+ EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
@@ -358,7 +372,7 @@
auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
- EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
+ EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
EXPECT_TRUE(profile.hasRenderIntent(VendorRenderIntent));
@@ -414,47 +428,37 @@
void checkGetBestColorMode(
DisplayColorProfile& profile,
- const std::array<std::tuple<Dataspace, ColorMode, RenderIntent>, 25>& expected) {
+ const std::array<std::tuple<Dataspace, ColorMode, RenderIntent>, 15>& expected) {
using ArgsType = std::tuple<Dataspace, RenderIntent>;
// These are the combinations of dataspaces and render intents that could be
// passed to RenderSurface::getBestColorMode()
- const std::array<std::tuple<Dataspace, RenderIntent>, 25> kArgs = {
+ const std::array<std::tuple<Dataspace, RenderIntent>, 15> kArgs = {
/* clang-format off */
// Non-HDR combinations
/* 0 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
/* 1 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::ENHANCE},
- /* 2 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
- /* 3 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::TONE_MAP_ENHANCE}, // Vendor explicit setting
- /* 4 */ ArgsType{Dataspace::DISPLAY_BT2020, VendorRenderIntent}, // Vendor explicit setting
+ /* 2 */ ArgsType{Dataspace::DISPLAY_BT2020, VendorRenderIntent}, // Vendor explicit setting
- /* 5 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::COLORIMETRIC},
- /* 6 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::ENHANCE},
- /* 7 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
- /* 8 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::TONE_MAP_ENHANCE}, // Vendor explicit setting
- /* 9 */ ArgsType{Dataspace::DISPLAY_P3, VendorRenderIntent}, // Vendor explicit setting
+ /* 3 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 4 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::ENHANCE},
+ /* 5 */ ArgsType{Dataspace::DISPLAY_P3, VendorRenderIntent}, // Vendor explicit setting
- /* 10 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::COLORIMETRIC},
- /* 11 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::ENHANCE},
- /* 12 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
- /* 13 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::TONE_MAP_ENHANCE}, // Vendor explicit setting
- /* 14 */ ArgsType{Dataspace::V0_SRGB, VendorRenderIntent}, // Vendor explicit setting
+ /* 6 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::COLORIMETRIC},
+ /* 7 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::ENHANCE},
+ /* 8 */ ArgsType{Dataspace::V0_SRGB, VendorRenderIntent}, // Vendor explicit setting
// HDR combinations
- /* 15 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_COLORIMETRIC},
- /* 16 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_ENHANCE},
- /* 17 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::COLORIMETRIC}, // Vendor explicit setting
- /* 18 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::ENHANCE}, // Vendor explicit setting
- /* 19 */ ArgsType{Dataspace::BT2020_PQ, VendorRenderIntent}, // Vendor explicit setting
+ /* 9 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_COLORIMETRIC},
+ /* 10 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_ENHANCE},
+ /* 11 */ ArgsType{Dataspace::BT2020_PQ, VendorRenderIntent}, // Vendor explicit setting
- /* 20 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_COLORIMETRIC},
- /* 21 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_ENHANCE},
- /* 22 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::COLORIMETRIC}, // Vendor explicit setting
- /* 23 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::ENHANCE}, // Vendor explicit setting
- /* 24 */ ArgsType{Dataspace::BT2020_HLG, VendorRenderIntent}, // Vendor explicit setting
+ /* 12 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_COLORIMETRIC},
+ /* 13 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_ENHANCE},
+ /* 14 */ ArgsType{Dataspace::BT2020_HLG, VendorRenderIntent}, // Vendor explicit setting
/* clang-format on */
};
@@ -473,38 +477,28 @@
// Note: This table of expected values goes with the table of arguments
// used in checkGetBestColorMode.
using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
- std::array<Result, 25> expectedResults = {
+ std::array<Result, 15> expectedResults = {
/* clang-format off */
/* 0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
/* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 10 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 15 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 16 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
- /* 20 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 21 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
/* clang-format on */
};
@@ -517,37 +511,27 @@
// Note: This table of expected values goes with the table of arguments
// used in checkGetBestColorMode.
using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
- std::array<Result, 25> expectedResults = {
+ std::array<Result, 15> expectedResults = {
/* clang-format off */
/* 0 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 1 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+ /* 1 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
/* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 5 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+ /* 3 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+ /* 4 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
+ /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 6 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 7 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
/* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 9 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
/* 10 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 11 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 12 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
/* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
- /* 15 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 16 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
- /* 20 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 21 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
- /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* clang-format on */
};
@@ -560,37 +544,61 @@
// Note: This table of expected values goes with the table of arguments
// used in checkGetBestColorMode.
using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
- std::array<Result, 25> expectedResults = {
+ std::array<Result, 15> expectedResults = {
/* clang-format off */
/* 0 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+ /* 1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 2 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
- /* 5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 3 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
/* 6 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+ /* 7 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 8 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+ /* 9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
/* 10 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 11 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 14 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+ /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 15 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 16 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 12 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* clang-format on */
+ };
- /* 20 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 21 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
- /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ checkGetBestColorMode(profile, expectedResults);
+}
+
+TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasDisplayP3Support) {
+ auto profile = ProfileFactory::createProfileWithDisplayP3ColorModeSupport();
+
+ // Note: This table of expected values goes with the table of arguments
+ // used in checkGetBestColorMode.
+ using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
+ std::array<Result, 15> expectedResults = {
+ /* clang-format off */
+ /* 0 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 1 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+ // TODO(b/124317977): There is bug here.
+ /* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 3 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 4 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+ /* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 6 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 7 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+ /* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 9 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 10 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 12 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+ /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* clang-format on */
};
@@ -603,37 +611,27 @@
// Note: This table of expected values goes with the table of arguments
// used in checkGetBestColorMode.
using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
- std::array<Result, 25> expectedResults = {
+ std::array<Result, 15> expectedResults = {
/* clang-format off */
/* 0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
/* 5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
/* 6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
/* 8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 9 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+ /* 10 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+ /* 11 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
- /* 15 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
- /* 16 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
- /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
- /* 20 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
- /* 21 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
- /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
- /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* 12 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+ /* 14 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
/* clang-format on */
};
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 8ae057f..36885db 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -534,8 +534,7 @@
* operation, so this should be set only if needed). Typically this is used
* to figure out if the content or size of a surface has changed.
*/
- virtual bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
- const sp<Fence>& /*releaseFence*/) {
+ virtual bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/) {
return {};
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index af439f7..30fba3c 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -189,6 +189,49 @@
}
}
+void Scheduler::resyncToHardwareVsync(bool makeAvailable, nsecs_t period) {
+ {
+ std::lock_guard<std::mutex> lock(mHWVsyncLock);
+ if (makeAvailable) {
+ mHWVsyncAvailable = makeAvailable;
+ } else if (!mHWVsyncAvailable) {
+ // Hardware vsync is not currently available, so abort the resync
+ // attempt for now
+ return;
+ }
+ }
+
+ if (period <= 0) {
+ return;
+ }
+
+ setVsyncPeriod(period);
+}
+
+ResyncCallback Scheduler::makeResyncCallback(GetVsyncPeriod&& getVsyncPeriod) {
+ std::weak_ptr<VsyncState> ptr = mPrimaryVsyncState;
+ return [ptr, getVsyncPeriod = std::move(getVsyncPeriod)]() {
+ if (const auto vsync = ptr.lock()) {
+ vsync->resync(getVsyncPeriod);
+ }
+ };
+}
+
+void Scheduler::VsyncState::resync(const GetVsyncPeriod& getVsyncPeriod) {
+ static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
+
+ const nsecs_t now = systemTime();
+ const nsecs_t last = lastResyncTime.exchange(now);
+
+ if (now - last > kIgnoreDelay) {
+ scheduler.resyncToHardwareVsync(false, getVsyncPeriod());
+ }
+}
+
+void Scheduler::setRefreshSkipCount(int count) {
+ mPrimaryDispSync->setRefreshSkipCount(count);
+}
+
void Scheduler::setVsyncPeriod(const nsecs_t period) {
std::lock_guard<std::mutex> lock(mHWVsyncLock);
mPrimaryDispSync->reset();
@@ -229,16 +272,6 @@
mPrimaryDispSync->setIgnorePresentFences(ignore);
}
-void Scheduler::makeHWSyncAvailable(bool makeAvailable) {
- std::lock_guard<std::mutex> lock(mHWVsyncLock);
- mHWVsyncAvailable = makeAvailable;
-}
-
-bool Scheduler::getHWSyncAvailable() {
- std::lock_guard<std::mutex> lock(mHWVsyncLock);
- return mHWVsyncAvailable;
-}
-
nsecs_t Scheduler::expectedPresentTime() {
return mPrimaryDispSync->expectedPresentTime();
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index d628e40..7b5278c 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -37,6 +37,7 @@
class Scheduler {
public:
using ExpiredIdleTimerCallback = std::function<void()>;
+ using GetVsyncPeriod = std::function<nsecs_t()>;
using ResetIdleTimerCallback = std::function<void()>;
// Enum to indicate whether to start the transaction early, or at vsync time.
@@ -67,6 +68,16 @@
const std::unique_ptr<EventThread> thread;
};
+ // Stores per-display state about VSYNC.
+ struct VsyncState {
+ explicit VsyncState(Scheduler& scheduler) : scheduler(scheduler) {}
+
+ void resync(const GetVsyncPeriod&);
+
+ Scheduler& scheduler;
+ std::atomic<nsecs_t> lastResyncTime = 0;
+ };
+
explicit Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function);
virtual ~Scheduler();
@@ -104,13 +115,13 @@
void enableHardwareVsync();
void disableHardwareVsync(bool makeUnavailable);
- void setVsyncPeriod(const nsecs_t period);
+ void resyncToHardwareVsync(bool makeAvailable, nsecs_t period);
+ // Creates a callback for resyncing.
+ ResyncCallback makeResyncCallback(GetVsyncPeriod&& getVsyncPeriod);
+ void setRefreshSkipCount(int count);
void addResyncSample(const nsecs_t timestamp);
void addPresentFence(const std::shared_ptr<FenceTime>& fenceTime);
void setIgnorePresentFences(bool ignore);
- void makeHWSyncAvailable(bool makeAvailable);
- // returns HWSyncAvailable flag to SF would enable HW vsync based on this
- bool getHWSyncAvailable();
nsecs_t expectedPresentTime();
// Adds the present time for given layer to the history of present times.
void addFramePresentTimeForLayer(const nsecs_t framePresentTime, bool isAutoTimestamp,
@@ -133,6 +144,8 @@
impl::EventThread::InterceptVSyncsCallback interceptCallback);
private:
+ friend class TestableScheduler;
+
// Creates a connection on the given EventThread and forwards the given callbacks.
sp<EventThreadConnection> createConnectionInternal(EventThread*, ResyncCallback&&);
@@ -150,6 +163,8 @@
void resetTimerCallback();
// Function that is called when the timer expires.
void expiredTimerCallback();
+ // Sets vsync period.
+ void setVsyncPeriod(const nsecs_t period);
// If fences from sync Framework are supported.
const bool mHasSyncFramework;
@@ -167,6 +182,7 @@
std::mutex mHWVsyncLock;
bool mPrimaryHWVsyncEnabled GUARDED_BY(mHWVsyncLock);
bool mHWVsyncAvailable GUARDED_BY(mHWVsyncLock);
+ const std::shared_ptr<VsyncState> mPrimaryVsyncState{std::make_shared<VsyncState>(*this)};
std::unique_ptr<DispSync> mPrimaryDispSync;
std::unique_ptr<EventControlThread> mEventControlThread;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b68f053..e3f75e1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -292,8 +292,6 @@
mLastTransactionTime(0),
mForceFullDamage(false),
mTimeStats(factory.createTimeStats()),
- mPrimaryHWVsyncEnabled(false),
- mHWVsyncAvailable(false),
mRefreshStartTime(0),
mHasPoweredOff(false),
mNumLayers(0),
@@ -395,14 +393,8 @@
auto listSize = property_get_int32("debug.sf.max_igbp_list_size", int32_t(defaultListSize));
mMaxGraphicBufferProducerListSize = (listSize > 0) ? size_t(listSize) : defaultListSize;
- property_get("debug.sf.use_scheduler", value, "0");
- mUseScheduler = atoi(value);
-
- if (!mUseScheduler) {
- mPrimaryDispSync =
- getFactory().createDispSync("PrimaryDispSync", SurfaceFlinger::hasSyncFramework,
- SurfaceFlinger::dispSyncPresentTimeOffset);
- }
+ property_get("debug.sf.use_90Hz", value, "0");
+ mUse90Hz = atoi(value);
const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
mVsyncModulator.setPhaseOffsets(early, gl, late);
@@ -624,52 +616,28 @@
ALOGI("Phase offset NS: %" PRId64 "", mPhaseOffsets->getCurrentAppOffset());
Mutex::Autolock _l(mStateLock);
-
- auto resyncCallback = makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
-
// start the EventThread
- if (mUseScheduler) {
- mScheduler = getFactory().createScheduler(
- [this](bool enabled) { setPrimaryVsyncEnabled(enabled); });
+ mScheduler =
+ getFactory().createScheduler([this](bool enabled) { setPrimaryVsyncEnabled(enabled); });
+ auto resyncCallback =
+ mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
- // TODO(b/113612090): Currently we assume that if scheduler is turned on, then the refresh
- // rate is 90. Once b/122905403 is completed, this should be updated accordingly.
+ mAppConnectionHandle =
+ mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(),
+ resyncCallback,
+ impl::EventThread::InterceptVSyncsCallback());
+ mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(),
+ resyncCallback, [this](nsecs_t timestamp) {
+ mInterceptor->saveVSyncEvent(timestamp);
+ });
+
+ mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
+ mVsyncModulator.setSchedulerAndHandles(mScheduler.get(), mAppConnectionHandle.get(),
+ mSfConnectionHandle.get());
+
+ if (mUse90Hz) {
mPhaseOffsets->setRefreshRateType(
scheduler::RefreshRateConfigs::RefreshRateType::PERFORMANCE);
-
- mAppConnectionHandle =
- mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(),
- resyncCallback,
- impl::EventThread::InterceptVSyncsCallback());
- mSfConnectionHandle =
- mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(),
- resyncCallback, [this](nsecs_t timestamp) {
- mInterceptor->saveVSyncEvent(timestamp);
- });
-
- mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
- mVsyncModulator.setSchedulerAndHandles(mScheduler.get(), mAppConnectionHandle.get(),
- mSfConnectionHandle.get());
- } else {
- mEventThreadSource =
- std::make_unique<DispSyncSource>(mPrimaryDispSync.get(),
- mPhaseOffsets->getCurrentAppOffset(), true, "app");
- mEventThread =
- std::make_unique<impl::EventThread>(mEventThreadSource.get(),
- impl::EventThread::InterceptVSyncsCallback(),
- "appEventThread");
- mSfEventThreadSource =
- std::make_unique<DispSyncSource>(mPrimaryDispSync.get(),
- mPhaseOffsets->getCurrentSfOffset(), true, "sf");
-
- mSFEventThread =
- std::make_unique<impl::EventThread>(mSfEventThreadSource.get(),
- [this](nsecs_t timestamp) {
- mInterceptor->saveVSyncEvent(timestamp);
- },
- "sfEventThread");
- mEventQueue->setEventThread(mSFEventThread.get(), std::move(resyncCallback));
- mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
}
// Get a RenderEngine for the given display / config (can't fail)
@@ -719,11 +687,6 @@
}
}
- if (!mUseScheduler) {
- mEventControlThread = getFactory().createEventControlThread(
- [this](bool enabled) { setPrimaryVsyncEnabled(enabled); });
- }
-
// initialize our drawing state
mDrawingState = mCurrentState;
@@ -742,21 +705,18 @@
ALOGE("Run StartPropertySetThread failed!");
}
- if (mUseScheduler) {
- mScheduler->setExpiredIdleTimerCallback([this] {
- Mutex::Autolock lock(mStateLock);
- setRefreshRateTo(RefreshRateType::DEFAULT);
- });
- mScheduler->setResetIdleTimerCallback([this] {
- Mutex::Autolock lock(mStateLock);
- setRefreshRateTo(RefreshRateType::PERFORMANCE);
- });
+ mScheduler->setExpiredIdleTimerCallback([this] {
+ Mutex::Autolock lock(mStateLock);
+ setRefreshRateTo(RefreshRateType::DEFAULT);
+ });
+ mScheduler->setResetIdleTimerCallback([this] {
+ Mutex::Autolock lock(mStateLock);
+ setRefreshRateTo(RefreshRateType::PERFORMANCE);
+ });
- mRefreshRateStats =
- std::make_unique<scheduler::RefreshRateStats>(getHwComposer().getConfigs(
- *display->getId()),
- mTimeStats);
- }
+ mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(getHwComposer().getConfigs(
+ *display->getId()),
+ mTimeStats);
ALOGV("Done initializing");
}
@@ -773,6 +733,9 @@
property_get("persist.sys.sf.native_mode", value, "0");
mDisplayColorSetting = static_cast<DisplayColorSetting>(atoi(value));
+
+ property_get("persist.sys.sf.color_mode", value, "0");
+ mForceColorMode = static_cast<ColorMode>(atoi(value));
}
void SurfaceFlinger::startBootAnim() {
@@ -942,12 +905,7 @@
return BAD_VALUE;
}
- if (mUseScheduler) {
- mScheduler->getDisplayStatInfo(stats);
- } else {
- stats->vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
- stats->vsyncPeriod = mPrimaryDispSync->getPeriod();
- }
+ mScheduler->getDisplayStatInfo(stats);
return NO_ERROR;
}
@@ -1013,6 +971,7 @@
if (!display) {
return;
}
+
const auto displayId = display->getId();
LOG_ALWAYS_FATAL_IF(!displayId);
@@ -1026,9 +985,7 @@
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mActiveConfigLock);
- if (mUseScheduler) {
- mRefreshRateStats->setConfigMode(mUpcomingActiveConfig.configId);
- }
+ mRefreshRateStats->setConfigMode(mUpcomingActiveConfig.configId);
const auto display = getDisplayDeviceLocked(mUpcomingActiveConfig.displayToken);
display->setActiveConfig(mUpcomingActiveConfig.configId);
@@ -1036,7 +993,7 @@
mSetActiveConfigState = SetActiveConfigState::NONE;
ATRACE_INT("SetActiveConfigState", mSetActiveConfigState);
- resyncToHardwareVsync(true, getVsyncPeriod());
+ mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
ATRACE_INT("ActiveConfigMode", mUpcomingActiveConfig.configId);
}
@@ -1257,7 +1214,8 @@
return;
}
- auto resyncCallback = makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
+ auto resyncCallback =
+ mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
// TODO(akrulec): Part of the Injector should be refactored, so that it
// can be passed to Scheduler.
@@ -1273,7 +1231,8 @@
mEventQueue->setEventThread(mInjectorEventThread.get(), std::move(resyncCallback));
} else {
ALOGV("VSync Injections disabled");
- mEventQueue->setEventThread(mSFEventThread.get(), std::move(resyncCallback));
+ mEventQueue->setEventThread(mScheduler->getEventThread(mSfConnectionHandle),
+ std::move(resyncCallback));
}
mInjectVSyncs = enable;
@@ -1341,23 +1300,15 @@
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
ISurfaceComposer::VsyncSource vsyncSource) {
- auto resyncCallback = makeResyncCallback([this] {
+ auto resyncCallback = mScheduler->makeResyncCallback([this] {
Mutex::Autolock lock(mStateLock);
return getVsyncPeriod();
});
- if (mUseScheduler) {
- const auto& handle = vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle
- : mAppConnectionHandle;
+ const auto& handle =
+ vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle;
- return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback));
- } else {
- if (vsyncSource == eVsyncSourceSurfaceFlinger) {
- return mSFEventThread->createEventConnection(resyncCallback, ResetIdleTimerCallback());
- } else {
- return mEventThread->createEventConnection(resyncCallback, ResetIdleTimerCallback());
- }
- }
+ return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback));
}
// ----------------------------------------------------------------------------
@@ -1409,79 +1360,6 @@
return config ? config->getVsyncPeriod() : 0;
}
-void SurfaceFlinger::enableHardwareVsync() {
- assert(!mUseScheduler);
- Mutex::Autolock _l(mHWVsyncLock);
- if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
- mPrimaryDispSync->beginResync();
- mEventControlThread->setVsyncEnabled(true);
- mPrimaryHWVsyncEnabled = true;
- }
-}
-
-void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable, nsecs_t period) {
- Mutex::Autolock _l(mHWVsyncLock);
- // TODO(b/113612090): This is silly, but necessary evil until we turn on the flag for good.
- if (mUseScheduler) {
- if (makeAvailable) {
- mScheduler->makeHWSyncAvailable(true);
- } else if (!mScheduler->getHWSyncAvailable()) {
- // Hardware vsync is not currently available, so abort the resync
- // attempt for now
- return;
- }
- } else {
- if (makeAvailable) {
- mHWVsyncAvailable = true;
- } else if (!mHWVsyncAvailable) {
- // Hardware vsync is not currently available, so abort the resync
- // attempt for now
- return;
- }
- }
-
- if (period <= 0) {
- return;
- }
-
- if (mUseScheduler) {
- mScheduler->setVsyncPeriod(period);
- } else {
- mPrimaryDispSync->reset();
- mPrimaryDispSync->setPeriod(period);
-
- if (!mPrimaryHWVsyncEnabled) {
- mPrimaryDispSync->beginResync();
- mEventControlThread->setVsyncEnabled(true);
- mPrimaryHWVsyncEnabled = true;
- }
- }
-}
-
-void SurfaceFlinger::disableHardwareVsync(bool makeUnavailable) {
- assert(!mUseScheduler);
- Mutex::Autolock _l(mHWVsyncLock);
- if (mPrimaryHWVsyncEnabled) {
- mEventControlThread->setVsyncEnabled(false);
- mPrimaryDispSync->endResync();
- mPrimaryHWVsyncEnabled = false;
- }
- if (makeUnavailable) {
- mHWVsyncAvailable = false;
- }
-}
-
-void SurfaceFlinger::VsyncState::resync(const GetVsyncPeriod& getVsyncPeriod) {
- static constexpr nsecs_t kIgnoreDelay = ms2ns(500);
-
- const nsecs_t now = systemTime();
- const nsecs_t last = lastResyncTime.exchange(now);
-
- if (now - last > kIgnoreDelay) {
- flinger.resyncToHardwareVsync(false, getVsyncPeriod());
- }
-}
-
void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
int64_t timestamp) {
ATRACE_NAME("SF onVsync");
@@ -1501,23 +1379,7 @@
return;
}
- if (mUseScheduler) {
- mScheduler->addResyncSample(timestamp);
- } else {
- bool needsHwVsync = false;
- { // Scope for the lock
- Mutex::Autolock _l(mHWVsyncLock);
- if (mPrimaryHWVsyncEnabled) {
- needsHwVsync = mPrimaryDispSync->addResyncSample(timestamp);
- }
- }
-
- if (needsHwVsync) {
- enableHardwareVsync();
- } else {
- disableHardwareVsync(false);
- }
- }
+ mScheduler->addResyncSample(timestamp);
}
void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) {
@@ -1618,11 +1480,7 @@
// Note: it is assumed the caller holds |mStateLock| when this is called
void SurfaceFlinger::resetDisplayState() {
- if (mUseScheduler) {
- mScheduler->disableHardwareVsync(true);
- } else {
- disableHardwareVsync(true);
- }
+ mScheduler->disableHardwareVsync(true);
// Clear the drawing state so that the logic inside of
// handleTransactionLocked will fire. It will determine the delta between
// mCurrentState and mDrawingState and re-apply all changes when we make the
@@ -1689,20 +1547,14 @@
// The present fences returned from vr_hwc are not an accurate
// representation of vsync times.
- if (mUseScheduler) {
- mScheduler->setIgnorePresentFences(getHwComposer().isUsingVrComposer() ||
- !hasSyncFramework);
- } else {
- mPrimaryDispSync->setIgnorePresentFences(getHwComposer().isUsingVrComposer() ||
- !hasSyncFramework);
- }
+ mScheduler->setIgnorePresentFences(getHwComposer().isUsingVrComposer() || !hasSyncFramework);
// Use phase of 0 since phase is not known.
// Use latency of 0, which will snap to the ideal latency.
DisplayStatInfo stats{0 /* vsyncTime */, vsyncPeriod};
setCompositorTimingSnapped(stats, 0);
- resyncToHardwareVsync(false, vsyncPeriod);
+ mScheduler->resyncToHardwareVsync(false, vsyncPeriod);
mRepaintEverything = true;
setTransactionFlags(eDisplayTransactionNeeded);
@@ -1716,10 +1568,9 @@
break;
}
- if (mUseScheduler) {
- // This call is made each time SF wakes up and creates a new frame.
- mScheduler->incrementFrameCounter();
- }
+ // This call is made each time SF wakes up and creates a new frame.
+ mScheduler->incrementFrameCounter();
+
bool frameMissed = !mHadClientComposition && mPreviousPresentFence != Fence::NO_FENCE &&
(mPreviousPresentFence->getStatus() == Fence::Status::Unsignaled);
mFrameMissedCount += frameMissed;
@@ -1810,18 +1661,6 @@
mHadClientComposition || getHwComposer().hasClientComposition(displayId);
}
- // Setup RenderEngine sync fences if native sync is supported.
- if (getRenderEngine().useNativeFenceSync()) {
- if (mHadClientComposition) {
- base::unique_fd flushFence(getRenderEngine().flush());
- ALOGE_IF(flushFence < 0, "Failed to flush RenderEngine!");
- getBE().flushFence = new Fence(std::move(flushFence));
- } else {
- // Cleanup for hygiene.
- getBE().flushFence = Fence::NO_FENCE;
- }
- }
-
mVsyncModulator.onRefreshed(mHadClientComposition);
getBE().mEndOfFrameCompositionInfo = std::move(getBE().mCompositionInfo);
@@ -2170,12 +2009,7 @@
DisplayStatInfo stats;
DEFINE_STACK_GUARD(stats);
- if (mUseScheduler) {
- mScheduler->getDisplayStatInfo(&stats);
- } else {
- stats.vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
- stats.vsyncPeriod = mPrimaryDispSync->getPeriod();
- }
+ mScheduler->getDisplayStatInfo(&stats);
ASSERT_ON_STACK_GUARD();
@@ -2208,27 +2042,14 @@
if (presentFenceTime->isValid()) {
ASSERT_ON_STACK_GUARD();
- if (mUseScheduler) {
- mScheduler->addPresentFence(presentFenceTime);
- ASSERT_ON_STACK_GUARD();
- } else {
- if (mPrimaryDispSync->addPresentFence(presentFenceTime)) {
- enableHardwareVsync();
- } else {
- disableHardwareVsync(false);
- }
- ASSERT_ON_STACK_GUARD();
- }
+ mScheduler->addPresentFence(presentFenceTime);
+ ASSERT_ON_STACK_GUARD();
}
if (!hasSyncFramework) {
if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) &&
displayDevice->isPoweredOn()) {
- if (mUseScheduler) {
- mScheduler->enableHardwareVsync();
- } else {
- enableHardwareVsync();
- }
+ mScheduler->enableHardwareVsync();
}
}
@@ -2491,6 +2312,17 @@
auto* profile = display->getCompositionDisplay()->getDisplayColorProfile();
+ switch (mForceColorMode) {
+ case ColorMode::SRGB:
+ bestDataSpace = Dataspace::V0_SRGB;
+ break;
+ case ColorMode::DISPLAY_P3:
+ bestDataSpace = Dataspace::DISPLAY_P3;
+ break;
+ default:
+ break;
+ }
+
// respect hdrDataSpace only when there is no legacy HDR support
const bool isHdr =
hdrDataSpace != Dataspace::UNKNOWN && !profile->hasLegacyHdrSupport(hdrDataSpace);
@@ -2720,13 +2552,8 @@
}
void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected) {
- if (mUseScheduler) {
- mScheduler->hotplugReceived(mAppConnectionHandle, displayId, connected);
- mScheduler->hotplugReceived(mSfConnectionHandle, displayId, connected);
- } else {
- mEventThread->onHotplugReceived(displayId, connected);
- mSFEventThread->onHotplugReceived(displayId, connected);
- }
+ mScheduler->hotplugReceived(mAppConnectionHandle, displayId, connected);
+ mScheduler->hotplugReceived(mSfConnectionHandle, displayId, connected);
}
sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
@@ -3078,6 +2905,7 @@
});
}
+ commitInputWindowCommands();
commitTransaction();
}
@@ -3108,6 +2936,11 @@
mInputFlinger->setInputWindows(inputHandles);
}
+void SurfaceFlinger::commitInputWindowCommands() {
+ mInputWindowCommands.merge(mPendingInputWindowCommands);
+ mPendingInputWindowCommands.clear();
+}
+
void SurfaceFlinger::executeInputWindowCommands() {
for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) {
if (transferTouchFocusCommand.fromToken != nullptr &&
@@ -3136,16 +2969,8 @@
void SurfaceFlinger::latchAndReleaseBuffer(const sp<Layer>& layer) {
if (layer->hasReadyFrame()) {
- nsecs_t expectedPresentTime;
- if (mUseScheduler) {
- expectedPresentTime = mScheduler->expectedPresentTime();
- } else {
- expectedPresentTime = mPrimaryDispSync->expectedPresentTime();
- }
- if (layer->shouldPresentNow(expectedPresentTime)) {
- bool ignored = false;
- layer->latchBuffer(ignored, systemTime(), Fence::NO_FENCE);
- }
+ bool ignored = false;
+ layer->latchBuffer(ignored, systemTime());
}
layer->releasePendingBuffer(systemTime());
}
@@ -3374,11 +3199,7 @@
if (layer->hasReadyFrame()) {
frameQueued = true;
nsecs_t expectedPresentTime;
- if (mUseScheduler) {
- expectedPresentTime = mScheduler->expectedPresentTime();
- } else {
- expectedPresentTime = mPrimaryDispSync->expectedPresentTime();
- }
+ expectedPresentTime = mScheduler->expectedPresentTime();
if (layer->shouldPresentNow(expectedPresentTime)) {
mLayersWithQueuedFrames.push_back(layer);
} else {
@@ -3395,7 +3216,7 @@
Mutex::Autolock lock(mStateLock);
for (auto& layer : mLayersWithQueuedFrames) {
- if (layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence)) {
+ if (layer->latchBuffer(visibleRegions, latchTime)) {
mLayersPendingRefresh.push_back(layer);
}
layer->useSurfaceDamage();
@@ -3405,11 +3226,6 @@
}
}
- // Clear the renderengine fence here...
- // downstream code assumes that a cleared fence == NO_FENCE, so reassign to
- // clear instead of sp::clear.
- getBE().flushFence = Fence::NO_FENCE;
-
mVisibleRegionsDirty |= visibleRegions;
// If we will need to wake up at some time in the future to deal with a
@@ -3682,11 +3498,12 @@
auto& [applyToken, transactionQueue] = *it;
while (!transactionQueue.empty()) {
- const auto& [states, displays, flags, desiredPresentTime] = transactionQueue.front();
+ const auto& [states, displays, flags, desiredPresentTime, privileged] =
+ transactionQueue.front();
if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
break;
}
- applyTransactionState(states, displays, flags, mInputWindowCommands);
+ applyTransactionState(states, displays, flags, mPendingInputWindowCommands, privileged);
transactionQueue.pop();
}
@@ -3719,12 +3536,7 @@
bool SurfaceFlinger::transactionIsReadyToBeApplied(int64_t desiredPresentTime,
const Vector<ComposerState>& states) {
- nsecs_t expectedPresentTime;
- if (mUseScheduler) {
- expectedPresentTime = mScheduler->expectedPresentTime();
- } else {
- expectedPresentTime = mPrimaryDispSync->expectedPresentTime();
- }
+ nsecs_t expectedPresentTime = mScheduler->expectedPresentTime();
// Do not present if the desiredPresentTime has not passed unless it is more than one second
// in the future. We ignore timestamps more than 1 second in the future for stability reasons.
if (desiredPresentTime >= 0 && desiredPresentTime >= expectedPresentTime &&
@@ -3750,6 +3562,9 @@
const InputWindowCommands& inputWindowCommands,
int64_t desiredPresentTime) {
ATRACE_CALL();
+
+ bool privileged = callingThreadHasUnscopedSurfaceFlingerAccess();
+
Mutex::Autolock _l(mStateLock);
if (containsAnyInvalidClientState(states)) {
@@ -3759,17 +3574,19 @@
// If its TransactionQueue already has a pending TransactionState or if it is pending
if (mTransactionQueues.find(applyToken) != mTransactionQueues.end() ||
!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
- mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime);
+ mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
+ privileged);
setTransactionFlags(eTransactionNeeded);
return;
}
- applyTransactionState(states, displays, flags, inputWindowCommands);
+ applyTransactionState(states, displays, flags, inputWindowCommands, privileged);
}
void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
- const InputWindowCommands& inputWindowCommands) {
+ const InputWindowCommands& inputWindowCommands,
+ bool privileged) {
uint32_t transactionFlags = 0;
if (flags & eAnimation) {
@@ -3794,7 +3611,7 @@
uint32_t clientStateFlags = 0;
for (const ComposerState& state : states) {
- clientStateFlags |= setClientStateLocked(state);
+ clientStateFlags |= setClientStateLocked(state, privileged);
}
// If the state doesn't require a traversal and there are callbacks, send them now
if (!(clientStateFlags & eTraversalNeeded)) {
@@ -3892,7 +3709,7 @@
return flags;
}
-bool callingThreadHasUnscopedSurfaceFlingerAccess() {
+bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess() {
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
@@ -3903,7 +3720,8 @@
return true;
}
-uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState) {
+uint32_t SurfaceFlinger::setClientStateLocked(const ComposerState& composerState,
+ bool privileged) {
const layer_state_t& s = composerState.state;
sp<Client> client(static_cast<Client*>(composerState.client.get()));
@@ -4004,7 +3822,7 @@
// of cropped areas, we need to prevent non-root clients without permission ACCESS_SURFACE_FLINGER
// (a.k.a. everyone except WindowManager and tests) from setting non rectangle preserving
// transformations.
- if (layer->setMatrix(s.matrix, callingThreadHasUnscopedSurfaceFlingerAccess()))
+ if (layer->setMatrix(s.matrix, privileged))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eTransparentRegionChanged) {
@@ -4154,7 +3972,7 @@
flags |= eTraversalNeeded;
}
- mInputWindowCommands.merge(inputWindowCommands);
+ mPendingInputWindowCommands.merge(inputWindowCommands);
return flags;
}
@@ -4370,7 +4188,7 @@
d.width = 0;
d.height = 0;
displays.add(d);
- setTransactionState(state, displays, 0, nullptr, mInputWindowCommands, -1);
+ setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1);
setPowerModeInternal(display, HWC_POWER_MODE_NORMAL);
@@ -4415,12 +4233,8 @@
// Turn on the display
getHwComposer().setPowerMode(*displayId, mode);
if (display->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
- if (mUseScheduler) {
- mScheduler->onScreenAcquired(mAppConnectionHandle);
- } else {
- mEventThread->onScreenAcquired();
- }
- resyncToHardwareVsync(true, getVsyncPeriod());
+ mScheduler->onScreenAcquired(mAppConnectionHandle);
+ mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
}
mVisibleRegionsDirty = true;
@@ -4440,16 +4254,8 @@
}
if (display->isPrimary() && currentMode != HWC_POWER_MODE_DOZE_SUSPEND) {
- if (mUseScheduler) {
- mScheduler->disableHardwareVsync(true);
- } else {
- disableHardwareVsync(true); // also cancels any in-progress resync
- }
- if (mUseScheduler) {
- mScheduler->onScreenReleased(mAppConnectionHandle);
- } else {
- mEventThread->onScreenReleased();
- }
+ mScheduler->disableHardwareVsync(true);
+ mScheduler->onScreenReleased(mAppConnectionHandle);
}
getHwComposer().setPowerMode(*displayId, mode);
@@ -4460,26 +4266,14 @@
// Update display while dozing
getHwComposer().setPowerMode(*displayId, mode);
if (display->isPrimary() && currentMode == HWC_POWER_MODE_DOZE_SUSPEND) {
- if (mUseScheduler) {
- mScheduler->onScreenAcquired(mAppConnectionHandle);
- } else {
- mEventThread->onScreenAcquired();
- }
- resyncToHardwareVsync(true, getVsyncPeriod());
+ mScheduler->onScreenAcquired(mAppConnectionHandle);
+ mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
}
} else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
// Leave display going to doze
if (display->isPrimary()) {
- if (mUseScheduler) {
- mScheduler->disableHardwareVsync(true);
- } else {
- disableHardwareVsync(true); // also cancels any in-progress resync
- }
- if (mUseScheduler) {
- mScheduler->onScreenReleased(mAppConnectionHandle);
- } else {
- mEventThread->onScreenReleased();
- }
+ mScheduler->disableHardwareVsync(true);
+ mScheduler->onScreenReleased(mAppConnectionHandle);
}
getHwComposer().setPowerMode(*displayId, mode);
} else {
@@ -4489,7 +4283,7 @@
if (display->isPrimary()) {
mTimeStats->setPowerMode(mode);
- if (mUseScheduler && mRefreshRateStats) {
+ if (mRefreshRateStats) {
// Update refresh rate stats.
mRefreshRateStats->setPowerMode(mode);
}
@@ -4546,11 +4340,7 @@
{"--disable-layer-stats"s, dumper([this](std::string&) { mLayerStats.disable(); })},
{"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},
{"--dispsync"s, dumper([this](std::string& s) {
- if (mUseScheduler) {
mScheduler->dumpPrimaryDispSync(s);
- } else {
- mPrimaryDispSync->dump(s);
- }
})},
{"--dump-layer-stats"s, dumper([this](std::string& s) { mLayerStats.dump(s); })},
{"--enable-layer-stats"s, dumper([this](std::string&) { mLayerStats.enable(); })},
@@ -4650,13 +4440,8 @@
" present offset: %9" PRId64 " ns\t VSYNC period: %9" PRId64 " ns\n\n",
dispSyncPresentTimeOffset, getVsyncPeriod());
- StringAppendF(&result, "Scheduler: %s\n\n", mUseScheduler ? "enabled" : "disabled");
-
- if (mUseScheduler) {
- mScheduler->dump(mAppConnectionHandle, result);
- } else {
- mEventThread->dump(result);
- }
+ StringAppendF(&result, "Scheduler enabled. 90Hz feature: %s\n\n", mUse90Hz ? "on" : "off");
+ mScheduler->dump(mAppConnectionHandle, result);
}
void SurfaceFlinger::dumpStaticScreenStats(std::string& result) const {
@@ -5005,11 +4790,9 @@
/**
* Scheduler dump state.
*/
- if (mUseScheduler) {
- result.append("\nScheduler state:\n");
- result.append(mScheduler->doDump() + "\n");
- result.append(mRefreshRateStats->doDump() + "\n");
- }
+ result.append("\nScheduler state:\n");
+ result.append(mScheduler->doDump() + "\n");
+ result.append(mRefreshRateStats->doDump() + "\n");
}
const Vector<sp<Layer>>& SurfaceFlinger::getLayerSortedByZForHwcDisplay(DisplayId displayId) {
@@ -5285,7 +5068,7 @@
case 1016: {
n = data.readInt32();
// TODO(b/113612090): Evaluate if this can be removed.
- mPrimaryDispSync->setRefreshSkipCount(n);
+ mScheduler->setRefreshSkipCount(n);
return NO_ERROR;
}
case 1017: {
@@ -5295,20 +5078,12 @@
}
case 1018: { // Modify Choreographer's phase offset
n = data.readInt32();
- if (mUseScheduler) {
- mScheduler->setPhaseOffset(mAppConnectionHandle, static_cast<nsecs_t>(n));
- } else {
- mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
- }
+ mScheduler->setPhaseOffset(mAppConnectionHandle, static_cast<nsecs_t>(n));
return NO_ERROR;
}
case 1019: { // Modify SurfaceFlinger's phase offset
n = data.readInt32();
- if (mUseScheduler) {
- mScheduler->setPhaseOffset(mSfConnectionHandle, static_cast<nsecs_t>(n));
- } else {
- mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
- }
+ mScheduler->setPhaseOffset(mSfConnectionHandle, static_cast<nsecs_t>(n));
return NO_ERROR;
}
case 1020: { // Layer updates interceptor
@@ -5545,7 +5320,7 @@
newParent->computeBounds(drawingBounds.toFloatRect(), ui::Transform());
oldParent->setChildrenDrawingParent(newParent);
}
- ~ReparentForDrawing() { newParent->setChildrenDrawingParent(oldParent); }
+ ~ReparentForDrawing() { oldParent->setChildrenDrawingParent(oldParent); }
};
void render(std::function<void()> drawLayers) override {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4393077..36302d5 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -169,9 +169,6 @@
nsecs_t mTotalTime;
std::atomic<nsecs_t> mLastSwapTime;
- // Synchronization fence from a GL composition.
- sp<Fence> flushFence = Fence::NO_FENCE;
-
// Double- vs. triple-buffering stats
struct BufferingStats {
BufferingStats()
@@ -408,6 +405,7 @@
*/
status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override;
status_t dump(int fd, const Vector<String16>& args) override { return priorityDump(fd, args); }
+ bool callingThreadHasUnscopedSurfaceFlingerAccess() EXCLUDES(mStateLock);
/* ------------------------------------------------------------------------
* ISurfaceComposer interface
@@ -534,10 +532,11 @@
void handleMessageRefresh();
void handleTransaction(uint32_t transactionFlags);
- void handleTransactionLocked(uint32_t transactionFlags);
+ void handleTransactionLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
void updateInputFlinger();
void updateInputWindowInfo();
+ void commitInputWindowCommands() REQUIRES(mStateLock);
void executeInputWindowCommands();
void updateCursorAsync();
@@ -552,7 +551,8 @@
*/
void applyTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
- const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock);
+ const InputWindowCommands& inputWindowCommands,
+ bool privileged) REQUIRES(mStateLock);
bool flushTransactionQueues();
uint32_t getTransactionFlags(uint32_t flags);
uint32_t peekTransactionFlags();
@@ -564,9 +564,10 @@
bool containsAnyInvalidClientState(const Vector<ComposerState>& states);
bool transactionIsReadyToBeApplied(int64_t desiredPresentTime,
const Vector<ComposerState>& states);
- uint32_t setClientStateLocked(const ComposerState& composerState);
+ uint32_t setClientStateLocked(const ComposerState& composerState, bool privileged);
uint32_t setDisplayStateLocked(const DisplayState& s);
- uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
+ uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands)
+ REQUIRES(mStateLock);
/* ------------------------------------------------------------------------
* Layer management
@@ -785,37 +786,11 @@
* VSync
*/
nsecs_t getVsyncPeriod() const REQUIRES(mStateLock);
- void enableHardwareVsync();
- void resyncToHardwareVsync(bool makeAvailable, nsecs_t period);
- void disableHardwareVsync(bool makeUnavailable);
// Sets the refresh rate by switching active configs, if they are available for
// the desired refresh rate.
void setRefreshRateTo(scheduler::RefreshRateConfigs::RefreshRateType) REQUIRES(mStateLock);
- using GetVsyncPeriod = std::function<nsecs_t()>;
-
- // Stores per-display state about VSYNC.
- struct VsyncState {
- explicit VsyncState(SurfaceFlinger& flinger) : flinger(flinger) {}
-
- void resync(const GetVsyncPeriod&);
-
- SurfaceFlinger& flinger;
- std::atomic<nsecs_t> lastResyncTime = 0;
- };
-
- const std::shared_ptr<VsyncState> mPrimaryVsyncState{std::make_shared<VsyncState>(*this)};
-
- auto makeResyncCallback(GetVsyncPeriod&& getVsyncPeriod) {
- std::weak_ptr<VsyncState> ptr = mPrimaryVsyncState;
- return [ptr, getVsyncPeriod = std::move(getVsyncPeriod)]() {
- if (const auto vsync = ptr.lock()) {
- vsync->resync(getVsyncPeriod);
- }
- };
- }
-
/*
* Display identification
*/
@@ -953,11 +928,7 @@
// constant members (no synchronization needed for access)
nsecs_t mBootTime;
bool mGpuToCpuSupported;
- std::unique_ptr<EventThread> mEventThread;
- std::unique_ptr<EventThread> mSFEventThread;
std::unique_ptr<EventThread> mInjectorEventThread;
- std::unique_ptr<VSyncSource> mEventThreadSource;
- std::unique_ptr<VSyncSource> mSfEventThreadSource;
std::unique_ptr<InjectVSyncSource> mVSyncInjector;
std::unique_ptr<EventControlThread> mEventControlThread;
@@ -1024,16 +995,11 @@
// these are thread safe
mutable std::unique_ptr<MessageQueue> mEventQueue{mFactory.createMessageQueue()};
FrameTracker mAnimFrameTracker;
- std::unique_ptr<DispSync> mPrimaryDispSync;
// protected by mDestroyedLayerLock;
mutable Mutex mDestroyedLayerLock;
Vector<Layer const *> mDestroyedLayers;
- // protected by mHWVsyncLock
- Mutex mHWVsyncLock;
- bool mPrimaryHWVsyncEnabled;
- bool mHWVsyncAvailable;
nsecs_t mRefreshStartTime;
std::atomic<bool> mRefreshPending{false};
@@ -1053,16 +1019,19 @@
struct TransactionState {
TransactionState(const Vector<ComposerState>& composerStates,
const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
- int64_t desiredPresentTime)
+ int64_t desiredPresentTime,
+ bool privileged)
: states(composerStates),
displays(displayStates),
flags(transactionFlags),
- time(desiredPresentTime) {}
+ time(desiredPresentTime),
+ privileged(privileged) {}
Vector<ComposerState> states;
Vector<DisplayState> displays;
uint32_t flags;
int64_t time;
+ bool privileged;
};
std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IBinderHash> mTransactionQueues;
@@ -1088,6 +1057,15 @@
DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::ENHANCED;
+ // Color mode forced by setting persist.sys.sf.color_mode, it must:
+ // 1. not be NATIVE color mode, NATIVE color mode means no forced color mode;
+ // 2. be one of the supported color modes returned by hardware composer, otherwise
+ // it will not be respected.
+ // persist.sys.sf.color_mode will only take effect when persist.sys.sf.native_mode
+ // is not set to 1.
+ // This property can be used to force SurfaceFlinger to always pick a certain color mode.
+ ui::ColorMode mForceColorMode = ui::ColorMode::NATIVE;
+
ui::Dataspace mDefaultCompositionDataspace;
ui::Dataspace mWideColorGamutCompositionDataspace;
@@ -1097,7 +1075,7 @@
/* ------------------------------------------------------------------------
* Scheduler
*/
- bool mUseScheduler = false;
+ bool mUse90Hz = false;
std::unique_ptr<Scheduler> mScheduler;
sp<Scheduler::ConnectionHandle> mAppConnectionHandle;
sp<Scheduler::ConnectionHandle> mSfConnectionHandle;
@@ -1134,6 +1112,8 @@
/* ------------------------------------------------------------------------ */
sp<IInputFlinger> mInputFlinger;
+ InputWindowCommands mPendingInputWindowCommands GUARDED_BY(mStateLock);
+ // Should only be accessed by the main thread.
InputWindowCommands mInputWindowCommands;
ui::DisplayPrimaries mInternalDisplayPrimaries;
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index 5bec502..aea602b 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -2,7 +2,6 @@
class core animation
user system
group graphics drmrpc readproc
- updatable
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 3addd61..42bdccc 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -33,6 +33,7 @@
#include "ColorLayer.h"
#include "Layer.h"
+#include "TestableScheduler.h"
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/MockDispSync.h"
@@ -90,11 +91,9 @@
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
- mFlinger.mutableEventControlThread().reset(mEventControlThread);
- mFlinger.mutableEventThread().reset(mEventThread);
mFlinger.mutableEventQueue().reset(mMessageQueue);
+ setupScheduler();
- mFlinger.mutablePrimaryDispSync().reset(mPrimaryDispSync);
EXPECT_CALL(*mPrimaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
EXPECT_CALL(*mPrimaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
@@ -124,6 +123,18 @@
Mock::VerifyAndClear(mComposer);
}
+ void setupScheduler() {
+ mScheduler = new TestableScheduler();
+ mScheduler->mutableEventControlThread().reset(mEventControlThread);
+ mScheduler->mutablePrimaryDispSync().reset(mPrimaryDispSync);
+ EXPECT_CALL(*mEventThread.get(), registerDisplayEventConnection(_));
+ sp<Scheduler::ConnectionHandle> connectionHandle =
+ mScheduler->addConnection(std::move(mEventThread));
+ mFlinger.mutableSfConnectionHandle() = std::move(connectionHandle);
+
+ mFlinger.mutableScheduler().reset(mScheduler);
+ }
+
void setupForceGeometryDirty() {
// TODO: This requires the visible region and other related
// state to be set, and is problematic for BufferLayers since they are
@@ -145,6 +156,7 @@
std::unordered_set<HWC2::Capability> mDefaultCapabilities = {HWC2::Capability::SidebandStream};
+ TestableScheduler* mScheduler;
TestableSurfaceFlinger mFlinger;
sp<DisplayDevice> mDisplay;
sp<DisplayDevice> mExternalDisplay;
@@ -155,7 +167,7 @@
sp<GraphicBuffer> mBuffer = new GraphicBuffer();
ANativeWindowBuffer* mNativeWindowBuffer = mBuffer->getNativeBuffer();
- mock::EventThread* mEventThread = new mock::EventThread();
+ std::unique_ptr<mock::EventThread> mEventThread = std::make_unique<mock::EventThread>();
mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
Hwc2::mock::Composer* mComposer = nullptr;
@@ -482,7 +494,7 @@
EXPECT_CALL(*test->mRenderEngine, useNativeFenceSync()).WillRepeatedly(Return(true));
bool ignoredRecomputeVisibleRegions;
- layer->latchBuffer(ignoredRecomputeVisibleRegions, 0, Fence::NO_FENCE);
+ layer->latchBuffer(ignoredRecomputeVisibleRegions, 0);
Mock::VerifyAndClear(test->mRenderEngine);
}
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 6659d4a..19f308b 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -29,6 +29,7 @@
#include <ui/DebugUtils.h>
#include "DisplayIdentificationTest.h"
+#include "TestableScheduler.h"
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
#include "mock/MockDispSync.h"
@@ -94,6 +95,8 @@
DisplayTransactionTest();
~DisplayTransactionTest() override;
+ void setupScheduler();
+
// --------------------------------------------------------------------
// Mock/Fake injection
@@ -116,6 +119,7 @@
// --------------------------------------------------------------------
// Test instances
+ TestableScheduler* mScheduler;
TestableSurfaceFlinger mFlinger;
mock::EventThread* mEventThread = new mock::EventThread();
mock::EventThread* mSFEventThread = new mock::EventThread();
@@ -160,13 +164,10 @@
return nullptr;
});
- mFlinger.mutableEventControlThread().reset(mEventControlThread);
- mFlinger.mutableEventThread().reset(mEventThread);
- mFlinger.mutableSFEventThread().reset(mSFEventThread);
+ setupScheduler();
mFlinger.mutableEventQueue().reset(mMessageQueue);
mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
- mFlinger.mutablePrimaryDispSync().reset(mPrimaryDispSync);
injectMockComposer(0);
}
@@ -177,6 +178,22 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
+void DisplayTransactionTest::setupScheduler() {
+ mScheduler = new TestableScheduler();
+ mScheduler->mutableEventControlThread().reset(mEventControlThread);
+ mScheduler->mutablePrimaryDispSync().reset(mPrimaryDispSync);
+ EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_));
+ EXPECT_CALL(*mSFEventThread, registerDisplayEventConnection(_));
+
+ sp<Scheduler::ConnectionHandle> sfConnectionHandle =
+ mScheduler->addConnection(std::unique_ptr<EventThread>(mSFEventThread));
+ mFlinger.mutableSfConnectionHandle() = std::move(sfConnectionHandle);
+ sp<Scheduler::ConnectionHandle> appConnectionHandle =
+ mScheduler->addConnection(std::unique_ptr<EventThread>(mEventThread));
+ mFlinger.mutableAppConnectionHandle() = std::move(appConnectionHandle);
+ mFlinger.mutableScheduler().reset(mScheduler);
+}
+
void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
mComposer = new Hwc2::mock::Composer();
EXPECT_CALL(*mComposer, getCapabilities())
@@ -1106,8 +1123,8 @@
// Preconditions
// vsync is enabled and available
- mFlinger.mutablePrimaryHWVsyncEnabled() = true;
- mFlinger.mutableHWVsyncAvailable() = true;
+ mScheduler->mutablePrimaryHWVsyncEnabled() = true;
+ mScheduler->mutableHWVsyncAvailable() = true;
// A display exists
auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
@@ -1131,8 +1148,8 @@
// Postconditions
// vsyncs should be off and not available.
- EXPECT_FALSE(mFlinger.mutablePrimaryHWVsyncEnabled());
- EXPECT_FALSE(mFlinger.mutableHWVsyncAvailable());
+ EXPECT_FALSE(mScheduler->mutablePrimaryHWVsyncEnabled());
+ EXPECT_FALSE(mScheduler->mutableHWVsyncAvailable());
// The display should have been removed from the display map.
EXPECT_FALSE(hasDisplayDevice(existing.token()));
@@ -1557,7 +1574,6 @@
Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
-
expectHotplugReceived<Case, true>(mEventThread);
expectHotplugReceived<Case, true>(mSFEventThread);
}
@@ -3008,7 +3024,7 @@
}
static void setInitialPrimaryHWVsyncEnabled(DisplayTransactionTest* test, bool enabled) {
- test->mFlinger.mutablePrimaryHWVsyncEnabled() = enabled;
+ test->mScheduler->mutablePrimaryHWVsyncEnabled() = enabled;
}
static void setupRepaintEverythingCallExpectations(DisplayTransactionTest* test) {
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
new file mode 100644
index 0000000..dcbf973
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+
+#include "Scheduler/EventThread.h"
+#include "Scheduler/Scheduler.h"
+
+namespace android {
+
+class TestableScheduler : public Scheduler {
+public:
+ TestableScheduler() : Scheduler([](bool) {}) {}
+
+ // Creates EventThreadConnection with the given eventThread. Creates Scheduler::Connection
+ // and adds it to the list of connectins. Returns the ConnectionHandle for the
+ // Scheduler::Connection. This allows plugging in mock::EventThread.
+ sp<Scheduler::ConnectionHandle> addConnection(std::unique_ptr<EventThread> eventThread) {
+ sp<EventThreadConnection> eventThreadConnection =
+ new EventThreadConnection(eventThread.get(), ResyncCallback(),
+ ResetIdleTimerCallback());
+ const int64_t id = sNextId++;
+ mConnections.emplace(id,
+ std::make_unique<Scheduler::Connection>(new ConnectionHandle(id),
+ eventThreadConnection,
+ std::move(eventThread)));
+ return mConnections[id]->handle;
+ }
+
+ /* ------------------------------------------------------------------------
+ * Read-write access to private data to set up preconditions and assert
+ * post-conditions.
+ */
+ auto& mutablePrimaryHWVsyncEnabled() { return mPrimaryHWVsyncEnabled; }
+ auto& mutableEventControlThread() { return mEventControlThread; }
+ auto& mutablePrimaryDispSync() { return mPrimaryDispSync; }
+ auto& mutableHWVsyncAvailable() { return mHWVsyncAvailable; }
+
+ ~TestableScheduler() {
+ // All these pointer and container clears help ensure that GMock does
+ // not report a leaked object, since the Scheduler instance may
+ // still be referenced by something despite our best efforts to destroy
+ // it after each test is done.
+ mutableEventControlThread().reset();
+ mutablePrimaryDispSync().reset();
+ mConnections.clear();
+ };
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 53b867f..6313f1f 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -248,6 +248,7 @@
}
auto handleTransactionLocked(uint32_t transactionFlags) {
+ Mutex::Autolock _l(mFlinger->mStateLock);
return mFlinger->handleTransactionLocked(transactionFlags);
}
@@ -298,7 +299,6 @@
const auto& getAnimFrameTracker() const { return mFlinger->mAnimFrameTracker; }
const auto& getHasPoweredOff() const { return mFlinger->mHasPoweredOff; }
- const auto& getHWVsyncAvailable() const { return mFlinger->mHWVsyncAvailable; }
const auto& getVisibleRegionsDirty() const { return mFlinger->mVisibleRegionsDirty; }
auto& getHwComposer() const {
return static_cast<impl::HWComposer&>(mFlinger->getHwComposer());
@@ -319,18 +319,12 @@
auto& mutableDisplayColorSetting() { return mFlinger->mDisplayColorSetting; }
auto& mutableDisplays() { return mFlinger->mDisplays; }
auto& mutableDrawingState() { return mFlinger->mDrawingState; }
- auto& mutableEventControlThread() { return mFlinger->mEventControlThread; }
auto& mutableEventQueue() { return mFlinger->mEventQueue; }
- auto& mutableEventThread() { return mFlinger->mEventThread; }
- auto& mutableSFEventThread() { return mFlinger->mSFEventThread; }
auto& mutableGeometryInvalid() { return mFlinger->mGeometryInvalid; }
- auto& mutableHWVsyncAvailable() { return mFlinger->mHWVsyncAvailable; }
auto& mutableInterceptor() { return mFlinger->mInterceptor; }
auto& mutableMainThreadId() { return mFlinger->mMainThreadId; }
auto& mutablePendingHotplugEvents() { return mFlinger->mPendingHotplugEvents; }
auto& mutablePhysicalDisplayTokens() { return mFlinger->mPhysicalDisplayTokens; }
- auto& mutablePrimaryDispSync() { return mFlinger->mPrimaryDispSync; }
- auto& mutablePrimaryHWVsyncEnabled() { return mFlinger->mPrimaryHWVsyncEnabled; }
auto& mutableTexturePool() { return mFlinger->mTexturePool; }
auto& mutableTransactionFlags() { return mFlinger->mTransactionFlags; }
auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
@@ -340,6 +334,9 @@
auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; }
auto& mutableInternalHwcDisplayId() { return getHwComposer().mInternalHwcDisplayId; }
auto& mutableExternalHwcDisplayId() { return getHwComposer().mExternalHwcDisplayId; }
+ auto& mutableScheduler() { return mFlinger->mScheduler; }
+ auto& mutableAppConnectionHandle() { return mFlinger->mAppConnectionHandle; }
+ auto& mutableSfConnectionHandle() { return mFlinger->mSfConnectionHandle; }
~TestableSurfaceFlinger() {
// All these pointer and container clears help ensure that GMock does
@@ -347,12 +344,9 @@
// still be referenced by something despite our best efforts to destroy
// it after each test is done.
mutableDisplays().clear();
- mutableEventControlThread().reset();
mutableEventQueue().reset();
- mutableEventThread().reset();
- mutableSFEventThread().reset();
mutableInterceptor().reset();
- mutablePrimaryDispSync().reset();
+ mutableScheduler().reset();
mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>());
mFlinger->mCompositionEngine->setRenderEngine(
std::unique_ptr<renderengine::RenderEngine>());
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index f3e54a0..b49d894 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -91,11 +91,10 @@
// Using placement new here to reuse shared memory instead of new allocation
// and also initialize the value to zero.
- buffer_state_ =
- new (&metadata_header_->buffer_state) std::atomic<uint32_t>(0);
- fence_state_ = new (&metadata_header_->fence_state) std::atomic<uint32_t>(0);
+ buffer_state_ = new (&metadata_header_->bufferState) std::atomic<uint32_t>(0);
+ fence_state_ = new (&metadata_header_->fenceState) std::atomic<uint32_t>(0);
active_clients_bit_mask_ =
- new (&metadata_header_->active_clients_bit_mask) std::atomic<uint32_t>(0);
+ new (&metadata_header_->activeClientsBitMask) std::atomic<uint32_t>(0);
// Producer channel is never created after consumer channel, and one buffer
// only have one fixed producer for now. Thus, it is correct to assume
@@ -183,7 +182,7 @@
buffer_.height(), buffer_.layer_count(), buffer_.format(),
buffer_.usage(),
buffer_state_->load(std::memory_order_acquire),
- signaled_mask, metadata_header_->queue_index);
+ signaled_mask, metadata_header_->queueIndex);
}
void ProducerChannel::HandleImpulse(Message& message) {
@@ -547,7 +546,7 @@
"%s: orphaned buffer detected during the this acquire/release cycle: "
"id=%d orphaned=0x%" PRIx32 " queue_index=%" PRId64 ".",
__FUNCTION__, buffer_id(), orphaned_consumer_bit_mask_,
- metadata_header_->queue_index);
+ metadata_header_->queueIndex);
orphaned_consumer_bit_mask_ = 0;
}
}
@@ -581,7 +580,7 @@
"consumer_state_mask=%" PRIx32 " queue_index=%" PRId64
" buffer_state=%" PRIx32 " fence_state=%" PRIx32 ".",
__FUNCTION__, buffer_id(), consumer_state_mask,
- metadata_header_->queue_index,
+ metadata_header_->queueIndex,
buffer_state_->load(std::memory_order_acquire),
fence_state_->load(std::memory_order_acquire));
}
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index fed8481..206c8eb 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -84,8 +84,8 @@
"libutils",
"libcutils",
"libz",
- "libnativebridge",
- "libnativeloader",
+ "libnativebridge_lazy",
+ "libnativeloader_lazy",
"libnativewindow",
"android.hardware.graphics.common@1.0",
],
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 3a8e34e..b3259de 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -33,6 +33,7 @@
#include <configstore/Utils.h>
#include <cutils/properties.h>
#include <graphicsenv/GraphicsEnv.h>
+#include <utils/Timers.h>
#include <utils/Trace.h>
#include <utils/Vector.h>
@@ -210,6 +211,8 @@
auto ns = android_get_exported_namespace("sphal");
if (!ns)
return -ENOENT;
+ android::GraphicsEnv::getInstance().setDriverToLoad(
+ android::GraphicsEnv::Driver::VULKAN);
return LoadDriver(ns, module);
}
@@ -219,12 +222,16 @@
auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
if (!ns)
return -ENOENT;
+ android::GraphicsEnv::getInstance().setDriverToLoad(
+ android::GraphicsEnv::Driver::VULKAN_UPDATED);
return LoadDriver(ns, module);
}
bool Hal::Open() {
ATRACE_CALL();
+ const nsecs_t openTime = systemTime();
+
ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
// Use a stub device unless we successfully open a real HAL device.
@@ -250,11 +257,12 @@
}
}
if (result != 0) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);
return true;
}
- android::GraphicsEnv::getInstance().sendGpuStats();
hwvulkan_device_t* device;
ATRACE_BEGIN("hwvulkan module open");
@@ -263,6 +271,8 @@
reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
if (result != 0) {
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, false, systemTime() - openTime);
// Any device with a Vulkan HAL should be able to open the device.
ALOGE("failed to open Vulkan HAL device: %s (%d)", strerror(-result),
result);
@@ -273,6 +283,9 @@
hal_.InitDebugReportIndex();
+ android::GraphicsEnv::getInstance().setDriverLoaded(
+ android::GraphicsEnv::Api::API_VK, true, systemTime() - openTime);
+
return true;
}