blob: a7d72cc0e0c0297ea0f1c035d4432320f0d214d0 [file]
// Copyright 2025 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.
#ifndef SRC_UI_SCENIC_LIB_DISPLAY_INTERNAL_LAYER_H_
#define SRC_UI_SCENIC_LIB_DISPLAY_INTERNAL_LAYER_H_
#include "src/ui/scenic/lib/display/fidl_id_types.h"
#include "src/ui/scenic/lib/display/internal/layer_equivalence.h"
namespace display::internal {
// Manages the state of a single display layer within the `CoordinatorProxy`.
// This class maintains a "draft" state, representing pending changes, and an "applied" state,
// representing the configuration last known to be successfully applied on the display hardware via
// the FIDL `ApplyConfig()` method.
//
// The `Layer` also holds a `LayerEquivalence`, which is a projection of the layer's state used by
// `CoordinatorProxy` to determine `CheckConfig()` equivalency.
//
// Workflow:
// 1. Calls to `Set*()` methods update the `draft_equiv_` and other draft fields
// (e.g., `draft_image_`).
// 2. `CoordinatorProxy` calls `SendDiffsToCoordinator()`. This method compares the current
// `draft_equiv_` and `draft_image_` against the `applied_equiv_` and `applied_image_`. It
// sends the minimal set of FIDL commands to the `fuchsia.hardware.display.Coordinator` to make
// the coordinator's layer state match this `Layer`'s draft state.
// 3a. *After* a successful `CheckConfig()` and `ApplyConfig()` sequence in `CoordinatorProxy`, the
// proxy calls this `Layer`'s `AcceptDraftState()` method to promote the draft state to the
// applied state. Or:
// 3b. If `CheckConfig()` fails, `CoordinatorProxy` calls `ResetDraftState()` to
// revert the draft state back to the last known good applied state.
class Layer {
public:
// Values that are not directly held in a `LayerEquivalence`. For example, the specific alpha
// value is irrelevant from the POV of a `LayerEquivalence`, which only cares if the value is one,
// zero, or between the two.
struct ConfigValues {
float alpha_value = 1.f;
};
Layer() = default;
// Corresponds to `fuchsia.hardware.display.Coordinator/SetLayerPrimaryConfig()`.
// Modifies the layer's draft state; no FIDL methods are invoked.
//
// Note: calling this clears the image, as done by the coordinator impl.
void SetPrimaryConfig(const Extent2& image_dimensions, uint32_t image_tiling_type);
// Corresponds to `fuchsia.hardware.display.Coordinator/SetLayerPrimaryPosition()`.
// Modifies the layer's draft state; no FIDL methods are invoked.
void SetPrimaryPosition(const RotateFlip& transform, const Rectangle& src, const Rectangle& dst);
// Corresponds to `fuchsia.hardware.display.Coordinator/SetLayerPrimaryAlpha()`.
// Modifies the layer's draft state; no FIDL methods are invoked.
void SetPrimaryAlpha(const BlendMode& blend_mode, float alpha_value);
// Corresponds to `fuchsia.hardware.display.Coordinator/SetLayerPrimaryImage()`.
// Modifies the layer's draft state; no FIDL methods are invoked.
void SetLayerImage(const ImageId& image_id, const EventId& wait_event_id);
// Corresponds to `fuchsia.hardware.display.Coordinator/SetLayerColorConfig()`.
// Modifies the layer's draft state; no FIDL methods are invoked.
void SetColorConfig(const WireColor& color, const Rectangle& display_destination);
// If either the draft or applied state includes `image_id`, replace with `kInvalidImageId`.
void UnsetImage(const ImageId& image_id);
// Compute the diffs between the draft and applied states, and make only the necessary FIDL calls
// to make the Coordinator's draft state match this layer's draft state. Returns the number of
// FIDL API calls that were sent.
size_t SendDiffsToCoordinator(
const LayerId& layer_id,
fidl::WireSharedClient<fuchsia_hardware_display::Coordinator>& coordinator);
// Reset all draft state to be identical to the currently-applied state.
void ResetDraftState();
// Replace the accepted state with the draft state. Afterward, they are identical.
void AcceptDraftState();
const LayerEquivalence& draft_equiv() const { return draft_equiv_; }
private:
// Helper for `SendDiffsToCoordinator()`.
size_t SendImageLayerDiffsToCoordinator(
const LayerId& layer_id,
fidl::WireSharedClient<fuchsia_hardware_display::Coordinator>& coordinator);
// Helper for `SendDiffsToCoordinator()`.
size_t SendColorLayerDiffsToCoordinator(
const LayerId& layer_id,
fidl::WireSharedClient<fuchsia_hardware_display::Coordinator>& coordinator);
LayerEquivalence applied_equiv_;
ConfigValues applied_values_;
ImageId applied_image_ = kInvalidImageId;
EventId applied_wait_event_ = kInvalidEventId;
LayerEquivalence draft_equiv_;
ConfigValues draft_values_;
ImageId draft_image_ = kInvalidImageId;
EventId draft_wait_event_ = kInvalidEventId;
};
} // namespace display::internal
#endif // SRC_UI_SCENIC_LIB_DISPLAY_INTERNAL_LAYER_H_