// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "logical_buffer_collection.h"

#include "buffer_collection.h"
#include "buffer_collection_token.h"
#include "koid_util.h"
#include "usage_pixel_format_cost.h"

#include <lib/image-format/image_format.h>
#include <limits.h> // PAGE_SIZE
#include <limits> // std::numeric_limits
#include <zircon/assert.h>

namespace {

// Sysmem is creating the VMOs, so sysmem can have all the rights and just not
// mis-use any rights.  Remove ZX_RIGHT_EXECUTE though.
const uint32_t kSysmemVmoRights = ZX_DEFAULT_VMO_RIGHTS & ~ZX_RIGHT_EXECUTE;
// 1 GiB cap for now.
const uint64_t kMaxTotalSizeBytesPerCollection = 1ull * 1024 * 1024 * 1024;
// 256 MiB cap for now.
const uint64_t kMaxSizeBytesPerBuffer = 256ull * 1024 * 1024;

template <typename T> bool IsNonZeroPowerOf2(T value) {
    if (!value) {
        return false;
    }
    if (value & (value - 1)) {
        return false;
    }
    return true;
}

// TODO(dustingreen): Switch to FIDL C++ generated code (preferred) and remove
// this, or fully implement something like this for all fields that need 0 to
// imply a default value that isn't 0.
template <typename T> void FieldDefault1(T* value) {
    if (*value == 0) {
        *value = 1;
    }
}

template <typename T> void FieldDefaultMax(T* value) {
    if (*value == 0) {
        *value = std::numeric_limits<T>::max();
    }
}

// This exists just to document the meaning for now, to make the conversion more
// clear when we switch from FIDL struct to FIDL table.
template <typename T> void FieldDefaultZero(T* value) {
    // no-op
}

template <typename T> T AlignUp(T value, T divisor) {
    return (value + divisor - 1) / divisor * divisor;
}

bool IsCpuUsage(const fuchsia_sysmem_BufferUsage& usage) {
    return usage.cpu != 0;
}

} // namespace

// static
void LogicalBufferCollection::Create(
    zx::channel buffer_collection_token_request, Device* parent_device) {
    fbl::RefPtr<LogicalBufferCollection> logical_buffer_collection =
        fbl::AdoptRef<LogicalBufferCollection>(
            new LogicalBufferCollection(parent_device));
    // The existence of a channel-owned BufferCollectionToken adds a
    // fbl::RefPtr<> ref to LogicalBufferCollection.
    LogInfo("LogicalBufferCollection::Create()");
    logical_buffer_collection->CreateBufferCollectionToken(
        logical_buffer_collection, std::numeric_limits<uint32_t>::max(),
        std::move(buffer_collection_token_request));
}

// static
//
// The buffer_collection_token is the client end of the BufferCollectionToken
// which the client is exchanging for the BufferCollection (which the client is
// passing the server end of in buffer_collection_request).
//
// However, before we convert the client's token into a BufferCollection and
// start processing the messages the client may have already sent toward the
// BufferCollection, we want to process all the messages the client may have
// already sent toward the BufferCollectionToken.  This comes up because the
// BufferCollectionToken and Allocator2 are separate channels.
//
// We know that fidl_server will process all messages before it processes the
// close - it intentionally delays noticing the close until no messages are
// available to read.
//
// So this method will close the buffer_collection_token and when it closes via
// normal FIDL processing path, the token will remember the
// buffer_collection_request to essentially convert itself into.
void LogicalBufferCollection::BindSharedCollection(
    Device* parent_device,
    zx::channel buffer_collection_token,
    zx::channel buffer_collection_request) {
    ZX_DEBUG_ASSERT(buffer_collection_token);
    ZX_DEBUG_ASSERT(buffer_collection_request);

    zx_koid_t token_client_koid;
    zx_koid_t token_server_koid;
    zx_status_t status = get_channel_koids(
        buffer_collection_token, &token_client_koid, &token_server_koid);
    if (status != ZX_OK) {
        // ~buffer_collection_token
        // ~buffer_collection_request
        return;
    }

    BufferCollectionToken* token =
        parent_device->FindTokenByServerChannelKoid(token_server_koid);
    if (!token) {
        // ~buffer_collection_token
        // ~buffer_collection_request
        return;
    }

    // This will token->FailAsync() if the token has already got one, or if the
    // token already saw token->Close().
    token->SetBufferCollectionRequest(std::move(buffer_collection_request));

    // At this point, the token will process the rest of its previously queued
    // messages (from client to server), and then will convert the token into
    // a BufferCollection (view).  That conversion happens async shortly in
    // BindSharedCollectionInternal() (unless the LogicalBufferCollection fails
    // before then, in which case everything just gets deleted).
    //
    // ~buffer_collection_token here closes the client end of the token, but we
    // still process the rest of the queued messages before we process the
    // close.
    //
    // ~buffer_collection_token
}

void LogicalBufferCollection::CreateBufferCollectionToken(
    fbl::RefPtr<LogicalBufferCollection> self, uint32_t rights_attenuation_mask,
    zx::channel buffer_collection_token_request) {
    auto token = BufferCollectionToken::Create(
        parent_device_, self, rights_attenuation_mask);
    token->SetErrorHandler([this, token_ptr = token.get()](zx_status_t status) {
        // Clean close from FIDL channel point of view is ZX_ERR_PEER_CLOSED,
        // and ZX_OK is never passed to the error handler.
        ZX_DEBUG_ASSERT(status != ZX_OK);

        // We know |this| is alive because the token is alive and the token has
        // a fbl::RefPtr<LogicalBufferCollection>.  The token is alive because
        // the token is still in token_views_.
        //
        // Any other deletion of the token_ptr out of token_views_ (outside of
        // this error handler) doesn't run this error handler.
        //
        // TODO(dustingreen): Switch to contains() when C++20.
        ZX_DEBUG_ASSERT(token_views_.find(token_ptr) != token_views_.end());

        zx::channel buffer_collection_request =
            token_ptr->TakeBufferCollectionRequest();

        if (!(status == ZX_ERR_PEER_CLOSED &&
              (token_ptr->is_done() || buffer_collection_request))) {
            // We don't have to explicitly remove token from token_views_
            // because Fail() will token_views_.clear().
            //
            // A token whose error handler sees anything other than clean close
            // with is_done() implies LogicalBufferCollection failure.  The
            // ability to detect unexpected closure of a token is a main reason
            // we use a channel for BufferCollectionToken instead of an
            // eventpair.
            Fail("Token failure causing LogicalBufferCollection failure - "
                 "status: %d",
                 status);
            return;
        }

        // At this point we know the token channel was closed cleanly, and that
        // before the client's closing the channel, the client did a
        // token::Close() or allocator::BindSharedCollection().
        ZX_DEBUG_ASSERT(status == ZX_ERR_PEER_CLOSED &&
                        (token_ptr->is_done() || buffer_collection_request));
        // BufferCollectionToken enforces that these never both become true; the
        // BufferCollectionToken will fail instead.
        ZX_DEBUG_ASSERT(!(token_ptr->is_done() && buffer_collection_request));

        if (!buffer_collection_request) {
            // This was a token::Close().  In this case we want to stop tracking
            // the token now that we've processed all its previously-queued
            // inbound messages.  This might be the last token, so we
            // MaybeAllocate().  This path isn't a failure.
            auto self = token_ptr->parent_shared();
            ZX_DEBUG_ASSERT(self.get() == this);
            token_views_.erase(token_ptr);
            MaybeAllocate();
            // ~self - might delete this
        }

        // At this point we know that this was a BindSharedCollection().  We
        // need to convert the BufferCollectionToken into a BufferCollection.
        //
        // ~token_ptr during this call
        BindSharedCollectionInternal(token_ptr,
                                     std::move(buffer_collection_request));
    });
    auto token_ptr = token.get();
    token_views_.insert({token_ptr, std::move(token)});

    zx_koid_t server_koid;
    zx_koid_t client_koid;
    zx_status_t status = get_channel_koids(buffer_collection_token_request,
                                           &server_koid, &client_koid);
    if (status != ZX_OK) {
        Fail("get_channel_koids() failed - status: %d", status);
        return;
    }
    token_ptr->SetServerKoid(server_koid);

    LogInfo("CreateBufferCollectionToken() - server_koid: %lu",
            token_ptr->server_koid());
    token_ptr->Bind(std::move(buffer_collection_token_request));
}

