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:

committed by
Chromium LUCI CQ

parent
1ce03e689e
commit
27976ea3fc
1
AUTHORS
1
AUTHORS
@ -118,6 +118,7 @@ Andreas Papacharalampous <andreas@apap04.com>
|
|||||||
Andrei Borza <andrei.borza@gmail.com>
|
Andrei Borza <andrei.borza@gmail.com>
|
||||||
Andrei Parvu <andrei.prv@gmail.com>
|
Andrei Parvu <andrei.prv@gmail.com>
|
||||||
Andrei Parvu <parvu@adobe.com>
|
Andrei Parvu <parvu@adobe.com>
|
||||||
|
Andrei Volykhin <andrei.volykhin@gmail.com>
|
||||||
Andres Salomon <dilinger@queued.net>
|
Andres Salomon <dilinger@queued.net>
|
||||||
Andreu Botella <andreu@andreubotella.com>
|
Andreu Botella <andreu@andreubotella.com>
|
||||||
Andrew Boyarshin <andrew.boyarshin@gmail.com>
|
Andrew Boyarshin <andrew.boyarshin@gmail.com>
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "components/viz/common/resources/shared_image_format_utils.h"
|
#include "components/viz/common/resources/shared_image_format_utils.h"
|
||||||
#include "gpu/GLES2/gl2extchromium.h"
|
#include "gpu/GLES2/gl2extchromium.h"
|
||||||
#include "gpu/command_buffer/client/client_shared_image.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/client/shared_image_interface.h"
|
||||||
#include "gpu/command_buffer/common/shared_image_capabilities.h"
|
#include "gpu/command_buffer/common/shared_image_capabilities.h"
|
||||||
#include "gpu/command_buffer/common/shared_image_trace_utils.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
|
VideoFrameExternalResource
|
||||||
VideoResourceUpdater::CreateExternalResourceFromVideoFrame(
|
VideoResourceUpdater::CreateExternalResourceFromVideoFrame(
|
||||||
scoped_refptr<VideoFrame> video_frame) {
|
scoped_refptr<VideoFrame> video_frame) {
|
||||||
|
@ -116,6 +116,8 @@ class MEDIA_EXPORT VideoResourceUpdater
|
|||||||
float draw_opacity,
|
float draw_opacity,
|
||||||
int sorting_context_id);
|
int sorting_context_id);
|
||||||
|
|
||||||
|
void ClearFrameResources();
|
||||||
|
|
||||||
// TODO(kylechar): This is only public for testing, make private.
|
// TODO(kylechar): This is only public for testing, make private.
|
||||||
VideoFrameExternalResource CreateExternalResourceFromVideoFrame(
|
VideoFrameExternalResource CreateExternalResourceFromVideoFrame(
|
||||||
scoped_refptr<VideoFrame> video_frame);
|
scoped_refptr<VideoFrame> video_frame);
|
||||||
|
@ -128,6 +128,12 @@ void VideoFrameResourceProvider::ReleaseFrameResources() {
|
|||||||
resource_updater_->ReleaseFrameResource();
|
resource_updater_->ReleaseFrameResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoFrameResourceProvider::ClearFrameResources() {
|
||||||
|
if (resource_updater_) {
|
||||||
|
resource_updater_->ClearFrameResources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VideoFrameResourceProvider::PrepareSendToParent(
|
void VideoFrameResourceProvider::PrepareSendToParent(
|
||||||
const WebVector<viz::ResourceId>& resource_ids,
|
const WebVector<viz::ResourceId>& resource_ids,
|
||||||
WebVector<viz::TransferableResource>* transferable_resources) {
|
WebVector<viz::TransferableResource>* transferable_resources) {
|
||||||
|
@ -52,6 +52,7 @@ class PLATFORM_EXPORT VideoFrameResourceProvider {
|
|||||||
media::VideoTransformation,
|
media::VideoTransformation,
|
||||||
bool is_opaque);
|
bool is_opaque);
|
||||||
virtual void ReleaseFrameResources();
|
virtual void ReleaseFrameResources();
|
||||||
|
virtual void ClearFrameResources();
|
||||||
|
|
||||||
// Once the context is lost, we must call Initialize again before we can
|
// Once the context is lost, we must call Initialize again before we can
|
||||||
// continue doing work.
|
// continue doing work.
|
||||||
|
@ -52,6 +52,12 @@ BASE_FEATURE(kUseVideoFrameSinkBundle,
|
|||||||
"UseVideoFrameSinkBundle",
|
"UseVideoFrameSinkBundle",
|
||||||
base::FEATURE_ENABLED_BY_DEFAULT);
|
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
|
// Builds a cc::FrameInfo representing a video frame, which is considered
|
||||||
// Compositor-only.
|
// Compositor-only.
|
||||||
cc::FrameInfo CreateFrameInfo(cc::FrameInfo::FrameFinalState final_state) {
|
cc::FrameInfo CreateFrameInfo(cc::FrameInfo::FrameFinalState final_state) {
|
||||||
@ -565,6 +571,17 @@ void VideoFrameSubmitter::ReclaimResources(
|
|||||||
WTF::Vector<viz::ReturnedResource> resources) {
|
WTF::Vector<viz::ReturnedResource> resources) {
|
||||||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
||||||
resource_provider_->ReceiveReturnsFromParent(std::move(resources));
|
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(
|
void VideoFrameSubmitter::OnReceivedContextProvider(
|
||||||
@ -993,4 +1010,15 @@ void VideoFrameSubmitter::NotifyOpacityIfNeeded(Opacity new_opacity) {
|
|||||||
surface_embedder_->OnOpacityChanged(new_opacity == Opacity::kIsOpaque);
|
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
|
} // namespace blink
|
||||||
|
@ -160,6 +160,8 @@ class PLATFORM_EXPORT VideoFrameSubmitter
|
|||||||
// has changed.
|
// has changed.
|
||||||
void NotifyOpacityIfNeeded(Opacity new_opacity);
|
void NotifyOpacityIfNeeded(Opacity new_opacity);
|
||||||
|
|
||||||
|
void ClearFrameResources();
|
||||||
|
|
||||||
raw_ptr<cc::VideoFrameProvider> video_frame_provider_ = nullptr;
|
raw_ptr<cc::VideoFrameProvider> video_frame_provider_ = nullptr;
|
||||||
bool is_media_stream_ = false;
|
bool is_media_stream_ = false;
|
||||||
scoped_refptr<viz::RasterContextProvider> context_provider_;
|
scoped_refptr<viz::RasterContextProvider> context_provider_;
|
||||||
|
Reference in New Issue
Block a user