summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Stoza <stoza@google.com>2015-03-23 13:46:14 -0700
committerDan Stoza <stoza@google.com>2015-04-15 13:04:15 -0700
commit6fbefbbd8edc9953041289fbd77bb18c4964dce5 (patch)
treee8a0451bbe1f7ee62a15d5ff910dca7dcd59b090
parenta894d082cfee8d12ee5913163a34ec5dc521d005 (diff)
downloadnative-6fbefbbd8edc9953041289fbd77bb18c4964dce5.tar.gz
libui: Clean up Fence and Region flattening
Fence was flattening incorrectly, causing issues with any fields flattened after it, and Region was relying on being the last object flattened. This change addresses both. Change-Id: If49de061de6e2f11f4d846b4d8c18627dfb7e109
-rw-r--r--libs/ui/Fence.cpp6
-rw-r--r--libs/ui/Region.cpp45
2 files changed, 35 insertions, 16 deletions
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index 9cf2881787..bf24ffb7e0 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -130,7 +130,7 @@ nsecs_t Fence::getSignalTime() const {
}
size_t Fence::getFlattenedSize() const {
- return 1;
+ return 4;
}
size_t Fence::getFdCount() const {
@@ -141,7 +141,9 @@ status_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) c
if (size < getFlattenedSize() || count < getFdCount()) {
return NO_MEMORY;
}
- FlattenableUtils::write(buffer, size, getFdCount());
+ // Cast to uint32_t since the size of a size_t can vary between 32- and
+ // 64-bit processes
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(getFdCount()));
if (isValid()) {
*fds++ = mFenceFd;
count--;
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 91fa21626f..23503b118f 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -754,35 +754,52 @@ void Region::translate(Region& dst, const Region& reg, int dx, int dy)
// ----------------------------------------------------------------------------
size_t Region::getFlattenedSize() const {
- return mStorage.size() * sizeof(Rect);
+ return sizeof(uint32_t) + mStorage.size() * sizeof(Rect);
}
status_t Region::flatten(void* buffer, size_t size) const {
#if VALIDATE_REGIONS
validate(*this, "Region::flatten");
#endif
- if (size < mStorage.size() * sizeof(Rect)) {
+ if (size < getFlattenedSize()) {
return NO_MEMORY;
}
- Rect* rects = reinterpret_cast<Rect*>(buffer);
- memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
+ // Cast to uint32_t since the size of a size_t can vary between 32- and
+ // 64-bit processes
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(mStorage.size()));
+ for (auto rect : mStorage) {
+ status_t result = rect.flatten(buffer, size);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ FlattenableUtils::advance(buffer, size, sizeof(rect));
+ }
return NO_ERROR;
}
status_t Region::unflatten(void const* buffer, size_t size) {
+ if (size < sizeof(uint32_t)) {
+ return NO_MEMORY;
+ }
+
+ uint32_t numRects = 0;
+ FlattenableUtils::read(buffer, size, numRects);
+ if (size < numRects * sizeof(Rect)) {
+ return NO_MEMORY;
+ }
+
Region result;
- if (size >= sizeof(Rect)) {
- Rect const* rects = reinterpret_cast<Rect const*>(buffer);
- size_t count = size / sizeof(Rect);
- if (count > 0) {
- result.mStorage.clear();
- ssize_t err = result.mStorage.insertAt(0, count);
- if (err < 0) {
- return status_t(err);
- }
- memcpy(result.mStorage.editArray(), rects, count*sizeof(Rect));
+ result.mStorage.clear();
+ for (size_t r = 0; r < numRects; ++r) {
+ Rect rect;
+ status_t status = rect.unflatten(buffer, size);
+ if (status != NO_ERROR) {
+ return status;
}
+ FlattenableUtils::advance(buffer, size, sizeof(rect));
+ result.mStorage.push_back(rect);
}
+
#if VALIDATE_REGIONS
validate(result, "Region::unflatten");
#endif