void LogicalBufferCollection::OnSetConstraints() {
    MaybeAllocate();
    return;
}

LogicalBufferCollection::AllocationResult
LogicalBufferCollection::allocation_result() {
    ZX_DEBUG_ASSERT(
        has_allocation_result_ ||
        (allocation_result_status_ == ZX_OK && !allocation_result_info_));
    return {
        .buffer_collection_info = allocation_result_info_.get(),
        .status = allocation_result_status_,
    };
}

LogicalBufferCollection::LogicalBufferCollection(Device* parent_device)
    : parent_device_(parent_device), constraints_(Constraints::Null) {
    // nothing else to do here
}

LogicalBufferCollection::~LogicalBufferCollection() {
    LogInfo("~LogicalBufferCollection");
    // Every entry in these collections keeps a
    // fbl::RefPtr<LogicalBufferCollection>, so these should both already be
    // empty.
    ZX_DEBUG_ASSERT(token_views_.empty());
    ZX_DEBUG_ASSERT(collection_views_.empty());
}

void LogicalBufferCollection::Fail(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vLog(true, "LogicalBufferCollection", "fail", format, args);
    va_end(args);

    // Close all the associated channels.  We do this by swapping into local
    // collections and clearing those, since deleting the items in the
    // collections will delete |this|.
    TokenMap local_token_views;
    token_views_.swap(local_token_views);
    CollectionMap local_collection_views;
    collection_views_.swap(local_collection_views);

    // |this| is very likely to be deleted during these calls to clear().  The
    // only exception is if the caller of Fail() happens to have its own
    // temporary fbl::RefPtr<LogicalBufferCollection> on the stack.
    local_token_views.clear();
    local_collection_views.clear();
}

void LogicalBufferCollection::LogInfo(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vLog(false, "LogicalBufferCollection", "info", format, args);
    va_end(args);
}

void LogicalBufferCollection::LogError(const char* format, ...) {
    va_list args;
    va_start(args, format);
    vLog(true, "LogicalBufferCollection", "error", format, args);
    va_end(args);
}

void LogicalBufferCollection::MaybeAllocate() {
    if (is_allocate_attempted_) {
        // Allocate was already attempted.
        return;
    }
    if (!token_views_.empty()) {
        // All tokens must be converted into BufferCollection views or Close()ed
        // before allocation will happen.
        return;
    }
    if (collection_views_.empty()) {
        // No point in allocating if there aren't any BufferCollection views
        // left either.
        return;
    }
    // Sweep looking for any views that haven't set constraints.
    for (auto& [key, value] : collection_views_) {
        if (!key->is_set_constraints_seen()) {
            return;
        }
    }
    // All the views have seen SetConstraints(), and there are no tokens left.
    // Regardless of whether allocation succeeds or fails, we remember we've
    // started an attempt to allocate so we don't attempt again.
    is_allocate_attempted_ = true;
    TryAllocate();
    return;
}

// This only runs on a clean stack.
void LogicalBufferCollection::TryAllocate() {
    // If we're here it means we still have collection_views_, because if the
    // last collection view disappeared we would have run ~this which would have
    // cleared the Post() canary so this method woudn't be running.
    ZX_DEBUG_ASSERT(!collection_views_.empty());

    // Currently only BufferCollection(s) that have already done a clean Close()
    // have their constraints in constraints_list_.  Now we want all the rest of
    // the constraints represented in collection_views_ to be in
    // constraints_list_ so we can just process constraints_list_ in
    // CombineConstraints().  These can't be moved, only cloned, because the
    // still-alive BufferCollection(s) will still want to refer to their
    // constraints at least for GetUsageBasedRightsAttenuation() purposes.
    for (auto& [key, value] : collection_views_) {
        ZX_DEBUG_ASSERT(key->is_set_constraints_seen());
        if (key->constraints()) {
            constraints_list_.emplace_back(
                BufferCollectionConstraintsClone(key->constraints()));
        }
    }

    if (!CombineConstraints()) {
        // It's impossible to combine the constraints due to incompatible
        // constraints, or all participants set null constraints.
        SetFailedAllocationResult(ZX_ERR_NOT_SUPPORTED);
        return;
    }
    ZX_DEBUG_ASSERT(!!constraints_);

    zx_status_t allocate_result = ZX_OK;
    BufferCollectionInfo allocation = Allocate(&allocate_result);
    if (!allocation) {
        ZX_DEBUG_ASSERT(allocate_result != ZX_OK);
        SetFailedAllocationResult(allocate_result);
        return;
    }
    ZX_DEBUG_ASSERT(allocate_result == ZX_OK);

    SetAllocationResult(std::move(allocation));
    return;
}

void LogicalBufferCollection::SetFailedAllocationResult(zx_status_t status) {
    ZX_DEBUG_ASSERT(status != ZX_OK);

    // Only set result once.
    ZX_DEBUG_ASSERT(!has_allocation_result_);
    // allocation_result_status_ is initialized to ZX_OK, so should still be set
    // that way.
    ZX_DEBUG_ASSERT(allocation_result_status_ == ZX_OK);

    allocation_result_status_ = status;
    // Was initialized to nullptr.
    ZX_DEBUG_ASSERT(!allocation_result_info_);
    has_allocation_result_ = true;
    SendAllocationResult();
    return;
}

