Loading libs/hwui/aconfig/hwui_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -211,3 +211,11 @@ flag { description: "Whether to parcel implicit copies of bitmaps to ashmem as immutable" bug: "400807118" } flag { name: "bitmap_use_memfd" namespace: "system_performance" description: "Whether to parcel implicit copies of bitmaps to memfd instead of ashmem" bug: "400807118" is_fixed_read_only: true } No newline at end of file libs/hwui/jni/Bitmap.cpp +42 −12 Original line number Diff line number Diff line Loading @@ -5,11 +5,15 @@ #ifdef __linux__ #include <com_android_graphics_hwui_flags.h> #endif #include <fcntl.h> #include <hwui/Bitmap.h> #include <hwui/Paint.h> #include <inttypes.h> #include <renderthread/RenderProxy.h> #include <string.h> #include <sys/mman.h> #include <sys/syscall.h> #include <unistd.h> #include <memory> Loading Loading @@ -688,7 +692,31 @@ static binder_status_t writeBlob(AParcel* parcel, uint64_t bitmapId, const SkBit // Create new ashmem region with read/write priv auto ashmemId = Bitmap::getAshmemId("writeblob", bitmapId, bitmap.width(), bitmap.height(), size); base::unique_fd fd(ashmem_create_region(ashmemId.c_str(), size)); base::unique_fd fd; if (com::android::graphics::hwui::flags::bitmap_use_memfd()) { fd.reset(syscall(__NR_memfd_create, ashmemId.c_str(), MFD_CLOEXEC | MFD_ALLOW_SEALING)); if (fd.get() < 0) { return STATUS_NO_MEMORY; } ssize_t written = write(fd.get(), data, size); if (written != size) { return STATUS_NO_MEMORY; } if (fcntl(fd, F_ADD_SEALS, // Disallow growing / shrinking F_SEAL_GROW | F_SEAL_SHRINK // If immutable, disallow writing | (immutable ? F_SEAL_WRITE : 0) // Seal the seals 🦭 | F_SEAL_SEAL) == -1) { return STATUS_UNKNOWN_ERROR; } } else { fd.reset(ashmem_create_region(ashmemId.c_str(), size)); if (fd.get() < 0) { return STATUS_NO_MEMORY; } Loading @@ -705,6 +733,8 @@ static binder_status_t writeBlob(AParcel* parcel, uint64_t bitmapId, const SkBit if (immutable && ashmem_set_prot_region(fd.get(), PROT_READ) < 0) { return STATUS_UNKNOWN_ERROR; } } // Workaround b/149851140 in AParcel_writeParcelFileDescriptor int rawFd = fd.release(); error = writeBlobFromFd(parcel, size, rawFd); Loading Loading
libs/hwui/aconfig/hwui_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -211,3 +211,11 @@ flag { description: "Whether to parcel implicit copies of bitmaps to ashmem as immutable" bug: "400807118" } flag { name: "bitmap_use_memfd" namespace: "system_performance" description: "Whether to parcel implicit copies of bitmaps to memfd instead of ashmem" bug: "400807118" is_fixed_read_only: true } No newline at end of file
libs/hwui/jni/Bitmap.cpp +42 −12 Original line number Diff line number Diff line Loading @@ -5,11 +5,15 @@ #ifdef __linux__ #include <com_android_graphics_hwui_flags.h> #endif #include <fcntl.h> #include <hwui/Bitmap.h> #include <hwui/Paint.h> #include <inttypes.h> #include <renderthread/RenderProxy.h> #include <string.h> #include <sys/mman.h> #include <sys/syscall.h> #include <unistd.h> #include <memory> Loading Loading @@ -688,7 +692,31 @@ static binder_status_t writeBlob(AParcel* parcel, uint64_t bitmapId, const SkBit // Create new ashmem region with read/write priv auto ashmemId = Bitmap::getAshmemId("writeblob", bitmapId, bitmap.width(), bitmap.height(), size); base::unique_fd fd(ashmem_create_region(ashmemId.c_str(), size)); base::unique_fd fd; if (com::android::graphics::hwui::flags::bitmap_use_memfd()) { fd.reset(syscall(__NR_memfd_create, ashmemId.c_str(), MFD_CLOEXEC | MFD_ALLOW_SEALING)); if (fd.get() < 0) { return STATUS_NO_MEMORY; } ssize_t written = write(fd.get(), data, size); if (written != size) { return STATUS_NO_MEMORY; } if (fcntl(fd, F_ADD_SEALS, // Disallow growing / shrinking F_SEAL_GROW | F_SEAL_SHRINK // If immutable, disallow writing | (immutable ? F_SEAL_WRITE : 0) // Seal the seals 🦭 | F_SEAL_SEAL) == -1) { return STATUS_UNKNOWN_ERROR; } } else { fd.reset(ashmem_create_region(ashmemId.c_str(), size)); if (fd.get() < 0) { return STATUS_NO_MEMORY; } Loading @@ -705,6 +733,8 @@ static binder_status_t writeBlob(AParcel* parcel, uint64_t bitmapId, const SkBit if (immutable && ashmem_set_prot_region(fd.get(), PROT_READ) < 0) { return STATUS_UNKNOWN_ERROR; } } // Workaround b/149851140 in AParcel_writeParcelFileDescriptor int rawFd = fd.release(); error = writeBlobFromFd(parcel, size, rawFd); Loading