0

Reland "Delete recycled video frame resources in background"

This is a reland of commit fbe817332f

Included required fix for nullptr checking of resource_updater_
(could be nullptr on context lost event).

Original change's description:
> Delete recycled video frame resources in background
>
> Allow to delete video frame resources from VideoFrameUpdater
> recycled pool in background (invisible page) to reduce
> shared image memory footprint.
>
> Bug: 381937282
> Change-Id: I31d7bb6d09978049014099e6071b82684c69177a
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6074531
> Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
> Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
> Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1395458}

Bug: 381937282
Change-Id: Ifed2032a25c6b3e09d2c26c67f6fcec31e7450b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6095721
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1407447}
This commit is contained in:
Andrei Volykhin
2025-01-16 10:51:26 -08:00
committed by Chromium LUCI CQ
parent 1ce03e689e
commit 27976ea3fc
7 changed files with 61 additions and 0 deletions

@ -118,6 +118,7 @@ Andreas Papacharalampous <andreas@apap04.com>
Andrei Borza <andrei.borza@gmail.com>
Andrei Parvu <andrei.prv@gmail.com>
Andrei Parvu <parvu@adobe.com>
Andrei Volykhin <andrei.volykhin@gmail.com>
Andres Salomon <dilinger@queued.net>
Andreu Botella <andreu@andreubotella.com>
Andrew Boyarshin <andrew.boyarshin@gmail.com>

@ -43,6 +43,7 @@
#include "components/viz/common/resources/shared_image_format_utils.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_capabilities.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
@ -727,6 +728,26 @@ void VideoResourceUpdater::AppendQuad(
}
}
void VideoResourceUpdater::ClearFrameResources() {
// Delete recycled resources that are not in use anymore.
bool cleared_resources = std::erase_if(
all_resources_, [](const std::unique_ptr<PlaneResource>& resource) {
// Resources that are still being used can't be deleted.
return !resource->has_refs();
});
// May have destroyed resources above, make sure that it gets to the other
// side. SharedImage destruction (which may be triggered by the removal of
// canvas resources above) is a deferred message, we need to flush pending
// work to ensure that it is not merely queued, but is executed on the service
// side.
if (cleared_resources && context_provider_) {
if (auto* context_support = context_provider_->ContextSupport()) {
context_support->FlushPendingWork();
}
}
}
VideoFrameExternalResource
VideoResourceUpdater::CreateExternalResourceFromVideoFrame(
scoped_refptr<VideoFrame> video_frame) {

@ -116,6 +116,8 @@ class MEDIA_EXPORT VideoResourceUpdater
float draw_opacity,
int sorting_context_id);
void ClearFrameResources();
// TODO(kylechar): This is only public for testing, make private.
VideoFrameExternalResource CreateExternalResourceFromVideoFrame(
scoped_refptr<VideoFrame> video_frame);

@ -128,6 +128,12 @@ void VideoFrameResourceProvider::ReleaseFrameResources() {
resource_updater_->ReleaseFrameResource();
}
void VideoFrameResourceProvider::ClearFrameResources() {
if (resource_updater_) {
resource_updater_->ClearFrameResources();
}
}
void VideoFrameResourceProvider::PrepareSendToParent(
const WebVector<viz::ResourceId>& resource_ids,
WebVector<viz::TransferableResource>* transferable_resources) {

@ -52,6 +52,7 @@ class PLATFORM_EXPORT VideoFrameResourceProvider {
media::VideoTransformation,
bool is_opaque);
virtual void ReleaseFrameResources();
virtual void ClearFrameResources();
// Once the context is lost, we must call Initialize again before we can
// continue doing work.

@ -52,6 +52,12 @@ BASE_FEATURE(kUseVideoFrameSinkBundle,
"UseVideoFrameSinkBundle",
base::FEATURE_ENABLED_BY_DEFAULT);
// When VideoFrameSubmitter::ReclaimResources() is called in background,
// trigger a clean of recycled video frames.
BASE_FEATURE(kClearVideoFrameResourcesInBackground,
"ClearVideoFrameResourcesInBackground",
base::FEATURE_ENABLED_BY_DEFAULT);
// Builds a cc::FrameInfo representing a video frame, which is considered
// Compositor-only.
cc::FrameInfo CreateFrameInfo(cc::FrameInfo::FrameFinalState final_state) {
@ -565,6 +571,17 @@ void VideoFrameSubmitter::ReclaimResources(
WTF::Vector<viz::ReturnedResource> resources) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
resource_provider_->ReceiveReturnsFromParent(std::move(resources));
// We've already submitted an empty frame so post a delayed task to clear
// frame resources.
if (!ShouldSubmit() && !last_frame_id_.has_value() &&
base::FeatureList::IsEnabled(kClearVideoFrameResourcesInBackground)) {
task_runner_->PostDelayedTask(
FROM_HERE,
base::BindOnce(&VideoFrameSubmitter::ClearFrameResources,
weak_ptr_factory_.GetWeakPtr()),
base::Seconds(5));
}
}
void VideoFrameSubmitter::OnReceivedContextProvider(
@ -993,4 +1010,15 @@ void VideoFrameSubmitter::NotifyOpacityIfNeeded(Opacity new_opacity) {
surface_embedder_->OnOpacityChanged(new_opacity == Opacity::kIsOpaque);
}
void VideoFrameSubmitter::ClearFrameResources() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// If we are allowed to submit real frames, then don't clear frame resources.
if (ShouldSubmit()) {
return;
}
resource_provider_->ClearFrameResources();
}
} // namespace blink

@ -160,6 +160,8 @@ class PLATFORM_EXPORT VideoFrameSubmitter
// has changed.
void NotifyOpacityIfNeeded(Opacity new_opacity);
void ClearFrameResources();
raw_ptr<cc::VideoFrameProvider> video_frame_provider_ = nullptr;
bool is_media_stream_ = false;
scoped_refptr<viz::RasterContextProvider> context_provider_;