void LogicalBufferCollection::SetAllocationResult(BufferCollectionInfo info) {
    // Setting null constraints as the success case isn't allowed.  That's
    // considered a failure.  At least one participant must specify non-null
    // constraints.
    ZX_DEBUG_ASSERT(info);

    // Only set result once.
    ZX_DEBUG_ASSERT(!has_allocation_result_);
    // allocation_result_status_ is initialized to ZX_OK, so should still be set
    // that way.
    ZX_DEBUG_ASSERT(allocation_result_status_ == ZX_OK);

    allocation_result_status_ = ZX_OK;
    allocation_result_info_ = std::move(info);
    has_allocation_result_ = true;
    SendAllocationResult();
    return;
}

void LogicalBufferCollection::SendAllocationResult() {
    ZX_DEBUG_ASSERT(has_allocation_result_);
    ZX_DEBUG_ASSERT(token_views_.empty());
    ZX_DEBUG_ASSERT(!collection_views_.empty());

    for (auto& [key, value] : collection_views_) {
        // May as well assert since we can.
        ZX_DEBUG_ASSERT(key->is_set_constraints_seen());
        key->OnBuffersAllocated();
    }

    if (allocation_result_status_ != ZX_OK) {
        Fail("LogicalBufferCollection::SendAllocationResult() done sending "
             "allocation failure - now auto-failing self.");
        return;
    }
}

void LogicalBufferCollection::BindSharedCollectionInternal(
    BufferCollectionToken* token, zx::channel buffer_collection_request) {
    auto self = token->parent_shared();
    ZX_DEBUG_ASSERT(self.get() == this);
    auto collection = BufferCollection::Create(self);
    collection->SetErrorHandler(
        [this, collection_ptr = collection.get()](zx_status_t status) {
            // status passed to an error handler is never ZX_OK.  Clean close is
            // ZX_ERR_PEER_CLOSED.
            ZX_DEBUG_ASSERT(status != ZX_OK);

            // We know collection_ptr is still alive because collection_ptr is
            // still in collection_views_.  We know this is still alive because
            // this has a RefPtr<> ref from collection_ptr.
            //
            // TODO(dustingreen): Switch to contains() when C++20.
            ZX_DEBUG_ASSERT(collection_views_.find(collection_ptr) !=
                            collection_views_.end());

            // The BufferCollection may have had Close() called on it, in which
            // case closure of the BufferCollection doesn't cause
            // LogicalBufferCollection failure.  Or, Close() wasn't called and
            // the LogicalBufferCollection is out of here.

            if (!(status == ZX_ERR_PEER_CLOSED && collection_ptr->is_done())) {
                // We don't have to explicitly remove collection from
                // collection_views_ because Fail() will
                // collection_views_.clear().
                //
                // A BufferCollection view whose error handler runs implies
                // LogicalBufferCollection failure.
                Fail("BufferCollection (view) failure (or closure without "
                     "Close()) causing "
                     "LogicalBufferCollection failure - status: %d",
                     status);
                return;
            }

            // At this point we know the collection_ptr is cleanly done (Close()
            // was sent from client) and can be removed from the set of tracked
            // collections.  We keep the collection's constraints (if any), as
            // those are still relevant - this lets a participant do
            // SetConstraints() followed by Close() followed by closing the
            // participant's BufferCollection channel, which is convenient for
            // some participants.

            if (collection_ptr->is_set_constraints_seen()) {
                constraints_list_.emplace_back(collection_ptr->TakeConstraints());
            }

            auto self = collection_ptr->parent_shared();
            ZX_DEBUG_ASSERT(self.get() == this);
            collection_views_.erase(collection_ptr);
            MaybeAllocate();
            return;
        });
    auto collection_ptr = collection.get();
    collection_views_.insert({collection_ptr, std::move(collection)});
    // ~BufferCollectionToken calls UntrackTokenKoid().
    token_views_.erase(token);
    collection_ptr->Bind(std::move(buffer_collection_request));
}

bool LogicalBufferCollection::CombineConstraints() {
    // This doesn't necessarily mean that any of the collection_views_ have
    // set non-null constraints though.  We do require that at least one
    // participant (probably the initiator) retains an open channel to its
    // BufferCollection until allocation is done, else allocation won't be
    // attempted.
    ZX_DEBUG_ASSERT(!collection_views_.empty());

    // We also know that all the constraints are in constraints_list_ now,
    // including all constraints from collection_views_.
    ZX_DEBUG_ASSERT(!constraints_list_.empty());

    auto iter =
        std::find_if(constraints_list_.begin(), constraints_list_.end(),
                     [](auto& item) { return !!item; });
    if (iter == constraints_list_.end()) {
        // This is a failure.  At least one participant must provide
        // constraints.
        return false;
    }

    if (!CheckSanitizeBufferCollectionConstraints(iter->get())) {
        return false;
    }

    Constraints result =
        BufferCollectionConstraintsClone(iter->get());
    ++iter;

    for (; iter != constraints_list_.end(); ++iter) {
        if (!iter->get()) {
            continue;
        }
        if (!CheckSanitizeBufferCollectionConstraints(iter->get())) {
            return false;
        }
        if (!AccumulateConstraintBufferCollection(result.get(),
                                                  iter->get())) {
            // This is a failure.  The space of permitted settings contains no
            // points.
            return false;
        }
    }

    if (!CheckSanitizeBufferCollectionConstraints(result.get())) {
      return false;
    }

    constraints_ = std::move(result);
    return true;
}

bool LogicalBufferCollection::CheckSanitizeBufferCollectionConstraints(
    fuchsia_sysmem_BufferCollectionConstraints* constraints) {
    FieldDefaultMax(&constraints->max_buffer_count);
    // At least one usage bit must be specified by any participant that
    // specifies constraints.
    if (constraints->usage.cpu == 0 && constraints->usage.vulkan == 0 &&
        constraints->usage.display == 0 && constraints->usage.video == 0) {
        LogError("At least one usage bit must be set.");
        return false;
    }
    for (uint32_t i = 0; i < constraints->image_format_constraints_count; ++i) {
        if (!CheckSanitizeImageFormatConstraints(
                &constraints->image_format_constraints[i])) {
            return false;
        }
    }
    return true;
}

