// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMECAST_STARBOARD_MEDIA_MEDIA_STARBOARD_VIDEO_PLANE_H_
#define CHROMECAST_STARBOARD_MEDIA_MEDIA_STARBOARD_VIDEO_PLANE_H_
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "chromecast/public/graphics_types.h"
#include "chromecast/public/video_plane.h"
namespace chromecast {
namespace media {
// A VideoPlane that can be used to register callbacks that will be run when the
// plane's geometry changes. Must be created on a sequence.
//
// Public functions can be called from any sequence. Note that registered
// callbacks will be run from the sequence on which the StarboardVideoPlane was
// constructed. To run the callback on another sequence, use base::BindPostTask
// or similar logic.
class StarboardVideoPlane : public VideoPlane {
public:
using GeometryChangedCallback =
base::RepeatingCallback<void(const RectF& display_rect,
Transform transform)>;
StarboardVideoPlane();
// Disallow copy and assign.
StarboardVideoPlane(const StarboardVideoPlane&) = delete;
StarboardVideoPlane& operator=(const StarboardVideoPlane&) = delete;
~StarboardVideoPlane() override;
// Registers a callback that will be run when the geometry changes. Returns an
// opaque token that can be used to remove the callback later.
int64_t RegisterCallback(GeometryChangedCallback callback);
// Unregisters a callback from the list of callbacks that are run when the
// geometry changes. `token` should be the value returned from a previous
// RegisterCallback call. If no matching token is found, this is a no-op.
void UnregisterCallback(int64_t token);
// VideoPlane implementation:
void SetGeometry(const RectF& display_rect, Transform transform) override;
private:
// A helper function that must be run on task_runner_. Registers `callback`
// with the specified `token`.
void RegisterCallbackForToken(int64_t token,
GeometryChangedCallback callback);
base::flat_map<int64_t, GeometryChangedCallback> token_to_callback_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
base::Lock current_token_lock_;
// This must only be accessed while current_token_lock_ is held.
int64_t current_token_ = 0;
// This must be destructed first.
base::WeakPtrFactory<StarboardVideoPlane> weak_factory_{this};
};
} // namespace media
} // namespace chromecast
#endif // CHROMECAST_STARBOARD_MEDIA_MEDIA_STARBOARD_VIDEO_PLANE_H_