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
This commit is contained in:
Dan Stoza 2015-03-23 13:46:14 -07:00
parent a894d082cf
commit 6fbefbbd8e
2 changed files with 37 additions and 18 deletions

View File

@ -130,7 +130,7 @@ nsecs_t Fence::getSignalTime() const {
} }
size_t Fence::getFlattenedSize() const { size_t Fence::getFlattenedSize() const {
return 1; return 4;
} }
size_t Fence::getFdCount() const { 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()) { if (size < getFlattenedSize() || count < getFdCount()) {
return NO_MEMORY; 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()) { if (isValid()) {
*fds++ = mFenceFd; *fds++ = mFenceFd;
count--; count--;

View File

@ -754,35 +754,52 @@ void Region::translate(Region& dst, const Region& reg, int dx, int dy)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
size_t Region::getFlattenedSize() const { 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 { status_t Region::flatten(void* buffer, size_t size) const {
#if VALIDATE_REGIONS #if VALIDATE_REGIONS
validate(*this, "Region::flatten"); validate(*this, "Region::flatten");
#endif #endif
if (size < mStorage.size() * sizeof(Rect)) { if (size < getFlattenedSize()) {
return NO_MEMORY; return NO_MEMORY;
} }
Rect* rects = reinterpret_cast<Rect*>(buffer); // Cast to uint32_t since the size of a size_t can vary between 32- and
memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect)); // 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; return NO_ERROR;
} }
status_t Region::unflatten(void const* buffer, size_t size) { 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; 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(); result.mStorage.clear();
ssize_t err = result.mStorage.insertAt(0, count); for (size_t r = 0; r < numRects; ++r) {
if (err < 0) { Rect rect;
return status_t(err); status_t status = rect.unflatten(buffer, size);
} if (status != NO_ERROR) {
memcpy(result.mStorage.editArray(), rects, count*sizeof(Rect)); return status;
} }
FlattenableUtils::advance(buffer, size, sizeof(rect));
result.mStorage.push_back(rect);
} }
#if VALIDATE_REGIONS #if VALIDATE_REGIONS
validate(result, "Region::unflatten"); validate(result, "Region::unflatten");
#endif #endif