bool LogicalBufferCollection::CheckSanitizeImageFormatConstraints(
    fuchsia_sysmem_ImageFormatConstraints* constraints) {
    if (constraints->pixel_format.type ==
        fuchsia_sysmem_PixelFormatType_INVALID) {
        LogError("PixelFormatType INVALID not allowed");
        return false;
    }
    if (!ImageFormatIsSupported(&constraints->pixel_format)) {
        LogError("Unsupported pixel format");
        return false;
    }

    if (!constraints->color_spaces_count) {
        LogError("color_spaces_count == 0 not allowed");
        return false;
    }
    if (constraints->layers != 1) {
        LogError("layers != 1 is not yet implemented");
        return false;
    }

    FieldDefault1(&constraints->coded_width_divisor);
    FieldDefault1(&constraints->coded_height_divisor);
    FieldDefault1(&constraints->bytes_per_row_divisor);
    FieldDefault1(&constraints->start_offset_divisor);
    FieldDefault1(&constraints->display_width_divisor);
    FieldDefault1(&constraints->display_height_divisor);

    if (!IsNonZeroPowerOf2(constraints->coded_width_divisor)) {
        LogError("non-power-of-2 coded_width_divisor not supported");
        return false;
    }
    if (!IsNonZeroPowerOf2(constraints->coded_height_divisor)) {
        LogError("non-power-of-2 coded_width_divisor not supported");
        return false;
    }
    if (!IsNonZeroPowerOf2(constraints->bytes_per_row_divisor)) {
        LogError("non-power-of-2 bytes_per_row_divisor not supported");
        return false;
    }
    if (!IsNonZeroPowerOf2(constraints->display_width_divisor)) {
        LogError("non-power-of-2 display_width_divisor not supported");
        return false;
    }
    if (!IsNonZeroPowerOf2(constraints->display_height_divisor)) {
        LogError("non-power-of-2 display_height_divisor not supported");
        return false;
    }

    for (uint32_t i = 0; i < constraints->color_spaces_count; ++i) {
        if (!ImageFormatIsSupportedColorSpaceForPixelFormat(
                constraints->color_space[i], constraints->pixel_format)) {
            LogError("!ImageFormatIsSupportedColorSpaceForPixelFormat() "
                     "color_space.type: %u "
                     "pixel_format.type: %u",
                     constraints->color_space[i].type,
                     constraints->pixel_format.type);
            return false;
        }
    }

    FieldDefaultMax(&constraints->required_min_coded_width);
    FieldDefaultZero(&constraints->required_max_coded_width);
    FieldDefaultMax(&constraints->required_min_coded_height);
    FieldDefaultZero(&constraints->required_max_coded_height);
    FieldDefaultMax(&constraints->required_min_bytes_per_row);
    FieldDefaultZero(&constraints->required_max_bytes_per_row);

    uint32_t min_bytes_per_row_given_min_width =
        ImageFormatStrideBytesPerWidthPixel(&constraints->pixel_format) *
                                            constraints->min_coded_width;
    constraints->min_bytes_per_row = std::max(
        constraints->min_bytes_per_row,
        min_bytes_per_row_given_min_width);

    // TODO(dustingreen): Check compatibility of color_space[] entries vs. the
    // pixel_format.  In particular, 2020 and 2100 don't have 8 bpp, only 10 or
    // 12 bpp, while a given PixelFormat.type is a specific bpp.  There's
    // probably no reason to allow 2020 or 2100 to be specified along with a
    // PixelFormat.type that's 8 bpp for example.

    return true;
}

LogicalBufferCollection::Constraints
LogicalBufferCollection::BufferCollectionConstraintsClone(
    const fuchsia_sysmem_BufferCollectionConstraints* input) {
    // There are no handles in BufferCollectionConstraints, so just copy the
    // payload.  If any handles are added later we'll have to fix this up.
    return Constraints(*input);
}

LogicalBufferCollection::ImageFormatConstraints
LogicalBufferCollection::ImageFormatConstraintsClone(
    const fuchsia_sysmem_ImageFormatConstraints* input) {
    // There are no handles in ImageFormatConstraints, so just copy the
    // payload.  If any handles are added later we'll have to fix this up.
    return ImageFormatConstraints(*input);
}

// |acc| accumulated constraints so far
//
// |c| additional constraint to aggregate into acc
bool LogicalBufferCollection::AccumulateConstraintBufferCollection(
    fuchsia_sysmem_BufferCollectionConstraints* acc,
    const fuchsia_sysmem_BufferCollectionConstraints* c) {
    acc->usage.cpu |= c->usage.cpu;
    acc->usage.vulkan |= c->usage.vulkan;
    acc->usage.display |= c->usage.display;
    acc->usage.video |= c->usage.video;

    acc->min_buffer_count_for_camping += c->min_buffer_count_for_camping;
    acc->min_buffer_count_for_dedicated_slack +=
        c->min_buffer_count_for_dedicated_slack;
    acc->min_buffer_count_for_shared_slack =
        std::max(acc->min_buffer_count_for_shared_slack,
                 c->min_buffer_count_for_shared_slack);

    // 0 is replaced with 0xFFFFFFFF in
    // CheckSanitizeBufferCollectionConstraints.
    ZX_DEBUG_ASSERT(acc->max_buffer_count != 0);
    ZX_DEBUG_ASSERT(c->max_buffer_count != 0);
    acc->max_buffer_count = std::min(
        acc->max_buffer_count, c->max_buffer_count);

    if (!acc->has_buffer_memory_constraints) {
        if (c->has_buffer_memory_constraints) {
            // struct copy
            acc->buffer_memory_constraints = c->buffer_memory_constraints;
            acc->has_buffer_memory_constraints = true;
        }
    } else {
        ZX_DEBUG_ASSERT(acc->has_buffer_memory_constraints);
        if (c->has_buffer_memory_constraints) {
            if (!AccumulateConstraintBufferMemory(
                    &acc->buffer_memory_constraints,
                    &c->buffer_memory_constraints)) {
                return false;
            }
        }
    }

    // Reject secure_required in combination with any CPU usage, since CPU usage
    // isn't possible given secure memory.
    if (acc->has_buffer_memory_constraints &&
        acc->buffer_memory_constraints.secure_required &&
        IsCpuUsage(acc->usage)) {
        return false;
    }

    if (acc->has_buffer_memory_constraints &&
        !acc->buffer_memory_constraints.ram_domain_supported &&
        !acc->buffer_memory_constraints.cpu_domain_supported) {
        LogError("Neither RAM nor CPU coherency domains supported");
        return false;
    }

    if (!acc->image_format_constraints_count) {
        for (uint32_t i = 0; i < c->image_format_constraints_count; ++i) {
            // struct copy
            acc->image_format_constraints[i] = c->image_format_constraints[i];
        }
        acc->image_format_constraints_count = c->image_format_constraints_count;
    } else {
        ZX_DEBUG_ASSERT(acc->image_format_constraints_count);
        if (c->image_format_constraints_count) {
            if (!AccumulateConstraintImageFormats(
                    &acc->image_format_constraints_count,
                    acc->image_format_constraints,
                    c->image_format_constraints_count,
                    c->image_format_constraints)) {
                // We return false if we've seen non-zero
                // image_format_constraint_count from at least one participant
                // but among non-zero image_format_constraint_count participants
                // since then the overlap has dropped to empty set.
                //
                // This path is taken when there are completely non-overlapping
                // PixelFormats and also when PixelFormat(s) overlap but none
                // of those have any non-empty settings space remaining.  In
                // that case we've removed the PixelFormat from consideration
                // despite it being common among participants (so far).
                return false;
            }
            ZX_DEBUG_ASSERT(acc->image_format_constraints_count);
        }
    }

    // acc->image_format_constraints_count == 0 is allowed here, when all
    // participants had image_format_constraints_count == 0.
    return true;
}

