// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module viz.mojom;

import "gpu/ipc/common/context_result.mojom";
import "gpu/ipc/common/surface_handle.mojom";
import "mojo/public/mojom/base/time.mojom";
import "ui/display/mojom/display_constants.mojom";
import "ui/gfx/mojom/ca_layer_params.mojom";
import "ui/gfx/mojom/delegated_ink_point_renderer.mojom";
import "ui/gfx/mojom/display_color_spaces.mojom";
import "ui/gfx/mojom/overlay_transform.mojom";
import "ui/gfx/mojom/transform.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/latency/mojom/latency_info.mojom";
import "services/viz/privileged/mojom/compositing/begin_frame_observer.mojom";
import "services/viz/privileged/mojom/compositing/layered_window_updater.mojom";
import "services/viz/privileged/mojom/compositing/vsync_parameter_observer.mojom";

struct FrameRateVelocityPoint {
  float frame_per_second;
  float dp_per_second;
};

struct AdaptiveRefreshRateInfo {
  bool has_support;
  float suggested_high;
  array<FrameRateVelocityPoint> velocity_mapping;
  float device_scale_factor;
};

// The DisplayPrivate is used by privileged clients to talk to Display.
interface DisplayPrivate {
  SetDisplayVisible(bool visible);

  // Resizes the display.
  Resize(gfx.mojom.Size size);

  // Sets the matrix that will be used to transform the output color of the
  // display. This only works in GPU compositing.
  SetDisplayColorMatrix(gfx.mojom.Transform color_matrix);

  // Sets the color spaces that may be used for rendering. This only has an
  // effect when using GPU compositing.
  SetDisplayColorSpaces(gfx.mojom.DisplayColorSpaces display_color_spaces);
  SetOutputIsSecure(bool secure);

  // Sets CGDirectDisplayID for GPU begin frame source.
  [EnableIf=is_mac]
  SetVSyncDisplayID(int64 display_id);

  // Updates vsync parameters used to generate BeginFrames for this display.
  // This will do nothing if the display is using an external BeginFrame source.
  SetDisplayVSyncParameters(
    mojo_base.mojom.TimeTicks timebase,
    mojo_base.mojom.TimeDelta interval);

  // Attempts to immediately draw and swap a frame if possible. Note that this
  // is not a sync IPC, as all current uses are during tear down of the root
  // compositor frame sink and are immediately followed by a call to
  // FrameSinkManager::DestroyCompositorFrameSink which is an associated sync
  // IPC. If this function is needed in cases where ordering isn't guaranteed
  // by other means, it should be made sync.
  ForceImmediateDrawAndSwapIfPossible();

  // Updates the refresh rate of the associated Display.
  [EnableIf=is_android|is_mac]
  UpdateRefreshRate(float refresh_rate);

  // Updates adaptive refresh rate information of the associated Display.
  [EnableIf=is_android]
  SetAdaptiveRefreshRateInfo(AdaptiveRefreshRateInfo info);

  // Updates the list of refresh rates supported by the associated Display.
  [EnableIf=can_set_refresh_rate]
  SetSupportedRefreshRates(array<float> refresh_rates);

  // Notifies associated Display to not detach child surface controls during
  // destruction.
  [EnableIf=is_android]
  PreserveChildSurfaceControls();

  // Lets client control whether it wants `DidCompleteSwapWithSize` callbacks.
  [EnableIf=is_android]
  SetSwapCompletionCallbackEnabled(bool enable);

  // Adds an observer that gets notified about vsync parameter changes. See
  // VSyncParameterObserver for details.
  //
  // Note that only one observer can be added. Adding a new observer will
  // replace the old one, which is fine since only exo uses this. If you are
  // adding a new use case VSyncParameterListener needs to be extended to
  // support multiple observers.
  AddVSyncParameterObserver(
    pending_remote<VSyncParameterObserver> observer);

  // Bind an interface between browser process and viz for ink points to be
  // sent to viz and stored, to be used when drawing a delegated ink trail.
  SetDelegatedInkPointRenderer(
    pending_receiver<gfx.mojom.DelegatedInkPointRenderer> receiver);

  // Allow browser to observe begin frames without implementing the contract of
  // CompositorFrameSink and Client. Eg there is no need to respond by
  // submitting a frame. Note setting this to non-null requests begin frames,
  // not just observe begin frames requested by other observers. This only a
  // single observer at a time; calling this will replace any existing observer.
  SetStandaloneBeginFrameObserver(pending_remote<BeginFrameObserver> observer);

  // Sets the maximum vsync interval supported by the display for use with
  // variable refresh rates and/or virtual modes, if supported. Also sets
  // the current VRR state indicating whether it is enabled on the display.
  SetMaxVSyncAndVrr(
    mojo_base.mojom.TimeDelta? max_vsync_interval,
    display.mojom.VariableRefreshRateState vrr_state);
};

// DisplayClient allows privileged clients to receive events from the Display.
interface DisplayClient {
  // Called when new Core Animation Layer params are received.
  [EnableIf=is_apple]
  OnDisplayReceivedCALayerParams(gfx.mojom.CALayerParams ca_layer_params);

  // Creates a LayeredWindowUpdater implementation to draw into a layered
  // window.
  [EnableIf=is_win]
  CreateLayeredWindowUpdater(pending_receiver<LayeredWindowUpdater> receiver);

  // Sends the created child window to the browser process so that it can be
  // parented to the browser process window
  [EnableIf=is_win]
  AddChildWindowToBrowser(gpu.mojom.SurfaceHandle child_window);

  // Notifies that a swap has occurred and provides information about the pixel
  // size of the swapped frame.
  [EnableIf=is_android]
  DidCompleteSwapWithSize(gfx.mojom.Size size);

  // Notifies that a swap has occurred with a new size.
  [EnableIf=linux_x11]
  DidCompleteSwapWithNewSize(gfx.mojom.Size size);

  // Notifies the client of the result of context creation attempt. On Android we can't
  // fall back to SW in failure cases, so we need to handle this specifically.
  [EnableIf=is_android]
  OnContextCreationResult(gpu.mojom.ContextResult result);

  // Notifies the AndroidWindow that wide color gamut is being enabled or
  // disabled.
  [EnableIf=is_android]
  SetWideColorEnabled(bool enabled);

  // Notifies that there is a new refresh rate preference.
  [EnableIf=can_set_refresh_rate]
  SetPreferredRefreshRate(float refresh_rate);
};
