[{"id":18625,"web_url":"https://patchwork.libcamera.org/comment/18625/","msgid":"<YRE5pIGjmrAT7/zE@pendragon.ideasonboard.com>","date":"2021-08-09T14:20:20","subject":"Re: [libcamera-devel] [PATCH v3 3/3] libcamera: MappedFrameBuffer:\n\tUse typed Flags<MapFlags>","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Kieran,\n\nThank you for the patch.\n\nOn Mon, Aug 09, 2021 at 02:29:29PM +0100, Kieran Bingham wrote:\n> Remove the need for callers to reference PROT_READ/PROT_WRITE directly\n> from <sys/mman.h> by instead exposing the Read/Write mapping options as\n> flags from the MappedFrameBuffer class itself.\n> \n> While here, introduce the <stdint.h> header which is required for the\n> uint8_t as part of the Plane.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> ---\n> v2\n>  - Use fully scoped enum class\n>  - Swap MapMode and MapModes\n>  - s/mmap_flags/mmapFlags/\n>  - Remove and fix documentation regarding the modes\n>  - add LIBCAMERA_FLAGS_ENABLE_OPERATORS()\n> \n> v3:\n>  - Remove no longer necessary sys/mman.h inclusions throughout\n>  - fix documentation\n>  - rename MapMode as MapFlag and MapModes as MapFlags\n> ---\n>  .../libcamera/internal/mapped_framebuffer.h   | 15 ++++++--\n>  src/android/jpeg/encoder_libjpeg.cpp          |  3 +-\n>  src/android/jpeg/thumbnailer.cpp              |  2 +-\n>  src/android/yuv/post_processor_yuv.cpp        |  2 +-\n>  src/ipa/ipu3/ipu3.cpp                         |  3 +-\n>  src/ipa/raspberrypi/raspberrypi.cpp           |  3 +-\n>  src/libcamera/framebuffer.cpp                 |  1 -\n>  src/libcamera/mapped_framebuffer.cpp          | 34 ++++++++++++++++---\n>  test/mapped-buffer.cpp                        |  6 ++--\n>  9 files changed, 51 insertions(+), 18 deletions(-)\n> \n> diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h\n> index 41e587364260..68c8a43c35dc 100644\n> --- a/include/libcamera/internal/mapped_framebuffer.h\n> +++ b/include/libcamera/internal/mapped_framebuffer.h\n> @@ -7,10 +7,11 @@\n>  #ifndef __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__\n>  #define __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__\n>  \n> -#include <sys/mman.h>\n> +#include <stdint.h>\n>  #include <vector>\n>  \n>  #include <libcamera/base/class.h>\n> +#include <libcamera/base/flags.h>\n>  #include <libcamera/base/span.h>\n>  \n>  #include <libcamera/framebuffer.h>\n> @@ -44,9 +45,19 @@ private:\n>  class MappedFrameBuffer : public MappedBuffer\n>  {\n>  public:\n> -\tMappedFrameBuffer(const FrameBuffer *buffer, int flags);\n> +\tenum class MapFlag {\n> +\t\tRead = 0 << 1,\n> +\t\tWrite = 1 << 1,\n\nDid you mean\n\n\t\tRead = 1 << 0,\n\t\tWrite = 1 << 1,\n\n? Otherwise, Read == 0, Write == 1 and ReadWrite == 1.\n\nWith this fixed,\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\t\tReadWrite = Read | Write,\n> +\t};\n> +\n> +\tusing MapFlags = Flags<MapFlag>;\n> +\n> +\tMappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags);\n>  };\n>  \n> +LIBCAMERA_FLAGS_ENABLE_OPERATORS(MappedFrameBuffer::MapFlag)\n> +\n>  } /* namespace libcamera */\n>  \n>  #endif /* __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ */\n> diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp\n> index 372018d2207f..a7a636011045 100644\n> --- a/src/android/jpeg/encoder_libjpeg.cpp\n> +++ b/src/android/jpeg/encoder_libjpeg.cpp\n> @@ -12,7 +12,6 @@\n>  #include <iostream>\n>  #include <sstream>\n>  #include <string.h>\n> -#include <sys/mman.h>\n>  #include <unistd.h>\n>  #include <vector>\n>  \n> @@ -182,7 +181,7 @@ void EncoderLibJpeg::compressNV(Span<const uint8_t> frame)\n>  int EncoderLibJpeg::encode(const FrameBuffer &source, Span<uint8_t> dest,\n>  \t\t\t   Span<const uint8_t> exifData, unsigned int quality)\n>  {\n> -\tMappedFrameBuffer frame(&source, PROT_READ);\n> +\tMappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);\n>  \tif (!frame.isValid()) {\n>  \t\tLOG(JPEG, Error) << \"Failed to map FrameBuffer : \"\n>  \t\t\t\t << strerror(frame.error());\n> diff --git a/src/android/jpeg/thumbnailer.cpp b/src/android/jpeg/thumbnailer.cpp\n> index 535e2cece914..79d83926af5c 100644\n> --- a/src/android/jpeg/thumbnailer.cpp\n> +++ b/src/android/jpeg/thumbnailer.cpp\n> @@ -41,7 +41,7 @@ void Thumbnailer::createThumbnail(const FrameBuffer &source,\n>  \t\t\t\t  const Size &targetSize,\n>  \t\t\t\t  std::vector<unsigned char> *destination)\n>  {\n> -\tMappedFrameBuffer frame(&source, PROT_READ);\n> +\tMappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);\n>  \tif (!frame.isValid()) {\n>  \t\tLOG(Thumbnailer, Error)\n>  \t\t\t<< \"Failed to map FrameBuffer : \"\n> diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp\n> index 509d4244d614..3e793a580377 100644\n> --- a/src/android/yuv/post_processor_yuv.cpp\n> +++ b/src/android/yuv/post_processor_yuv.cpp\n> @@ -57,7 +57,7 @@ int PostProcessorYuv::process(const FrameBuffer &source,\n>  \tif (!isValidBuffers(source, *destination))\n>  \t\treturn -EINVAL;\n>  \n> -\tconst MappedFrameBuffer sourceMapped(&source, PROT_READ);\n> +\tconst MappedFrameBuffer sourceMapped(&source, MappedFrameBuffer::MapFlag::Read);\n>  \tif (!sourceMapped.isValid()) {\n>  \t\tLOG(YUV, Error) << \"Failed to mmap camera frame buffer\";\n>  \t\treturn -EINVAL;\n> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\n> index 2647bf2f3b96..10093acdad30 100644\n> --- a/src/ipa/ipu3/ipu3.cpp\n> +++ b/src/ipa/ipu3/ipu3.cpp\n> @@ -6,7 +6,6 @@\n>   */\n>  \n>  #include <stdint.h>\n> -#include <sys/mman.h>\n>  \n>  #include <linux/intel-ipu3.h>\n>  #include <linux/v4l2-controls.h>\n> @@ -211,7 +210,7 @@ void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)\n>  \tfor (const IPABuffer &buffer : buffers) {\n>  \t\tconst FrameBuffer fb(buffer.planes);\n>  \t\tbuffers_.emplace(buffer.id,\n> -\t\t\t\t MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));\n> +\t\t\t\t MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));\n>  \t}\n>  }\n>  \n> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\n> index 76f67dd4567a..592e2fe41617 100644\n> --- a/src/ipa/raspberrypi/raspberrypi.cpp\n> +++ b/src/ipa/raspberrypi/raspberrypi.cpp\n> @@ -411,7 +411,8 @@ void IPARPi::mapBuffers(const std::vector<IPABuffer> &buffers)\n>  {\n>  \tfor (const IPABuffer &buffer : buffers) {\n>  \t\tconst FrameBuffer fb(buffer.planes);\n> -\t\tbuffers_.emplace(buffer.id, MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));\n> +\t\tbuffers_.emplace(buffer.id,\n> +\t\t\t\t MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));\n>  \t}\n>  }\n>  \n> diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp\n> index 3d98affb20f9..2223e24321ca 100644\n> --- a/src/libcamera/framebuffer.cpp\n> +++ b/src/libcamera/framebuffer.cpp\n> @@ -10,7 +10,6 @@\n>  \n>  #include <errno.h>\n>  #include <string.h>\n> -#include <sys/mman.h>\n>  #include <unistd.h>\n>  \n>  #include <libcamera/base/log.h>\n> diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp\n> index 0e30fc542154..5a70c18147f2 100644\n> --- a/src/libcamera/mapped_framebuffer.cpp\n> +++ b/src/libcamera/mapped_framebuffer.cpp\n> @@ -142,21 +142,45 @@ MappedBuffer::~MappedBuffer()\n>   * \\brief Map a FrameBuffer using the MappedBuffer interface\n>   */\n>  \n> +/**\n> + * \\enum MappedFrameBuffer::MapFlag\n> + * \\brief Specify the mapping mode for the FrameBuffer\n> + * \\var MappedFrameBuffer::Read\n> + * \\brief Create a read-only mapping\n> + * \\var MappedFrameBuffer::Write\n> + * \\brief Create a write-only mapping\n> + * \\var MappedFrameBuffer::ReadWrite\n> + * \\brief Create a mapping that can be both read and written\n> + */\n> +\n> +/**\n> + * \\typedef MappedFrameBuffer::MapFlags\n> + * \\brief A bitwise combination of MappedFrameBuffer::MapFlag values\n> + */\n> +\n>  /**\n>   * \\brief Map all planes of a FrameBuffer\n>   * \\param[in] buffer FrameBuffer to be mapped\n>   * \\param[in] flags Protection flags to apply to map\n>   *\n> - * Construct an object to map a frame buffer for CPU access.\n> - * The flags are passed directly to mmap and should be either PROT_READ,\n> - * PROT_WRITE, or a bitwise-or combination of both.\n> + * Construct an object to map a frame buffer for CPU access. The mapping can be\n> + * made as Read only, Write only or support Read and Write operations by setting\n> + * the MapFlag flags accordingly.\n>   */\n> -MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags)\n> +MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags)\n>  {\n>  \tmaps_.reserve(buffer->planes().size());\n>  \n> +\tint mmapFlags = 0;\n> +\n> +\tif (flags & MapFlag::Read)\n> +\t\tmmapFlags |= PROT_READ;\n> +\n> +\tif (flags & MapFlag::Write)\n> +\t\tmmapFlags |= PROT_WRITE;\n> +\n>  \tfor (const FrameBuffer::Plane &plane : buffer->planes()) {\n> -\t\tvoid *address = mmap(nullptr, plane.length, flags,\n> +\t\tvoid *address = mmap(nullptr, plane.length, mmapFlags,\n>  \t\t\t\t     MAP_SHARED, plane.fd.fd(), 0);\n>  \t\tif (address == MAP_FAILED) {\n>  \t\t\terror_ = -errno;\n> diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp\n> index a3d1511b74ce..97571945cbca 100644\n> --- a/test/mapped-buffer.cpp\n> +++ b/test/mapped-buffer.cpp\n> @@ -71,7 +71,7 @@ protected:\n>  \t\tconst std::unique_ptr<FrameBuffer> &buffer = allocator_->buffers(stream_).front();\n>  \t\tstd::vector<MappedBuffer> maps;\n>  \n> -\t\tMappedFrameBuffer map(buffer.get(), PROT_READ);\n> +\t\tMappedFrameBuffer map(buffer.get(), MappedFrameBuffer::MapFlag::Read);\n>  \t\tif (!map.isValid()) {\n>  \t\t\tcout << \"Failed to successfully map buffer\" << endl;\n>  \t\t\treturn TestFail;\n> @@ -90,13 +90,13 @@ protected:\n>  \t\t}\n>  \n>  \t\t/* Test for multiple successful maps on the same buffer. */\n> -\t\tMappedFrameBuffer write_map(buffer.get(), PROT_WRITE);\n> +\t\tMappedFrameBuffer write_map(buffer.get(), MappedFrameBuffer::MapFlag::Write);\n>  \t\tif (!write_map.isValid()) {\n>  \t\t\tcout << \"Failed to map write buffer\" << endl;\n>  \t\t\treturn TestFail;\n>  \t\t}\n>  \n> -\t\tMappedFrameBuffer rw_map(buffer.get(), PROT_READ | PROT_WRITE);\n> +\t\tMappedFrameBuffer rw_map(buffer.get(), MappedFrameBuffer::MapFlag::ReadWrite);\n>  \t\tif (!rw_map.isValid()) {\n>  \t\t\tcout << \"Failed to map RW buffer\" << endl;\n>  \t\t\treturn TestFail;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 201B4C3240\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  9 Aug 2021 14:20:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 82978687EB;\n\tMon,  9 Aug 2021 16:20:23 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 47AF260269\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  9 Aug 2021 16:20:22 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C1D16DD;\n\tMon,  9 Aug 2021 16:20:21 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"YGicWU/+\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628518821;\n\tbh=0IIVpiceLvkJF2sqKsHQ8yKDyf53quuHtzVKrb5J5a0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=YGicWU/+aNi8bRy6i8ZT6mNDxgcrHw87mIEF7cSBro/QbIjwCrCqt3ZQ//EY5Buq5\n\tuBE4QKeZYs6h1q3krFXXnvIJLQcKLKc55o6sNyXrPMK42GrbhSeGC4MYbRm/yTood3\n\toDxMVlAdZXRNMKgqpp4q7OaHq/BiHa/3SgwZdPVw=","Date":"Mon, 9 Aug 2021 17:20:20 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Message-ID":"<YRE5pIGjmrAT7/zE@pendragon.ideasonboard.com>","References":"<20210809132929.1824114-1-kieran.bingham@ideasonboard.com>\n\t<20210809132929.1824114-4-kieran.bingham@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210809132929.1824114-4-kieran.bingham@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 3/3] libcamera: MappedFrameBuffer:\n\tUse typed Flags<MapFlags>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18635,"web_url":"https://patchwork.libcamera.org/comment/18635/","msgid":"<cdcb4efe-30ea-58d7-df66-c7887dca950e@ideasonboard.com>","date":"2021-08-09T16:26:43","subject":"Re: [libcamera-devel] [PATCH v3 3/3] libcamera: MappedFrameBuffer:\n\tUse typed Flags<MapFlags>","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Laurent,\n\nOn 09/08/2021 15:20, Laurent Pinchart wrote:\n> Hi Kieran,\n> \n> Thank you for the patch.\n> \n> On Mon, Aug 09, 2021 at 02:29:29PM +0100, Kieran Bingham wrote:\n>> Remove the need for callers to reference PROT_READ/PROT_WRITE directly\n>> from <sys/mman.h> by instead exposing the Read/Write mapping options as\n>> flags from the MappedFrameBuffer class itself.\n>>\n>> While here, introduce the <stdint.h> header which is required for the\n>> uint8_t as part of the Plane.\n>>\n>> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>>\n>> ---\n>> v2\n>>  - Use fully scoped enum class\n>>  - Swap MapMode and MapModes\n>>  - s/mmap_flags/mmapFlags/\n>>  - Remove and fix documentation regarding the modes\n>>  - add LIBCAMERA_FLAGS_ENABLE_OPERATORS()\n>>\n>> v3:\n>>  - Remove no longer necessary sys/mman.h inclusions throughout\n>>  - fix documentation\n>>  - rename MapMode as MapFlag and MapModes as MapFlags\n>> ---\n>>  .../libcamera/internal/mapped_framebuffer.h   | 15 ++++++--\n>>  src/android/jpeg/encoder_libjpeg.cpp          |  3 +-\n>>  src/android/jpeg/thumbnailer.cpp              |  2 +-\n>>  src/android/yuv/post_processor_yuv.cpp        |  2 +-\n>>  src/ipa/ipu3/ipu3.cpp                         |  3 +-\n>>  src/ipa/raspberrypi/raspberrypi.cpp           |  3 +-\n>>  src/libcamera/framebuffer.cpp                 |  1 -\n>>  src/libcamera/mapped_framebuffer.cpp          | 34 ++++++++++++++++---\n>>  test/mapped-buffer.cpp                        |  6 ++--\n>>  9 files changed, 51 insertions(+), 18 deletions(-)\n>>\n>> diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h\n>> index 41e587364260..68c8a43c35dc 100644\n>> --- a/include/libcamera/internal/mapped_framebuffer.h\n>> +++ b/include/libcamera/internal/mapped_framebuffer.h\n>> @@ -7,10 +7,11 @@\n>>  #ifndef __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__\n>>  #define __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__\n>>  \n>> -#include <sys/mman.h>\n>> +#include <stdint.h>\n>>  #include <vector>\n>>  \n>>  #include <libcamera/base/class.h>\n>> +#include <libcamera/base/flags.h>\n>>  #include <libcamera/base/span.h>\n>>  \n>>  #include <libcamera/framebuffer.h>\n>> @@ -44,9 +45,19 @@ private:\n>>  class MappedFrameBuffer : public MappedBuffer\n>>  {\n>>  public:\n>> -\tMappedFrameBuffer(const FrameBuffer *buffer, int flags);\n>> +\tenum class MapFlag {\n>> +\t\tRead = 0 << 1,\n>> +\t\tWrite = 1 << 1,\n> \n> Did you mean\n> \n> \t\tRead = 1 << 0,\n> \t\tWrite = 1 << 1,\n> \n\nYes, of course.\nMaybe we should have my favourite BIT() macro somewhere ...\n\n> ? Otherwise, Read == 0, Write == 1 and ReadWrite == 1.\n> \n> With this fixed,\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nFixed up, thanks.\n\n> \n>> +\t\tReadWrite = Read | Write,\n>> +\t};\n>> +\n>> +\tusing MapFlags = Flags<MapFlag>;\n>> +\n>> +\tMappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags);\n>>  };\n>>  \n>> +LIBCAMERA_FLAGS_ENABLE_OPERATORS(MappedFrameBuffer::MapFlag)\n>> +\n>>  } /* namespace libcamera */\n>>  \n>>  #endif /* __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ */\n>> diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp\n>> index 372018d2207f..a7a636011045 100644\n>> --- a/src/android/jpeg/encoder_libjpeg.cpp\n>> +++ b/src/android/jpeg/encoder_libjpeg.cpp\n>> @@ -12,7 +12,6 @@\n>>  #include <iostream>\n>>  #include <sstream>\n>>  #include <string.h>\n>> -#include <sys/mman.h>\n>>  #include <unistd.h>\n>>  #include <vector>\n>>  \n>> @@ -182,7 +181,7 @@ void EncoderLibJpeg::compressNV(Span<const uint8_t> frame)\n>>  int EncoderLibJpeg::encode(const FrameBuffer &source, Span<uint8_t> dest,\n>>  \t\t\t   Span<const uint8_t> exifData, unsigned int quality)\n>>  {\n>> -\tMappedFrameBuffer frame(&source, PROT_READ);\n>> +\tMappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);\n>>  \tif (!frame.isValid()) {\n>>  \t\tLOG(JPEG, Error) << \"Failed to map FrameBuffer : \"\n>>  \t\t\t\t << strerror(frame.error());\n>> diff --git a/src/android/jpeg/thumbnailer.cpp b/src/android/jpeg/thumbnailer.cpp\n>> index 535e2cece914..79d83926af5c 100644\n>> --- a/src/android/jpeg/thumbnailer.cpp\n>> +++ b/src/android/jpeg/thumbnailer.cpp\n>> @@ -41,7 +41,7 @@ void Thumbnailer::createThumbnail(const FrameBuffer &source,\n>>  \t\t\t\t  const Size &targetSize,\n>>  \t\t\t\t  std::vector<unsigned char> *destination)\n>>  {\n>> -\tMappedFrameBuffer frame(&source, PROT_READ);\n>> +\tMappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);\n>>  \tif (!frame.isValid()) {\n>>  \t\tLOG(Thumbnailer, Error)\n>>  \t\t\t<< \"Failed to map FrameBuffer : \"\n>> diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp\n>> index 509d4244d614..3e793a580377 100644\n>> --- a/src/android/yuv/post_processor_yuv.cpp\n>> +++ b/src/android/yuv/post_processor_yuv.cpp\n>> @@ -57,7 +57,7 @@ int PostProcessorYuv::process(const FrameBuffer &source,\n>>  \tif (!isValidBuffers(source, *destination))\n>>  \t\treturn -EINVAL;\n>>  \n>> -\tconst MappedFrameBuffer sourceMapped(&source, PROT_READ);\n>> +\tconst MappedFrameBuffer sourceMapped(&source, MappedFrameBuffer::MapFlag::Read);\n>>  \tif (!sourceMapped.isValid()) {\n>>  \t\tLOG(YUV, Error) << \"Failed to mmap camera frame buffer\";\n>>  \t\treturn -EINVAL;\n>> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\n>> index 2647bf2f3b96..10093acdad30 100644\n>> --- a/src/ipa/ipu3/ipu3.cpp\n>> +++ b/src/ipa/ipu3/ipu3.cpp\n>> @@ -6,7 +6,6 @@\n>>   */\n>>  \n>>  #include <stdint.h>\n>> -#include <sys/mman.h>\n>>  \n>>  #include <linux/intel-ipu3.h>\n>>  #include <linux/v4l2-controls.h>\n>> @@ -211,7 +210,7 @@ void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)\n>>  \tfor (const IPABuffer &buffer : buffers) {\n>>  \t\tconst FrameBuffer fb(buffer.planes);\n>>  \t\tbuffers_.emplace(buffer.id,\n>> -\t\t\t\t MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));\n>> +\t\t\t\t MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));\n>>  \t}\n>>  }\n>>  \n>> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\n>> index 76f67dd4567a..592e2fe41617 100644\n>> --- a/src/ipa/raspberrypi/raspberrypi.cpp\n>> +++ b/src/ipa/raspberrypi/raspberrypi.cpp\n>> @@ -411,7 +411,8 @@ void IPARPi::mapBuffers(const std::vector<IPABuffer> &buffers)\n>>  {\n>>  \tfor (const IPABuffer &buffer : buffers) {\n>>  \t\tconst FrameBuffer fb(buffer.planes);\n>> -\t\tbuffers_.emplace(buffer.id, MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));\n>> +\t\tbuffers_.emplace(buffer.id,\n>> +\t\t\t\t MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));\n>>  \t}\n>>  }\n>>  \n>> diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp\n>> index 3d98affb20f9..2223e24321ca 100644\n>> --- a/src/libcamera/framebuffer.cpp\n>> +++ b/src/libcamera/framebuffer.cpp\n>> @@ -10,7 +10,6 @@\n>>  \n>>  #include <errno.h>\n>>  #include <string.h>\n>> -#include <sys/mman.h>\n>>  #include <unistd.h>\n>>  \n>>  #include <libcamera/base/log.h>\n>> diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp\n>> index 0e30fc542154..5a70c18147f2 100644\n>> --- a/src/libcamera/mapped_framebuffer.cpp\n>> +++ b/src/libcamera/mapped_framebuffer.cpp\n>> @@ -142,21 +142,45 @@ MappedBuffer::~MappedBuffer()\n>>   * \\brief Map a FrameBuffer using the MappedBuffer interface\n>>   */\n>>  \n>> +/**\n>> + * \\enum MappedFrameBuffer::MapFlag\n>> + * \\brief Specify the mapping mode for the FrameBuffer\n>> + * \\var MappedFrameBuffer::Read\n>> + * \\brief Create a read-only mapping\n>> + * \\var MappedFrameBuffer::Write\n>> + * \\brief Create a write-only mapping\n>> + * \\var MappedFrameBuffer::ReadWrite\n>> + * \\brief Create a mapping that can be both read and written\n>> + */\n>> +\n>> +/**\n>> + * \\typedef MappedFrameBuffer::MapFlags\n>> + * \\brief A bitwise combination of MappedFrameBuffer::MapFlag values\n>> + */\n>> +\n>>  /**\n>>   * \\brief Map all planes of a FrameBuffer\n>>   * \\param[in] buffer FrameBuffer to be mapped\n>>   * \\param[in] flags Protection flags to apply to map\n>>   *\n>> - * Construct an object to map a frame buffer for CPU access.\n>> - * The flags are passed directly to mmap and should be either PROT_READ,\n>> - * PROT_WRITE, or a bitwise-or combination of both.\n>> + * Construct an object to map a frame buffer for CPU access. The mapping can be\n>> + * made as Read only, Write only or support Read and Write operations by setting\n>> + * the MapFlag flags accordingly.\n>>   */\n>> -MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags)\n>> +MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags)\n>>  {\n>>  \tmaps_.reserve(buffer->planes().size());\n>>  \n>> +\tint mmapFlags = 0;\n>> +\n>> +\tif (flags & MapFlag::Read)\n>> +\t\tmmapFlags |= PROT_READ;\n>> +\n>> +\tif (flags & MapFlag::Write)\n>> +\t\tmmapFlags |= PROT_WRITE;\n>> +\n>>  \tfor (const FrameBuffer::Plane &plane : buffer->planes()) {\n>> -\t\tvoid *address = mmap(nullptr, plane.length, flags,\n>> +\t\tvoid *address = mmap(nullptr, plane.length, mmapFlags,\n>>  \t\t\t\t     MAP_SHARED, plane.fd.fd(), 0);\n>>  \t\tif (address == MAP_FAILED) {\n>>  \t\t\terror_ = -errno;\n>> diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp\n>> index a3d1511b74ce..97571945cbca 100644\n>> --- a/test/mapped-buffer.cpp\n>> +++ b/test/mapped-buffer.cpp\n>> @@ -71,7 +71,7 @@ protected:\n>>  \t\tconst std::unique_ptr<FrameBuffer> &buffer = allocator_->buffers(stream_).front();\n>>  \t\tstd::vector<MappedBuffer> maps;\n>>  \n>> -\t\tMappedFrameBuffer map(buffer.get(), PROT_READ);\n>> +\t\tMappedFrameBuffer map(buffer.get(), MappedFrameBuffer::MapFlag::Read);\n>>  \t\tif (!map.isValid()) {\n>>  \t\t\tcout << \"Failed to successfully map buffer\" << endl;\n>>  \t\t\treturn TestFail;\n>> @@ -90,13 +90,13 @@ protected:\n>>  \t\t}\n>>  \n>>  \t\t/* Test for multiple successful maps on the same buffer. */\n>> -\t\tMappedFrameBuffer write_map(buffer.get(), PROT_WRITE);\n>> +\t\tMappedFrameBuffer write_map(buffer.get(), MappedFrameBuffer::MapFlag::Write);\n>>  \t\tif (!write_map.isValid()) {\n>>  \t\t\tcout << \"Failed to map write buffer\" << endl;\n>>  \t\t\treturn TestFail;\n>>  \t\t}\n>>  \n>> -\t\tMappedFrameBuffer rw_map(buffer.get(), PROT_READ | PROT_WRITE);\n>> +\t\tMappedFrameBuffer rw_map(buffer.get(), MappedFrameBuffer::MapFlag::ReadWrite);\n>>  \t\tif (!rw_map.isValid()) {\n>>  \t\t\tcout << \"Failed to map RW buffer\" << endl;\n>>  \t\t\treturn TestFail;\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 1AE0DBD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  9 Aug 2021 16:26:49 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6CB2D687EB;\n\tMon,  9 Aug 2021 18:26:48 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B6AFE60269\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  9 Aug 2021 18:26:46 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1CFEA466;\n\tMon,  9 Aug 2021 18:26:46 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Dmj4R7Ae\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1628526406;\n\tbh=uNlvOA1tJ7I2/y14sHl2oiBnRLEh0fB7W7oqttDE3Ew=;\n\th=From:To:Cc:References:Subject:Date:In-Reply-To:From;\n\tb=Dmj4R7Ae6pfNPExbVu32NOY0XcObEjYjzbFCAfYg7Lc1jynTcByL78ONhWg1gvQGw\n\tClW7nog00ZHC0wNgAMZ+s8rQoNvnKXbYD9VGQsxBKxdqvCzDiQJascybRtumtLrCYZ\n\tYUMvzSpa+xgkGEbwBT5eNKrS6Q6lD7/KLniuzEt4=","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20210809132929.1824114-1-kieran.bingham@ideasonboard.com>\n\t<20210809132929.1824114-4-kieran.bingham@ideasonboard.com>\n\t<YRE5pIGjmrAT7/zE@pendragon.ideasonboard.com>","Message-ID":"<cdcb4efe-30ea-58d7-df66-c7887dca950e@ideasonboard.com>","Date":"Mon, 9 Aug 2021 17:26:43 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101\n\tThunderbird/78.11.0","MIME-Version":"1.0","In-Reply-To":"<YRE5pIGjmrAT7/zE@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-GB","Content-Transfer-Encoding":"8bit","Subject":"Re: [libcamera-devel] [PATCH v3 3/3] libcamera: MappedFrameBuffer:\n\tUse typed Flags<MapFlags>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":18652,"web_url":"https://patchwork.libcamera.org/comment/18652/","msgid":"<CAO5uPHOgywbWV4j1T0VRS0t_OhmL=iJXCmnN=R_bk4mfExdWWw@mail.gmail.com>","date":"2021-08-10T02:48:36","subject":"Re: [libcamera-devel] [PATCH v3 3/3] libcamera: MappedFrameBuffer:\n\tUse typed Flags<MapFlags>","submitter":{"id":63,"url":"https://patchwork.libcamera.org/api/people/63/","name":"Hirokazu Honda","email":"hiroh@chromium.org"},"content":"Hi Kieran, thank you for the patch.\n\nOn Tue, Aug 10, 2021 at 1:26 AM Kieran Bingham\n<kieran.bingham@ideasonboard.com> wrote:\n>\n> Hi Laurent,\n>\n> On 09/08/2021 15:20, Laurent Pinchart wrote:\n> > Hi Kieran,\n> >\n> > Thank you for the patch.\n> >\n> > On Mon, Aug 09, 2021 at 02:29:29PM +0100, Kieran Bingham wrote:\n> >> Remove the need for callers to reference PROT_READ/PROT_WRITE directly\n> >> from <sys/mman.h> by instead exposing the Read/Write mapping options as\n> >> flags from the MappedFrameBuffer class itself.\n> >>\n> >> While here, introduce the <stdint.h> header which is required for the\n> >> uint8_t as part of the Plane.\n> >>\n> >> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> >>\n> >> ---\n> >> v2\n> >>  - Use fully scoped enum class\n> >>  - Swap MapMode and MapModes\n> >>  - s/mmap_flags/mmapFlags/\n> >>  - Remove and fix documentation regarding the modes\n> >>  - add LIBCAMERA_FLAGS_ENABLE_OPERATORS()\n> >>\n> >> v3:\n> >>  - Remove no longer necessary sys/mman.h inclusions throughout\n> >>  - fix documentation\n> >>  - rename MapMode as MapFlag and MapModes as MapFlags\n> >> ---\n> >>  .../libcamera/internal/mapped_framebuffer.h   | 15 ++++++--\n> >>  src/android/jpeg/encoder_libjpeg.cpp          |  3 +-\n> >>  src/android/jpeg/thumbnailer.cpp              |  2 +-\n> >>  src/android/yuv/post_processor_yuv.cpp        |  2 +-\n> >>  src/ipa/ipu3/ipu3.cpp                         |  3 +-\n> >>  src/ipa/raspberrypi/raspberrypi.cpp           |  3 +-\n> >>  src/libcamera/framebuffer.cpp                 |  1 -\n> >>  src/libcamera/mapped_framebuffer.cpp          | 34 ++++++++++++++++---\n> >>  test/mapped-buffer.cpp                        |  6 ++--\n> >>  9 files changed, 51 insertions(+), 18 deletions(-)\n> >>\n> >> diff --git a/include/libcamera/internal/mapped_framebuffer.h b/include/libcamera/internal/mapped_framebuffer.h\n> >> index 41e587364260..68c8a43c35dc 100644\n> >> --- a/include/libcamera/internal/mapped_framebuffer.h\n> >> +++ b/include/libcamera/internal/mapped_framebuffer.h\n> >> @@ -7,10 +7,11 @@\n> >>  #ifndef __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__\n> >>  #define __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__\n> >>\n> >> -#include <sys/mman.h>\n> >> +#include <stdint.h>\n> >>  #include <vector>\n> >>\n> >>  #include <libcamera/base/class.h>\n> >> +#include <libcamera/base/flags.h>\n> >>  #include <libcamera/base/span.h>\n> >>\n> >>  #include <libcamera/framebuffer.h>\n> >> @@ -44,9 +45,19 @@ private:\n> >>  class MappedFrameBuffer : public MappedBuffer\n> >>  {\n> >>  public:\n> >> -    MappedFrameBuffer(const FrameBuffer *buffer, int flags);\n> >> +    enum class MapFlag {\n> >> +            Read = 0 << 1,\n> >> +            Write = 1 << 1,\n> >\n> > Did you mean\n> >\n> >               Read = 1 << 0,\n> >               Write = 1 << 1,\n> >\n>\n> Yes, of course.\n> Maybe we should have my favourite BIT() macro somewhere ...\n>\n> > ? Otherwise, Read == 0, Write == 1 and ReadWrite == 1.\n> >\n> > With this fixed,\n> >\n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n\nReviewed-by: Hirokazu Honda <hiroh@chromium.org>\n\n> Fixed up, thanks.\n>\n> >\n> >> +            ReadWrite = Read | Write,\n> >> +    };\n> >> +\n> >> +    using MapFlags = Flags<MapFlag>;\n> >> +\n> >> +    MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags);\n> >>  };\n> >>\n> >> +LIBCAMERA_FLAGS_ENABLE_OPERATORS(MappedFrameBuffer::MapFlag)\n> >> +\n> >>  } /* namespace libcamera */\n> >>\n> >>  #endif /* __LIBCAMERA_INTERNAL_MAPPED_FRAMEBUFFER_H__ */\n> >> diff --git a/src/android/jpeg/encoder_libjpeg.cpp b/src/android/jpeg/encoder_libjpeg.cpp\n> >> index 372018d2207f..a7a636011045 100644\n> >> --- a/src/android/jpeg/encoder_libjpeg.cpp\n> >> +++ b/src/android/jpeg/encoder_libjpeg.cpp\n> >> @@ -12,7 +12,6 @@\n> >>  #include <iostream>\n> >>  #include <sstream>\n> >>  #include <string.h>\n> >> -#include <sys/mman.h>\n> >>  #include <unistd.h>\n> >>  #include <vector>\n> >>\n> >> @@ -182,7 +181,7 @@ void EncoderLibJpeg::compressNV(Span<const uint8_t> frame)\n> >>  int EncoderLibJpeg::encode(const FrameBuffer &source, Span<uint8_t> dest,\n> >>                         Span<const uint8_t> exifData, unsigned int quality)\n> >>  {\n> >> -    MappedFrameBuffer frame(&source, PROT_READ);\n> >> +    MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);\n> >>      if (!frame.isValid()) {\n> >>              LOG(JPEG, Error) << \"Failed to map FrameBuffer : \"\n> >>                               << strerror(frame.error());\n> >> diff --git a/src/android/jpeg/thumbnailer.cpp b/src/android/jpeg/thumbnailer.cpp\n> >> index 535e2cece914..79d83926af5c 100644\n> >> --- a/src/android/jpeg/thumbnailer.cpp\n> >> +++ b/src/android/jpeg/thumbnailer.cpp\n> >> @@ -41,7 +41,7 @@ void Thumbnailer::createThumbnail(const FrameBuffer &source,\n> >>                                const Size &targetSize,\n> >>                                std::vector<unsigned char> *destination)\n> >>  {\n> >> -    MappedFrameBuffer frame(&source, PROT_READ);\n> >> +    MappedFrameBuffer frame(&source, MappedFrameBuffer::MapFlag::Read);\n> >>      if (!frame.isValid()) {\n> >>              LOG(Thumbnailer, Error)\n> >>                      << \"Failed to map FrameBuffer : \"\n> >> diff --git a/src/android/yuv/post_processor_yuv.cpp b/src/android/yuv/post_processor_yuv.cpp\n> >> index 509d4244d614..3e793a580377 100644\n> >> --- a/src/android/yuv/post_processor_yuv.cpp\n> >> +++ b/src/android/yuv/post_processor_yuv.cpp\n> >> @@ -57,7 +57,7 @@ int PostProcessorYuv::process(const FrameBuffer &source,\n> >>      if (!isValidBuffers(source, *destination))\n> >>              return -EINVAL;\n> >>\n> >> -    const MappedFrameBuffer sourceMapped(&source, PROT_READ);\n> >> +    const MappedFrameBuffer sourceMapped(&source, MappedFrameBuffer::MapFlag::Read);\n> >>      if (!sourceMapped.isValid()) {\n> >>              LOG(YUV, Error) << \"Failed to mmap camera frame buffer\";\n> >>              return -EINVAL;\n> >> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\n> >> index 2647bf2f3b96..10093acdad30 100644\n> >> --- a/src/ipa/ipu3/ipu3.cpp\n> >> +++ b/src/ipa/ipu3/ipu3.cpp\n> >> @@ -6,7 +6,6 @@\n> >>   */\n> >>\n> >>  #include <stdint.h>\n> >> -#include <sys/mman.h>\n> >>\n> >>  #include <linux/intel-ipu3.h>\n> >>  #include <linux/v4l2-controls.h>\n> >> @@ -211,7 +210,7 @@ void IPAIPU3::mapBuffers(const std::vector<IPABuffer> &buffers)\n> >>      for (const IPABuffer &buffer : buffers) {\n> >>              const FrameBuffer fb(buffer.planes);\n> >>              buffers_.emplace(buffer.id,\n> >> -                             MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));\n> >> +                             MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));\n> >>      }\n> >>  }\n> >>\n> >> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp\n> >> index 76f67dd4567a..592e2fe41617 100644\n> >> --- a/src/ipa/raspberrypi/raspberrypi.cpp\n> >> +++ b/src/ipa/raspberrypi/raspberrypi.cpp\n> >> @@ -411,7 +411,8 @@ void IPARPi::mapBuffers(const std::vector<IPABuffer> &buffers)\n> >>  {\n> >>      for (const IPABuffer &buffer : buffers) {\n> >>              const FrameBuffer fb(buffer.planes);\n> >> -            buffers_.emplace(buffer.id, MappedFrameBuffer(&fb, PROT_READ | PROT_WRITE));\n> >> +            buffers_.emplace(buffer.id,\n> >> +                             MappedFrameBuffer(&fb, MappedFrameBuffer::MapFlag::ReadWrite));\n> >>      }\n> >>  }\n> >>\n> >> diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp\n> >> index 3d98affb20f9..2223e24321ca 100644\n> >> --- a/src/libcamera/framebuffer.cpp\n> >> +++ b/src/libcamera/framebuffer.cpp\n> >> @@ -10,7 +10,6 @@\n> >>\n> >>  #include <errno.h>\n> >>  #include <string.h>\n> >> -#include <sys/mman.h>\n> >>  #include <unistd.h>\n> >>\n> >>  #include <libcamera/base/log.h>\n> >> diff --git a/src/libcamera/mapped_framebuffer.cpp b/src/libcamera/mapped_framebuffer.cpp\n> >> index 0e30fc542154..5a70c18147f2 100644\n> >> --- a/src/libcamera/mapped_framebuffer.cpp\n> >> +++ b/src/libcamera/mapped_framebuffer.cpp\n> >> @@ -142,21 +142,45 @@ MappedBuffer::~MappedBuffer()\n> >>   * \\brief Map a FrameBuffer using the MappedBuffer interface\n> >>   */\n> >>\n> >> +/**\n> >> + * \\enum MappedFrameBuffer::MapFlag\n> >> + * \\brief Specify the mapping mode for the FrameBuffer\n> >> + * \\var MappedFrameBuffer::Read\n> >> + * \\brief Create a read-only mapping\n> >> + * \\var MappedFrameBuffer::Write\n> >> + * \\brief Create a write-only mapping\n> >> + * \\var MappedFrameBuffer::ReadWrite\n> >> + * \\brief Create a mapping that can be both read and written\n> >> + */\n> >> +\n> >> +/**\n> >> + * \\typedef MappedFrameBuffer::MapFlags\n> >> + * \\brief A bitwise combination of MappedFrameBuffer::MapFlag values\n> >> + */\n> >> +\n> >>  /**\n> >>   * \\brief Map all planes of a FrameBuffer\n> >>   * \\param[in] buffer FrameBuffer to be mapped\n> >>   * \\param[in] flags Protection flags to apply to map\n> >>   *\n> >> - * Construct an object to map a frame buffer for CPU access.\n> >> - * The flags are passed directly to mmap and should be either PROT_READ,\n> >> - * PROT_WRITE, or a bitwise-or combination of both.\n> >> + * Construct an object to map a frame buffer for CPU access. The mapping can be\n> >> + * made as Read only, Write only or support Read and Write operations by setting\n> >> + * the MapFlag flags accordingly.\n> >>   */\n> >> -MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, int flags)\n> >> +MappedFrameBuffer::MappedFrameBuffer(const FrameBuffer *buffer, MapFlags flags)\n> >>  {\n> >>      maps_.reserve(buffer->planes().size());\n> >>\n> >> +    int mmapFlags = 0;\n> >> +\n> >> +    if (flags & MapFlag::Read)\n> >> +            mmapFlags |= PROT_READ;\n> >> +\n> >> +    if (flags & MapFlag::Write)\n> >> +            mmapFlags |= PROT_WRITE;\n> >> +\n> >>      for (const FrameBuffer::Plane &plane : buffer->planes()) {\n> >> -            void *address = mmap(nullptr, plane.length, flags,\n> >> +            void *address = mmap(nullptr, plane.length, mmapFlags,\n> >>                                   MAP_SHARED, plane.fd.fd(), 0);\n> >>              if (address == MAP_FAILED) {\n> >>                      error_ = -errno;\n> >> diff --git a/test/mapped-buffer.cpp b/test/mapped-buffer.cpp\n> >> index a3d1511b74ce..97571945cbca 100644\n> >> --- a/test/mapped-buffer.cpp\n> >> +++ b/test/mapped-buffer.cpp\n> >> @@ -71,7 +71,7 @@ protected:\n> >>              const std::unique_ptr<FrameBuffer> &buffer = allocator_->buffers(stream_).front();\n> >>              std::vector<MappedBuffer> maps;\n> >>\n> >> -            MappedFrameBuffer map(buffer.get(), PROT_READ);\n> >> +            MappedFrameBuffer map(buffer.get(), MappedFrameBuffer::MapFlag::Read);\n> >>              if (!map.isValid()) {\n> >>                      cout << \"Failed to successfully map buffer\" << endl;\n> >>                      return TestFail;\n> >> @@ -90,13 +90,13 @@ protected:\n> >>              }\n> >>\n> >>              /* Test for multiple successful maps on the same buffer. */\n> >> -            MappedFrameBuffer write_map(buffer.get(), PROT_WRITE);\n> >> +            MappedFrameBuffer write_map(buffer.get(), MappedFrameBuffer::MapFlag::Write);\n> >>              if (!write_map.isValid()) {\n> >>                      cout << \"Failed to map write buffer\" << endl;\n> >>                      return TestFail;\n> >>              }\n> >>\n> >> -            MappedFrameBuffer rw_map(buffer.get(), PROT_READ | PROT_WRITE);\n> >> +            MappedFrameBuffer rw_map(buffer.get(), MappedFrameBuffer::MapFlag::ReadWrite);\n> >>              if (!rw_map.isValid()) {\n> >>                      cout << \"Failed to map RW buffer\" << endl;\n> >>                      return TestFail;\n> >","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 21D09BD87D\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 10 Aug 2021 02:48:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9E403687FA;\n\tTue, 10 Aug 2021 04:48:49 +0200 (CEST)","from mail-ed1-x530.google.com (mail-ed1-x530.google.com\n\t[IPv6:2a00:1450:4864:20::530])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D30DC687EB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 10 Aug 2021 04:48:47 +0200 (CEST)","by mail-ed1-x530.google.com with SMTP id i6so27913355edu.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 09 Aug 2021 19:48:47 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"JIBGRrNr\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=jN/cz9aWBEmm1G6cxNzIDkc435OVO+hwxEqi+3IQ8ZM=;\n\tb=JIBGRrNrqyLgB74voKNUJtVRbojlhfWiUU/HbhEl4DC82gKwRevK7hnN+MXlD6K5by\n\t0+wmU+pWcSJlcZZVgEEGLlYRohxXUHqi7P9kLbIcrsWy2ucU3OWH7ItcI9r9DbxfB/x9\n\tk1SNeT0xaGKmNZ+Hs0hynWPmd9TizWEy5mf1I=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=jN/cz9aWBEmm1G6cxNzIDkc435OVO+hwxEqi+3IQ8ZM=;\n\tb=GBHbryvlU5TKdbluPji0nzpEZpvR19827i1F1NJNYoqKJr0dIgkuGQjrkXWbfYqELd\n\tAWJxXoUHiEzPPoNJp+2Y33g1rb9Sdh4NA/JOC2ZSq9EfNIJXy/jd6vTMK1FASK6Ko3n1\n\t6SQT5EAMVZ80re3FKPv+/Qfd5OlaskASbvIs142mpDe/jPOTr08KNqB6J8IRwp3wwAB9\n\tYImKP0WpUfiehGcWAX/UsmtLtPqNPufyip9GLX5wEtiHigmfh36mFP08GWp5bVOQBEQk\n\tGfo0rE/Lot4WKdcDKnytCo+P9Jkjbv/DuQcLUpN3q9YQYaNxpct9Q2EDlpZ+uiSzKiLm\n\tt6rw==","X-Gm-Message-State":"AOAM532jXnk5xKO/voY9UV6PrLPTsQ+GcwwxODTKI7WbH0/CK8x7/E3U\n\tlTMTqdsXinLKeQcUGZDAu2pS2Pgz51feqNxxlbPddQ==","X-Google-Smtp-Source":"ABdhPJz0YF0oTjhAUioSkCI0YIAF4NLxdyprNTSLQSZCC2BKuno4GPc1rHvYS8gFZ/mfSh813oKIEaFAyF4a2CqYj/A=","X-Received":"by 2002:a50:9e87:: with SMTP id a7mr2032735edf.202.1628563727479;\n\tMon, 09 Aug 2021 19:48:47 -0700 (PDT)","MIME-Version":"1.0","References":"<20210809132929.1824114-1-kieran.bingham@ideasonboard.com>\n\t<20210809132929.1824114-4-kieran.bingham@ideasonboard.com>\n\t<YRE5pIGjmrAT7/zE@pendragon.ideasonboard.com>\n\t<cdcb4efe-30ea-58d7-df66-c7887dca950e@ideasonboard.com>","In-Reply-To":"<cdcb4efe-30ea-58d7-df66-c7887dca950e@ideasonboard.com>","From":"Hirokazu Honda <hiroh@chromium.org>","Date":"Tue, 10 Aug 2021 11:48:36 +0900","Message-ID":"<CAO5uPHOgywbWV4j1T0VRS0t_OhmL=iJXCmnN=R_bk4mfExdWWw@mail.gmail.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [PATCH v3 3/3] libcamera: MappedFrameBuffer:\n\tUse typed Flags<MapFlags>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]