bool LogicalBufferCollection::AccumulateConstraintBufferMemory(
    fuchsia_sysmem_BufferMemoryConstraints* acc,
    const fuchsia_sysmem_BufferMemoryConstraints* c) {
    acc->min_size_bytes = std::max(acc->min_size_bytes, c->min_size_bytes);
    // Don't permit 0 as the overall min_size_bytes; that would be nonsense.  No
    // particular initiator should feel that it has to specify 1 in this field;
    // that's just built into sysmem instead.  While a VMO will have a minimum
    // actual size of page size, we do permit treating buffers as if they're 1
    // byte, mainly for testing reasons, and to avoid any unnecessary dependence
    // or assumptions re. page size.
    acc->min_size_bytes = std::max(acc->min_size_bytes, 1u);
    acc->max_size_bytes = std::min(acc->max_size_bytes, c->max_size_bytes);
    if (acc->min_size_bytes > acc->max_size_bytes) {
        LogError("min_size_bytes > max_size_bytes");
        return false;
    }

    acc->physically_contiguous_required = acc->physically_contiguous_required ||
                                          c->physically_contiguous_required;

    acc->secure_required = acc->secure_required || c->secure_required;
    acc->secure_permitted = acc->secure_permitted && c->secure_permitted;
    if (acc->secure_required && !acc->secure_permitted) {
        LogError("secure_required && !secure_permitted");
        return false;
    }
    acc->ram_domain_supported = acc->ram_domain_supported && c->ram_domain_supported;
    acc->cpu_domain_supported = acc->cpu_domain_supported && c->cpu_domain_supported;
    return true;
}

bool LogicalBufferCollection::AccumulateConstraintImageFormats(
    uint32_t* acc_count, fuchsia_sysmem_ImageFormatConstraints acc[],
    uint32_t c_count, const fuchsia_sysmem_ImageFormatConstraints c[]) {
    // Remove any pixel_format in acc that's not in c.  Process any format
    // that's in both.  If processing the format results in empty set for that
    // format, pretend as if the format wasn't in c and remove that format from
    // acc.  If acc ends up with zero formats, return false.

    // This method doesn't get called unless there's at least one format in
    // acc.
    ZX_DEBUG_ASSERT(*acc_count);

    for (uint32_t ai = 0; ai < *acc_count; ++ai) {
        uint32_t ci;
        for (ci = 0; ci < c_count; ++ci) {
            if (ImageFormatIsPixelFormatEqual(acc[ai].pixel_format,
                                              c[ci].pixel_format)) {
                if (!AccumulateConstraintImageFormat(&acc[ai], &c[ci])) {
                    // Pretend like the format wasn't in c to begin with, so
                    // this format gets removed from acc.  Only if this results
                    // in zero formats in acc do we end up returning false.
                    ci = c_count;
                    break;
                }
                // We found the format in c and processed the format without
                // that resulting in empty set; break so we can move on to the
                // next format.
                break;
            }
        }
        if (ci == c_count) {
            // remove from acc because not found in c
            --(*acc_count);
            // struct copy of formerly last item on top of the item being
            // removed
            acc[ai] = acc[*acc_count];
            // adjust ai to force current index to be processed again as it's
            // now a different item
            --ai;
        }
    }

    if (!*acc_count) {
        LogError("all pixel_format(s) eliminated");
        return false;
    }

    return true;
}

bool LogicalBufferCollection::AccumulateConstraintImageFormat(
    fuchsia_sysmem_ImageFormatConstraints* acc,
    const fuchsia_sysmem_ImageFormatConstraints* c) {
    ZX_DEBUG_ASSERT(
        ImageFormatIsPixelFormatEqual(acc->pixel_format, c->pixel_format));
    // Checked previously.
    ZX_DEBUG_ASSERT(acc->color_spaces_count);
    // Checked previously.
    ZX_DEBUG_ASSERT(c->color_spaces_count);

    if (!AccumulateConstraintColorSpaces(
            &acc->color_spaces_count, acc->color_space, c->color_spaces_count,
            c->color_space)) {
        return false;
    }
    // Else AccumulateConstraintColorSpaces() would have returned false.
    ZX_DEBUG_ASSERT(acc->color_spaces_count);

    acc->min_coded_width = std::max(acc->min_coded_width, c->min_coded_width);
    acc->max_coded_width = std::min(acc->max_coded_width, c->max_coded_width);
    if (acc->min_coded_width > acc->max_coded_width) {
        LogError("min_coded_width > max_coded_width");
        return false;
    }

    acc->min_coded_height =
        std::max(acc->min_coded_height, c->min_coded_height);
    acc->max_coded_height =
        std::min(acc->max_coded_height, c->max_coded_height);
    if (acc->min_coded_height > acc->max_coded_height) {
        LogError("min_coded_height > max_coded_height");
        return false;
    }

    acc->min_bytes_per_row =
        std::max(acc->min_bytes_per_row, c->min_bytes_per_row);
    acc->max_bytes_per_row =
        std::min(acc->max_bytes_per_row, c->max_bytes_per_row);
    if (acc->min_bytes_per_row > acc->max_bytes_per_row) {
        LogError("min_bytes_per_row > max_bytes_per_row");
        return false;
    }

    acc->max_coded_width_times_coded_height =
        std::min(acc->max_coded_width_times_coded_height,
                 c->max_coded_width_times_coded_height);
    if (acc->min_coded_width * acc->min_coded_height >
        acc->max_coded_width_times_coded_height) {
        LogError("min_coded_width * min_coded_height > "
                 "max_coded_width_times_coded_height");
        return false;
    }

    // Checked previously.
    ZX_DEBUG_ASSERT(acc->layers == 1);
    if (acc->layers != 1) {
        LogError("layers != 1 is not yet implemented");
        return false;
    }

    acc->coded_width_divisor =
        std::max(acc->coded_width_divisor, c->coded_width_divisor);
    acc->coded_width_divisor =
        std::max(acc->coded_width_divisor,
                 ImageFormatCodedWidthMinDivisor(&acc->pixel_format));

    acc->coded_height_divisor =
        std::max(acc->coded_height_divisor, c->coded_height_divisor);
    acc->coded_height_divisor =
        std::max(acc->coded_height_divisor,
                 ImageFormatCodedHeightMinDivisor(&acc->pixel_format));

    acc->bytes_per_row_divisor =
        std::max(acc->bytes_per_row_divisor, c->bytes_per_row_divisor);
    acc->bytes_per_row_divisor =
        std::max(acc->bytes_per_row_divisor,
                 ImageFormatSampleAlignment(&acc->pixel_format));

    acc->start_offset_divisor =
        std::max(acc->start_offset_divisor, c->start_offset_divisor);
    acc->start_offset_divisor =
        std::max(acc->start_offset_divisor,
                 ImageFormatSampleAlignment(&acc->pixel_format));
    if (acc->start_offset_divisor > PAGE_SIZE) {
        LogError(
            "support for start_offset_divisor > PAGE_SIZE not yet implemented");
        return false;
    }

    acc->display_width_divisor =
        std::max(acc->display_width_divisor, c->display_width_divisor);
    acc->display_height_divisor =
        std::max(acc->display_height_divisor, c->display_height_divisor);

    // The required_ space is accumulated by taking the union, and must be fully
    // within the non-required_ space, else fail.  For example, this allows a
    // video decoder to indicate that it's capable of outputting a wide range of
    // output dimensions, but that it has specific current dimensions that are
    // presently required_ (min == max) for decode to proceed.
    ZX_DEBUG_ASSERT(acc->required_min_coded_width != 0);
    ZX_DEBUG_ASSERT(c->required_min_coded_width != 0);
    acc->required_min_coded_width = std::min(acc->required_min_coded_width, c->required_min_coded_width);
    if (acc->required_min_coded_width < acc->min_coded_width) {
        LogError("required_min_coded_width < min_coded_width");
        return false;
    }
    acc->required_max_coded_width = std::max(acc->required_max_coded_width, c->required_max_coded_width);
    if (acc->required_max_coded_width > acc->max_coded_width) {
        LogError("required_max_coded_width > max_coded_width");
        return false;
    }
    ZX_DEBUG_ASSERT(acc->required_min_coded_height != 0);
    ZX_DEBUG_ASSERT(c->required_min_coded_height != 0);
    acc->required_min_coded_height = std::min(acc->required_min_coded_height, c->required_min_coded_height);
    if (acc->required_min_coded_height < acc->min_coded_height) {
        LogError("required_min_coded_height < min_coded_height");
        return false;
    }
    acc->required_max_coded_height = std::max(acc->required_max_coded_height, c->required_max_coded_height);
    if (acc->required_max_coded_height > acc->max_coded_height) {
        LogError("required_max_coded_height > max_coded_height");
        return false;
    }
    ZX_DEBUG_ASSERT(acc->required_min_bytes_per_row != 0);
    ZX_DEBUG_ASSERT(c->required_min_bytes_per_row != 0);
    acc->required_min_bytes_per_row = std::min(acc->required_min_bytes_per_row, c->required_min_bytes_per_row);
    if (acc->required_min_bytes_per_row < acc->min_bytes_per_row) {
        LogError("required_min_bytes_per_row < min_bytes_per_row");
        return false;
    }
    acc->required_max_bytes_per_row = std::max(acc->required_max_bytes_per_row, c->required_max_bytes_per_row);
    if (acc->required_max_bytes_per_row > acc->max_bytes_per_row) {
        LogError("required_max_bytes_per_row > max_bytes_per_row");
        return false;
    }

    return true;
}

