// Copyright 2016 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 "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/shared_memory.mojom";
import "services/viz/public/mojom/compositing/begin_frame_args.mojom";
import "services/viz/public/mojom/compositing/compositor_frame.mojom";
import "services/viz/public/mojom/compositing/layer_context.mojom";
import "services/viz/public/mojom/compositing/local_surface_id.mojom";
import "services/viz/public/mojom/compositing/frame_timing_details.mojom";
import "services/viz/public/mojom/compositing/returned_resource.mojom";
import "services/viz/public/mojom/compositing/shared_bitmap_id.mojom";
import "services/viz/public/mojom/hit_test/hit_test_region_list.mojom";
// Tags the frame sink with the type of source producing its content.
enum CompositorFrameSinkType {
kUnspecified,
kVideo,
kMediaStream,
kLayerTree,
};
// A CompositorFrameSink is an interface for receiving CompositorFrame
// structs. A CompositorFrame contains the complete output meant for display.
// Each time a client has a graphical update, and receives an OnBeginFrame, it
// is responsible for creating a CompositorFrame to update its portion of the
// screen.
interface CompositorFrameSink {
// Lets the display compositor know that the client wishes to receive the next
// BeginFrame event.
SetNeedsBeginFrame(bool needs_begin_frame);
// Lets the display compositor know that the client also wants to receive
// BeginFrames with the animate_only flag set. Only clients that opt in
// will receive such BeginFrames.
SetWantsAnimateOnlyBeginFrames();
// Lets the display compositor know that the client wants merged OnBeginFrame,
// DidReceiveCompositorFrameAck, and ReclaimResources. Only supported when
// features::OnBeginFrameAcks is enabled. Only clients that opt in will
// receive such BeginFrames, others will still receive the signals separately.
SetWantsBeginFrameAcks();
// Lets the display compositor know that the client wants to use unsolicited
// compositor frame submission to indicate that it wants to receive subsequent
// BeginFrame events, as if SetNeedsBeginFrame(true) is called.
SetAutoNeedsBeginFrame();
// Submits a CompositorFrame to the display compositor that will be presented
// to screen the next time frames from all CompositorFrameSinks are aggregated
// to produce a display CompositorFrame. If a client wishes to allocate a new
// surface (e.g. during resize), then it can simply allocate a new
// |local_surface_id|. The local_id component of |local_surface_id| must be
// monontonically increasing for each change to LocalSurfaceId. Submit time is
// set to when this function is called to used for tracing how much time is
// spend between a CompositorFrame is sent and received. Once a
// |hit_test_region_list| is received, it will be reused until a new one is
// submitted.
// TODO(weiliangc): Submit time is recorded in microseconds right now and
// should be changed to use TimeTicks when Blink can send base types directly.
// For successful swaps, the implementation must call
// DidReceiveCompositorFrameAck() asynchronously when the frame has been
// processed in order to unthrottle the next frame.
//
// TODO(crbug.com/40154480): Investigate whether it's possible to alter the
// CompositorFrame structure to be less likely to exceed soft message size
// limits and remove [UnlimitedSize] here.
[EstimateSize, UnlimitedSize]
SubmitCompositorFrame(LocalSurfaceId local_surface_id,
CompositorFrame frame,
HitTestRegionList? hit_test_region_list,
uint64 submit_time);
// Same as above, submits a CompositorFrame to the display compositor. The
// implementation only returns when it's ready to receive another frame.
// We also return the list of resources that would be returned by
// DidReceiveCompositorFrameAck.
[Sync] SubmitCompositorFrameSync(LocalSurfaceId local_surface_id,
CompositorFrame frame,
HitTestRegionList? hit_test_region_list,
uint64 submit_time)
=> (array<ReturnedResource> resources);
// Notifies the frame sink that a BeginFrame was completed, but that no
// CompositorFrame was produced as a result of it.
DidNotProduceFrame(BeginFrameAck ack);
// Informs the display compositor that the client allocated a shared bitmap.
// The |id| can then be used in subsequent CompositorFrames given to
// SubmitCompositorFrame. The |id| is a SharedBitmapId.
DidAllocateSharedBitmap(mojo_base.mojom.ReadOnlySharedMemoryRegion region,
SharedBitmapId id);
// Informs the display compositor that the client deleted a shared bitmap. This
// allows the service to free the shared memory that was previously given to it
// via DidAllocateSharedBitmap(). The |id| is a SharedBitmapId.
DidDeleteSharedBitmap(SharedBitmapId id);
// This should be called atmost once for the lifetime of this frame sink. Once
// the value has been set to anything other than kUnspecified, subsequent calls
// are silently ignored.
InitializeCompositorFrameSinkType(CompositorFrameSinkType type);
// Binds to the LayerContext interface for this frame sink. Once this is bound
// the frame sink is permanently in LayerContext mode and the client should no
// longer submit frames through the CompositorFrameSink interface. Instead
// frames will automtaically be submitted by Viz based on the state of a
// GPU-side layer tree which can be manipulated through this LayerContext.
BindLayerContext(PendingLayerContext context);
// Informs the display compositor the IDs of the thread involved in frame
// production. This is used on Android PerformanceHint API to dynamically
// adjust performance to allow power saving.
[EnableIf=is_android]
SetThreadIds(array<int32> thread_ids);
};
interface CompositorFrameSinkClient {
// Notification that the previous CompositorFrame given to
// SubmitCompositorFrame() has been processed and that another frame
// can be submitted. This provides backpressure from the display compositor
// so that frames are submitted only at the rate it can handle them.
// TODO(fsamuel): This method ought not be necessary with unified BeginFrame.
// However, there's a fair amount of cleanup and refactoring necessary to get
// rid of it.
DidReceiveCompositorFrameAck(array<ReturnedResource> resources);
// Notification for the client to generate a CompositorFrame. The client is
// required to respond with either SubmitCompositorFrame() or
// DidNotProduceFrame(). If the client is unresponsive then begin frames will
// be throttled and eventually stopped entirely. We also return whether this
// OnBeginFrame is to act as DidReceiveCompositorFrameAck. We also return a
// list of resources, previously sent to SubmitCompositorFrame, to be reused
// or freed.
OnBeginFrame(BeginFrameArgs args,
map<uint32, FrameTimingDetails> details,
bool frame_ack,
array<ReturnedResource> resources);
// Inform the client that OnBeginFrame may not be called for some time.
OnBeginFramePausedChanged(bool paused);
// Returns resources sent to SubmitCompositorFrame to be reused or freed.
ReclaimResources(array<ReturnedResource> resources);
// Inform the client that a compositor frame transition directive was fully
// processed.
OnCompositorFrameTransitionDirectiveProcessed(uint32 sequence_id);
// Inform the client that a Surface has been evicted. Upon eviction a client
// should no longer submit to the given, or earlier, `local_surface_id`. This
// will be followed later by a call to ReclaimResources for the previously
// submitted CompositorFrame.
OnSurfaceEvicted(LocalSurfaceId local_surface_id);
};