Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 31ebd6c2 authored by Shai Barack's avatar Shai Barack Committed by Android (Google) Code Review
Browse files

Merge "Make writing Bitmap to ashmem faster" into main

parents 133cf140 de43e5f1
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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
+42 −12
Original line number Diff line number Diff line
@@ -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>

@@ -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;
            }
@@ -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);