bool LogicalBufferCollection::AccumulateConstraintColorSpaces(
    uint32_t* acc_count, fuchsia_sysmem_ColorSpace acc[], uint32_t c_count,
    const fuchsia_sysmem_ColorSpace c[]) {
    // Remove any color_space in acc that's not in c.  If zero color spaces
    // remain in acc, return false.

    for (uint32_t ai = 0; ai < *acc_count; ++ai) {
        uint32_t ci;
        for (ci = 0; ci < c_count; ++ci) {
            if (IsColorSpaceEqual(acc[ai], c[ci])) {
                // We found the color space in c.  Break so we can move on to
                // the next color space.
                break;
            }
        }
        if (ci == c_count) {
            // remove from acc because not found in c
            --(*acc_count);
            // struct copy of formerly last item on top of the item being
            // removed
            acc[ai] = acc[*acc_count];
            // adjust ai to force current index to be processed again as it's
            // now a different item
            --ai;
        }
    }

    if (!*acc_count) {
        LogError("Zero color_space overlap");
        return false;
    }

    return true;
}

bool LogicalBufferCollection::IsColorSpaceEqual(
    const fuchsia_sysmem_ColorSpace& a, const fuchsia_sysmem_ColorSpace& b) {
    return a.type == b.type;
}

static fuchsia_sysmem_CoherencyDomain
GetCoherencyDomain(const fuchsia_sysmem_BufferCollectionConstraints* constraints) {
    if (!constraints->has_buffer_memory_constraints)
        return fuchsia_sysmem_CoherencyDomain_Cpu;

    if (!constraints->buffer_memory_constraints.ram_domain_supported)
        return fuchsia_sysmem_CoherencyDomain_Cpu;
    if (!constraints->buffer_memory_constraints.cpu_domain_supported)
        return fuchsia_sysmem_CoherencyDomain_Ram;

    // Display controllers generally aren't cache coherent.
    // TODO - base on the system in use.
    return constraints->usage.display != 0 ? fuchsia_sysmem_CoherencyDomain_Ram
                                           : fuchsia_sysmem_CoherencyDomain_Cpu;
}

