blob: cc629f26e4faff1d2db1b3f13e4e5fe3950e913b [file] [log] [blame]
// Copyright 2022 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_EMBEDDER_SOFTWARE_SURFACE_PRODUCER_H_
#define SRC_EMBEDDER_SOFTWARE_SURFACE_PRODUCER_H_
#include <fuchsia/sysmem/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <lib/ui/scenic/cpp/resources.h>
#include <lib/ui/scenic/cpp/session.h>
#include <unordered_map>
#include "src/embedder/software_surface.h"
namespace embedder {
/// Factory for `SoftwareSurface`s that can recycle surfaces
/// and maintains older surfaces.
class SoftwareSurfaceProducer final {
public:
// Only keep 12 surfaces at a time.
static constexpr int kMaxSurfaces = 12;
// If a surface doesn't get used for 3 or more generations, we discard it.
static constexpr int kMaxSurfaceAge = 3;
explicit SoftwareSurfaceProducer();
~SoftwareSurfaceProducer();
SoftwareSurfaceProducer(const SoftwareSurfaceProducer&) = delete;
SoftwareSurfaceProducer& operator=(const SoftwareSurfaceProducer&) = delete;
bool IsValid() const;
std::unique_ptr<SoftwareSurface> ProduceOffscreenSurface(const Size size);
std::unique_ptr<SoftwareSurface> ProduceSurface(const Size size);
void SubmitSurfaces(std::vector<std::unique_ptr<SoftwareSurface>> surfaces);
private:
std::unique_ptr<SoftwareSurface> CreateSurface(const Size size);
void SubmitSurface(std::unique_ptr<SoftwareSurface> surface);
void RecycleSurface(std::unique_ptr<SoftwareSurface> surface);
void RecyclePendingSurface(uintptr_t surface_key);
/// Increments the age of all surfaces, and removes any that are past
/// `kMaxSurfaceAge`.
void AgeAndCollectOldBuffers();
/// The allocator for memory in Flatland.
///
/// Required to allocate a surface for Flatland. See
/// notes in
/// https://fuchsia.dev/fuchsia-src/concepts/ui/scenic/flatland?hl=en#design.
fuchsia::ui::composition::AllocatorPtr flatland_allocator_;
/// Allocator for memory from sysmem.
///
/// Memory for graphics surfaces on Fuchsia must come from sysmem.
///
/// For more details on how sysmem works and how to interact with
/// sysmem, see
/// https://fuchsia.dev/fuchsia-src/development/graphics/sysmem/concepts/sysmem.
fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator_;
/// These surfaces are available for re-use.
std::vector<std::unique_ptr<SoftwareSurface>> available_surfaces_;
/// These surfaces have been written to, but Scenic is not finished reading
/// from them yet.
std::unordered_map<uintptr_t, std::unique_ptr<SoftwareSurface>> pending_surfaces_;
/// True if the `SoftwareSurfaceProducer` is in a valid state to produce
/// surfaces, false otherwise.
///
/// An invalid `SoftwareSurfaceProducer` is unrecoverable.
bool valid_ = false;
// TODO(akbiggs): Add tracing once we figure out how to use the embedder's
// tracing utilities.
};
} // namespace embedder
#endif // SRC_EMBEDDER_SOFTWARE_SURFACE_PRODUCER_H_