blob: 15a41abc837e7fa4de543c165f892b25d82e1681 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_VIZ_SERVICE_TRANSITIONS_TRANSFERABLE_RESOURCE_TRACKER_H_
#define COMPONENTS_VIZ_SERVICE_TRANSITIONS_TRANSFERABLE_RESOURCE_TRACKER_H_
#include <map>
#include <memory>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "components/viz/common/resources/release_callback.h"
#include "components/viz/common/resources/resource_id.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "components/viz/service/display/shared_bitmap_manager.h"
#include "components/viz/service/surfaces/surface_saved_frame.h"
#include "components/viz/service/viz_service_export.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/geometry/size.h"
namespace viz {
// This class is a simple transferable resource generator and lifetime tracker.
// Note that TransferableResourceTracker uses reserved range ResourceIds.
class VIZ_SERVICE_EXPORT TransferableResourceTracker {
public:
// This represents a resource that is positioned somewhere on screen.
struct VIZ_SERVICE_EXPORT PositionedResource {
TransferableResource resource;
SurfaceSavedFrame::RenderPassDrawData draw_data;
};
// A SurfaceSavedFrame can be converted to a ResourceFrame via
// ImportResources.
struct VIZ_SERVICE_EXPORT ResourceFrame {
ResourceFrame();
ResourceFrame(ResourceFrame&& other);
~ResourceFrame();
ResourceFrame& operator=(ResourceFrame&& other);
// The cached resource for the root content.
PositionedResource root;
// The cached resource for each shared element. The entries here are
// optional since copy request for an element may fail or a
// [src_element, dst_element] has a null src_element.
std::vector<absl::optional<PositionedResource>> shared;
// A map from renderer generated ViewTransitionElementResourceId to the
// corresponding cached resource. The resources are the same as |shared|
// above.
base::flat_map<ViewTransitionElementResourceId, TransferableResource>
element_id_to_resource;
};
explicit TransferableResourceTracker(
SharedBitmapManager* shared_bitmap_manager);
TransferableResourceTracker(const TransferableResourceTracker&) = delete;
~TransferableResourceTracker();
TransferableResourceTracker& operator=(const TransferableResourceTracker&) =
delete;
// This call converts a SurfaceSavedFrame into a ResourceFrame by converting
// each of the resources into a TransferableResource. Note that `this` keeps
// a ref on each of the TransferableResources returned in the ResourceFrame.
// The ref count can be managed by calls to RefResource and UnrefResource
// below. Note that a convenience function, `ReturnFrame`, is also provided
// below which will unref every resource in a given ResourceFrame. Using the
// convenience function is not a guarantee that the resources will be
// released: it only removes one ref from each resource. The resources will
// be released when the ref count reaches 0.
// TODO(vmpstr): Instead of providing a convenience function, we should
// convert ResourceFrame to be RAII so that it can be automatically
// "returned".
ResourceFrame ImportResources(std::unique_ptr<SurfaceSavedFrame> saved_frame);
// Return a frame back to the tracker. This unrefs all of the resources.
void ReturnFrame(const ResourceFrame& frame);
// Ref count management for the resources returned by `ImportResources`.
void RefResource(ResourceId id);
void UnrefResource(ResourceId id, int count);
bool is_empty() const { return managed_resources_.empty(); }
private:
friend class TransferableResourceTrackerTest;
ResourceId GetNextAvailableResourceId();
PositionedResource ImportResource(
SurfaceSavedFrame::OutputCopyResult output_copy);
static_assert(std::is_same<decltype(kInvalidResourceId.GetUnsafeValue()),
uint32_t>::value,
"ResourceId underlying type should be uint32_t");
const uint32_t starting_id_;
uint32_t next_id_;
const raw_ptr<SharedBitmapManager> shared_bitmap_manager_;
struct TransferableResourceHolder {
using ResourceReleaseCallback =
base::OnceCallback<void(const TransferableResource&)>;
TransferableResourceHolder();
TransferableResourceHolder(const TransferableResource& resource,
ResourceReleaseCallback release_callback);
TransferableResourceHolder(TransferableResourceHolder&& other);
TransferableResourceHolder& operator=(TransferableResourceHolder&& other);
~TransferableResourceHolder();
TransferableResource resource;
ResourceReleaseCallback release_callback;
int ref_count = 0;
};
std::map<ResourceId, TransferableResourceHolder> managed_resources_;
};
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_TRANSITIONS_TRANSFERABLE_RESOURCE_TRACKER_H_