BufferCollection::BufferCollectionInfo
LogicalBufferCollection::Allocate(zx_status_t* allocation_result) {
    ZX_DEBUG_ASSERT(constraints_);
    ZX_DEBUG_ASSERT(allocation_result);

    // Unless fails later.
    *allocation_result = ZX_OK;

    BufferCollection::BufferCollectionInfo result(
        BufferCollection::BufferCollectionInfo::Default);

    uint32_t min_buffer_count =
        constraints_->min_buffer_count_for_camping +
        constraints_->min_buffer_count_for_dedicated_slack +
        constraints_->min_buffer_count_for_shared_slack;
    uint32_t max_buffer_count = constraints_->max_buffer_count;
    if (min_buffer_count > max_buffer_count) {
      LogError("aggregate min_buffer_count > aggregate max_buffer_count - "
               "min: %u max: %u", min_buffer_count, max_buffer_count);
      *allocation_result = ZX_ERR_NOT_SUPPORTED;
      return BufferCollection::BufferCollectionInfo(
          BufferCollection::BufferCollectionInfo::Null);
    }
    result->buffer_count = min_buffer_count;
    ZX_DEBUG_ASSERT(result->buffer_count <= max_buffer_count);

    uint64_t min_size_bytes = 0;
    uint64_t max_size_bytes = std::numeric_limits<uint64_t>::max();

    fuchsia_sysmem_SingleBufferSettings* settings = &result->settings;
    fuchsia_sysmem_BufferMemorySettings* buffer_settings =
        &settings->buffer_settings;

    // It's allowed for zero participants to have buffer_memory_constraints, as
    // long as at least one participant has image_format_constraint_count != 0.
    if (!constraints_->has_buffer_memory_constraints &&
        !constraints_->image_format_constraints_count) {
        // Too unconstrained...  We refuse to allocate buffers without any size
        // bounds from any participant.  At least one particpant must provide
        // some form of size bounds (in terms of buffer size bounds or in terms
        // of image size bounds).
        LogError("at least one participant must specify "
                 "buffer_memory_constraints or "
                 "image_format_constraints");
        *allocation_result = ZX_ERR_NOT_SUPPORTED;
        return BufferCollection::BufferCollectionInfo(
            BufferCollection::BufferCollectionInfo::Null);
    }
    if (constraints_->has_buffer_memory_constraints) {
        const fuchsia_sysmem_BufferMemoryConstraints* buffer_constraints =
            &constraints_->buffer_memory_constraints;
        buffer_settings->is_physically_contiguous =
            buffer_constraints->physically_contiguous_required;
        // checked previously
        ZX_DEBUG_ASSERT(!(buffer_constraints->secure_required &&
                          !buffer_constraints->secure_permitted));
        // checked previously
        ZX_DEBUG_ASSERT(!(buffer_constraints->secure_required &&
                          IsCpuUsage(constraints_->usage)));
        buffer_settings->is_secure = buffer_constraints->secure_required;
        // We can't fill out buffer_settings yet because that also depends on
        // ImageFormatConstraints.  We do need the min and max from here though.
        min_size_bytes = buffer_constraints->min_size_bytes;
        max_size_bytes = buffer_constraints->max_size_bytes;
    }
    buffer_settings->coherency_domain = GetCoherencyDomain(constraints_.get());

    // It's allowed for zero participants to have any ImageFormatConstraint(s),
    // in which case the combined constraints_ will have zero (and that's fine,
    // when allocating raw buffers that don't need any ImageFormatConstraint).
    //
    // At least for now, we pick which PixelFormat to use before determining if
    // the constraints associated with that PixelFormat imply a buffer size
    // range in min_size_bytes..max_size_bytes.
    if (constraints_->image_format_constraints_count) {
        // Pick the best ImageFormatConstraints.
        uint32_t best_index = 0;
        for (uint32_t i = 1; i < constraints_->image_format_constraints_count;
             ++i) {
            if (CompareImageFormatConstraintsByIndex(i, best_index) < 0) {
                best_index = i;
            }
        }
        // struct copy - if right hand side's clone results in any duplicated
        // handles, those will be owned by result.
        settings->image_format_constraints =
            *ImageFormatConstraintsClone(
                 &constraints_->image_format_constraints[best_index])
                 .get();
        settings->has_image_format_constraints = true;
    }

    // Compute the min buffer size implied by image_format_constraints, so we
    // ensure the buffers can hold the min-size image.
    if (settings->has_image_format_constraints) {
        const fuchsia_sysmem_ImageFormatConstraints* constraints =
            &settings->image_format_constraints;
        fuchsia_sysmem_ImageFormat_2 min_image{};

        // struct copy
        min_image.pixel_format = constraints->pixel_format;

        min_image.coded_width =
            AlignUp(constraints->min_coded_width,
                    constraints->coded_width_divisor);
        if (min_image.coded_width > constraints->max_coded_width) {
            LogError(
                "coded_width_divisor caused coded_width > max_coded_width");
            *allocation_result = ZX_ERR_NOT_SUPPORTED;
            return BufferCollection::BufferCollectionInfo(
                BufferCollection::BufferCollectionInfo::Null);
        }
        min_image.coded_height =
            AlignUp(constraints->min_coded_height,
                    constraints->coded_height_divisor);
        if (min_image.coded_height > constraints->max_coded_height) {
            LogError(
                "coded_height_divisor caused coded_height > max_coded_height");
            *allocation_result = ZX_ERR_NOT_SUPPORTED;
            return BufferCollection::BufferCollectionInfo(
                BufferCollection::BufferCollectionInfo::Null);
        }
        min_image.bytes_per_row =
            AlignUp(constraints->min_bytes_per_row,
                    constraints->bytes_per_row_divisor);
        if (min_image.bytes_per_row > constraints->max_bytes_per_row) {
            LogError("bytes_per_row_divisor caused bytes_per_row > "
                     "max_bytes_per_row");
            *allocation_result = ZX_ERR_NOT_SUPPORTED;
            return BufferCollection::BufferCollectionInfo(
                BufferCollection::BufferCollectionInfo::Null);
        }

        if (min_image.coded_width * min_image.coded_height >
            constraints->max_coded_width_times_coded_height) {
            LogError("coded_width * coded_height > "
                     "max_coded_width_times_coded_height");
            *allocation_result = ZX_ERR_NOT_SUPPORTED;
            return BufferCollection::BufferCollectionInfo(
                BufferCollection::BufferCollectionInfo::Null);
        }

        // These don't matter for computing size in bytes.
        ZX_DEBUG_ASSERT(min_image.display_width == 0);
        ZX_DEBUG_ASSERT(min_image.display_height == 0);

        // This is the only supported value for layers for now.
        min_image.layers = 1;

        // Checked previously.
        ZX_DEBUG_ASSERT(constraints->color_spaces_count >= 1);
        // This doesn't matter for computing size in bytes, as we trust the
        // pixel_format to fully specify the image size.  But set it to the
        // first ColorSpace anyway, just so the color_space.type is a valid
        // value.
        //
        // struct copy
        min_image.color_space = constraints->color_space[0];

        uint64_t image_min_size_bytes = ImageFormatImageSize(&min_image);

        if (image_min_size_bytes > min_size_bytes) {
            if (image_min_size_bytes > max_size_bytes) {
                LogError("image_min_size_bytes > max_size_bytes");
                *allocation_result = ZX_ERR_NOT_SUPPORTED;
                return BufferCollection::BufferCollectionInfo(
                    BufferCollection::BufferCollectionInfo::Null);
            }
            min_size_bytes = image_min_size_bytes;
            ZX_DEBUG_ASSERT(min_size_bytes <= max_size_bytes);
        }
    }

    if (min_size_bytes == 0) {
        LogError("min_size_bytes == 0");
        *allocation_result = ZX_ERR_NOT_SUPPORTED;
        return BufferCollection::BufferCollectionInfo(
            BufferCollection::BufferCollectionInfo::Null);
    }

    // For purposes of enforcing max_size_bytes, we intentionally don't care
    // that a VMO can only be a multiple of page size.

    uint64_t total_size_bytes = min_size_bytes * result->buffer_count;
    if (total_size_bytes > kMaxTotalSizeBytesPerCollection) {
        LogError("total_size_bytes > kMaxTotalSizeBytesPerCollection");
        *allocation_result = ZX_ERR_NO_MEMORY;
        return BufferCollection::BufferCollectionInfo(
            BufferCollection::BufferCollectionInfo::Null);
    }

    if (min_size_bytes > kMaxSizeBytesPerBuffer) {
        LogError("min_size_bytes > kMaxSizeBytesPerBuffer");
        *allocation_result = ZX_ERR_NO_MEMORY;
        return BufferCollection::BufferCollectionInfo(
            BufferCollection::BufferCollectionInfo::Null);
    }
    ZX_DEBUG_ASSERT(min_size_bytes <= std::numeric_limits<uint32_t>::max());

    // Now that min_size_bytes accounts for any ImageFormatConstraints, we can
    // just allocate min_size_bytes buffers.
    //
    // If an initiator (or a participant) wants to force buffers to be larger
    // than the size implied by minimum image dimensions, the initiator can use
    // BufferMemorySettings.min_size_bytes to force allocated buffers to be
    // large enough.
    buffer_settings->size_bytes = static_cast<uint32_t>(min_size_bytes);

    for (uint32_t i = 0; i < result->buffer_count; ++i) {
        // Assign directly into result to benefit from FidlStruct<> management
        // of handle lifetime.
        zx::vmo vmo;
        zx_status_t allocate_result = AllocateVmo(settings, &vmo);
        if (allocate_result != ZX_OK) {
            ZX_DEBUG_ASSERT(allocate_result == ZX_ERR_NO_MEMORY);
            LogError("AllocateVmo() failed - status: %d", allocate_result);
            // In release sanitize error code to ZX_ERR_NO_MEMORY regardless of
            // what AllocateVmo() returned.
            *allocation_result = ZX_ERR_NO_MEMORY;
            return BufferCollection::BufferCollectionInfo(
                BufferCollection::BufferCollectionInfo::Null);
        }
        // Transfer ownership from zx::vmo to FidlStruct<>.
        result->buffers[i].vmo = vmo.release();
    }

    ZX_DEBUG_ASSERT(*allocation_result == ZX_OK);
    return result;
}

zx_status_t LogicalBufferCollection::AllocateVmo(
    const fuchsia_sysmem_SingleBufferSettings* settings, zx::vmo* vmo) {
    if (settings->buffer_settings.is_secure) {
        ProtectedMemoryAllocator* allocator = parent_device_->protected_allocator();
        if (!allocator) {
            LogError("No protected memory allocator");
            return ZX_ERR_NOT_SUPPORTED;
        }

        zx::vmo raw_vmo;
        zx_status_t status = allocator->Allocate(settings->buffer_settings.size_bytes, &raw_vmo);
        if (status != ZX_OK) {
            LogError("Protected allocate failed - size_bytes: %u "
                     "status: %d",
                     settings->buffer_settings.size_bytes, status);
            // sanitize to ZX_ERR_NO_MEMORY regardless of why.
            status = ZX_ERR_NO_MEMORY;
            return status;
        }
        status = raw_vmo.duplicate(kSysmemVmoRights, vmo);
        if (status != ZX_OK) {
            LogError("zx::object::duplicate() failed - status: %d", status);
            return status;
        }
    } else if (settings->buffer_settings.is_physically_contiguous) {
        // TODO(dustingreen): Optionally (per board) pre-allocate a
        // physically-contiguous VMO with board-specific size, have a page heap,
        // dole out portions of that VMO or non-copy-on-write child VMOs of that
        // VMO.  For now, we just attempt to allocate contiguous when buffers
        // are allocated, which is unlikely to work after the system has been
        // running for a while and physical memory is more fragmented than early
        // during boot.
        zx::vmo raw_vmo;
        zx_status_t status = zx::vmo::create_contiguous(
            parent_device_->bti(), settings->buffer_settings.size_bytes, 0,
            &raw_vmo);
        if (status != ZX_OK) {
            LogError("zx::vmo::create_contiguous() failed - size_bytes: %u "
                     "status: %d",
                     settings->buffer_settings.size_bytes, status);
            // sanitize to ZX_ERR_NO_MEMORY regardless of why.
            status = ZX_ERR_NO_MEMORY;
            return status;
        }
        status = raw_vmo.duplicate(kSysmemVmoRights, vmo);
        if (status != ZX_OK) {
            LogError("zx::object::duplicate() failed - status: %d", status);
            return status;
        }
        // ~raw_vmo - *vmo is a duplicate with slightly-reduced rights.
    } else {
        zx::vmo raw_vmo;
        zx_status_t status =
            zx::vmo::create(settings->buffer_settings.size_bytes, 0, &raw_vmo);
        if (status != ZX_OK) {
            LogError("zx::vmo::create() failed - size_bytes: %u status: %d",
                     settings->buffer_settings.size_bytes, status);
            // sanitize to ZX_ERR_NO_MEMORY regardless of why.
            status = ZX_ERR_NO_MEMORY;
            return status;
        }
        status = raw_vmo.duplicate(kSysmemVmoRights, vmo);
        if (status != ZX_OK) {
            LogError("zx::object::duplicate() failed - status: %d", status);
            return status;
        }
        // ~raw_vmo - *vmo is a duplicate with slightly-reduced rights.
    }
    return ZX_OK;
}

static int32_t clamp_difference(int32_t a, int32_t b) {
    int32_t raw_result = a - b;

    int32_t cooked_result = raw_result;
    if (cooked_result > 0) {
        cooked_result = 1;
    } else if (cooked_result < 0) {
        cooked_result = -1;
    }
    ZX_DEBUG_ASSERT(cooked_result == 0 || cooked_result == 1 || cooked_result == -1);
    return cooked_result;
}

// 1 means a > b, 0 means ==, -1 means a < b.
//
// TODO(dustingreen): Pay attention to constraints_->usage, by checking any
// overrides that prefer particular PixelFormat based on a usage / usage
// combination.
int32_t LogicalBufferCollection::CompareImageFormatConstraintsTieBreaker(
    const fuchsia_sysmem_ImageFormatConstraints* a,
    const fuchsia_sysmem_ImageFormatConstraints* b) {
    // If there's not any cost difference, fall back to choosing the
    // pixel_format that has the larger type enum value as a tie-breaker.

    int32_t result = clamp_difference(static_cast<int32_t>(a->pixel_format.type),
                                      static_cast<int32_t>(b->pixel_format.type));

    if (result != 0)
        return result;

    result = clamp_difference(static_cast<int32_t>(a->pixel_format.has_format_modifier),
                              static_cast<int32_t>(b->pixel_format.has_format_modifier));

    if (result != 0)
        return result;

    if (a->pixel_format.has_format_modifier && b->pixel_format.has_format_modifier) {
        result = clamp_difference(static_cast<int32_t>(a->pixel_format.format_modifier.value),
                                  static_cast<int32_t>(b->pixel_format.format_modifier.value));
    }

    return result;
}

int32_t LogicalBufferCollection::CompareImageFormatConstraintsByIndex(
    uint32_t index_a, uint32_t index_b) {
    // This method is allowed to look at constraints_.
    ZX_DEBUG_ASSERT(constraints_);

    int32_t cost_compare =
        UsagePixelFormatCost::Compare(parent_device_->pdev_device_info_vid(),
                                      parent_device_->pdev_device_info_pid(),
                                      constraints_.get(), index_a, index_b);
    if (cost_compare != 0) {
        return cost_compare;
    }

    // If we get this far, there's no known reason to choose one PixelFormat
    // over another, so just pick one based on a tie-breaker that'll distinguish
    // between PixelFormat(s).

    int32_t tie_breaker_compare = CompareImageFormatConstraintsTieBreaker(
        &constraints_->image_format_constraints[index_a],
        &constraints_->image_format_constraints[index_b]);
    return tie_breaker_compare;
}
