Commit bdbdc364 authored by Weiliang Chen's avatar Weiliang Chen Committed by Commit Bot

viz: OverlayProcessor Android Synchronous Initialization

When OverlayProcessorAndroid tries to create the gpu thread part of
processor, wait at the initialization to make it synchronous.

R=khushal

Bug: 979788, 1044671
Change-Id: I6f9c65a6710d7af30a096958b471f250b156722f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2025643
Commit-Queue: weiliangc <weiliangc@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737041}
parent e3d8d933
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "components/viz/service/display/overlay_processor_android.h" #include "components/viz/service/display/overlay_processor_android.h"
#include "base/synchronization/waitable_event.h"
#include "components/viz/common/quads/stream_video_draw_quad.h" #include "components/viz/common/quads/stream_video_draw_quad.h"
#include "components/viz/service/display/overlay_processor_on_gpu.h" #include "components/viz/service/display/overlay_processor_on_gpu.h"
#include "components/viz/service/display/overlay_strategy_underlay.h" #include "components/viz/service/display/overlay_strategy_underlay.h"
...@@ -22,15 +23,20 @@ OverlayProcessorAndroid::OverlayProcessorAndroid( ...@@ -22,15 +23,20 @@ OverlayProcessorAndroid::OverlayProcessorAndroid(
if (!overlay_enabled_) if (!overlay_enabled_)
return; return;
// In unittests, we don't have the gpu_task_scheduler_ set up, but still want
// to test ProcessForOverlays functionalities where we are making overlay
// candidates correctly.
if (gpu_task_scheduler_) { if (gpu_task_scheduler_) {
gpu::ScopedAllowScheduleGpuTask allow_schedule_gpu_task; gpu::ScopedAllowScheduleGpuTask allow_schedule_gpu_task;
// TODO(weiliangc): Eventually move the on gpu initialization to another // TODO(weiliangc): Eventually move the on gpu initialization to another
// static function. // static function.
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
auto callback = base::BindOnce( auto callback = base::BindOnce(
&OverlayProcessorAndroid::InitializeOverlayProcessorOnGpu, &OverlayProcessorAndroid::InitializeOverlayProcessorOnGpu,
base::Unretained(this), shared_image_manager); base::Unretained(this), shared_image_manager, &event);
gpu_task_scheduler_->ScheduleGpuTask(std::move(callback), {}); gpu_task_scheduler_->ScheduleGpuTask(std::move(callback), {});
able_to_create_processor_on_gpu_ = true; event.Wait();
} }
// For Android, we do not have the ability to skip an overlay, since the // For Android, we do not have the ability to skip an overlay, since the
...@@ -47,7 +53,7 @@ OverlayProcessorAndroid::OverlayProcessorAndroid( ...@@ -47,7 +53,7 @@ OverlayProcessorAndroid::OverlayProcessorAndroid(
} }
OverlayProcessorAndroid::~OverlayProcessorAndroid() { OverlayProcessorAndroid::~OverlayProcessorAndroid() {
if (able_to_create_processor_on_gpu_) { if (processor_on_gpu_) {
gpu::ScopedAllowScheduleGpuTask allow_schedule_gpu_task; gpu::ScopedAllowScheduleGpuTask allow_schedule_gpu_task;
// If we have a |gpu_task_scheduler_|, we must have started initializing // If we have a |gpu_task_scheduler_|, we must have started initializing
// a |processor_on_gpu_| on the |gpu_task_scheduler_|. // a |processor_on_gpu_| on the |gpu_task_scheduler_|.
...@@ -62,10 +68,12 @@ OverlayProcessorAndroid::~OverlayProcessorAndroid() { ...@@ -62,10 +68,12 @@ OverlayProcessorAndroid::~OverlayProcessorAndroid() {
} }
void OverlayProcessorAndroid::InitializeOverlayProcessorOnGpu( void OverlayProcessorAndroid::InitializeOverlayProcessorOnGpu(
gpu::SharedImageManager* shared_image_manager) { gpu::SharedImageManager* shared_image_manager,
base::WaitableEvent* event) {
processor_on_gpu_ = processor_on_gpu_ =
std::make_unique<OverlayProcessorOnGpu>(shared_image_manager); std::make_unique<OverlayProcessorOnGpu>(shared_image_manager);
gpu_init_event_.Signal(); DCHECK(event);
event->Signal();
} }
void OverlayProcessorAndroid::DestroyOverlayProcessorOnGpu( void OverlayProcessorAndroid::DestroyOverlayProcessorOnGpu(
...@@ -85,10 +93,17 @@ bool OverlayProcessorAndroid::NeedsSurfaceOccludingDamageRect() const { ...@@ -85,10 +93,17 @@ bool OverlayProcessorAndroid::NeedsSurfaceOccludingDamageRect() const {
void OverlayProcessorAndroid::ScheduleOverlays( void OverlayProcessorAndroid::ScheduleOverlays(
DisplayResourceProvider* resource_provider) { DisplayResourceProvider* resource_provider) {
if (!gpu_task_scheduler_) if (!processor_on_gpu_)
return; return;
// Even if we don't have anything to overlay, still generate overlay locks for
// empty frame.
pending_overlay_locks_.emplace_back(); pending_overlay_locks_.emplace_back();
// Early out if we don't have any overlay candidates.
if (overlay_candidates_.empty())
return;
auto& locks = pending_overlay_locks_.back(); auto& locks = pending_overlay_locks_.back();
std::vector<gpu::SyncToken> locks_sync_tokens; std::vector<gpu::SyncToken> locks_sync_tokens;
for (auto& candidate : overlay_candidates_) { for (auto& candidate : overlay_candidates_) {
...@@ -96,10 +111,6 @@ void OverlayProcessorAndroid::ScheduleOverlays( ...@@ -96,10 +111,6 @@ void OverlayProcessorAndroid::ScheduleOverlays(
locks_sync_tokens.push_back(locks.back().sync_token()); locks_sync_tokens.push_back(locks.back().sync_token());
} }
// If we haven't finished creating processor_on_gpu_, wait for it.
if (!processor_on_gpu_ && able_to_create_processor_on_gpu_)
gpu_init_event_.Wait();
auto task = base::BindOnce(&OverlayProcessorOnGpu::ScheduleOverlays, auto task = base::BindOnce(&OverlayProcessorOnGpu::ScheduleOverlays,
base::Unretained(processor_on_gpu_.get()), base::Unretained(processor_on_gpu_.get()),
std::move(overlay_candidates_)); std::move(overlay_candidates_));
...@@ -175,9 +186,16 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion( ...@@ -175,9 +186,16 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion(
if (!resource_provider->DoAnyResourcesWantPromotionHints()) if (!resource_provider->DoAnyResourcesWantPromotionHints())
return; return;
// |promotion_hint_requestor_set_| is calculated here, so it should be empty // If we don't have a processor_on_gpu_, there is nothing to send the overlay
// to begin with. // promotions to.
DCHECK(promotion_hint_requestor_set_.empty()); if (!processor_on_gpu_) {
promotion_hint_info_map_.clear();
return;
}
// Set of resources that have requested a promotion hint that also have quads
// that use them.
ResourceIdSet promotion_hint_requestor_set;
for (auto* quad : quad_list) { for (auto* quad : quad_list) {
if (quad->material != DrawQuad::Material::kStreamVideoContent) if (quad->material != DrawQuad::Material::kStreamVideoContent)
...@@ -185,7 +203,7 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion( ...@@ -185,7 +203,7 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion(
ResourceId id = StreamVideoDrawQuad::MaterialCast(quad)->resource_id(); ResourceId id = StreamVideoDrawQuad::MaterialCast(quad)->resource_id();
if (!resource_provider->DoesResourceWantPromotionHint(id)) if (!resource_provider->DoesResourceWantPromotionHint(id))
continue; continue;
promotion_hint_requestor_set_.insert(id); promotion_hint_requestor_set.insert(id);
} }
base::flat_set<gpu::Mailbox> promotion_denied; base::flat_set<gpu::Mailbox> promotion_denied;
...@@ -196,7 +214,7 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion( ...@@ -196,7 +214,7 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion(
std::vector< std::vector<
std::unique_ptr<DisplayResourceProvider::ScopedReadLockSharedImage>> std::unique_ptr<DisplayResourceProvider::ScopedReadLockSharedImage>>
locks; locks;
for (auto& request : promotion_hint_requestor_set_) { for (auto& request : promotion_hint_requestor_set) {
// If we successfully promote one candidate, then that promotion hint // If we successfully promote one candidate, then that promotion hint
// should be sent later when we schedule the overlay. // should be sent later when we schedule the overlay.
if (!candidates.empty() && candidates.front().resource_id == request) if (!candidates.empty() && candidates.front().resource_id == request)
...@@ -220,10 +238,6 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion( ...@@ -220,10 +238,6 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion(
locks_sync_tokens.push_back(read_lock->sync_token()); locks_sync_tokens.push_back(read_lock->sync_token());
if (gpu_task_scheduler_) { if (gpu_task_scheduler_) {
// If we haven't finished creating processor_on_gpu_, wait for it.
if (!processor_on_gpu_ && able_to_create_processor_on_gpu_)
gpu_init_event_.Wait();
auto task = base::BindOnce(&OverlayProcessorOnGpu::NotifyOverlayPromotions, auto task = base::BindOnce(&OverlayProcessorOnGpu::NotifyOverlayPromotions,
base::Unretained(processor_on_gpu_.get()), base::Unretained(processor_on_gpu_.get()),
std::move(promotion_denied), std::move(promotion_denied),
...@@ -231,7 +245,6 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion( ...@@ -231,7 +245,6 @@ void OverlayProcessorAndroid::NotifyOverlayPromotion(
gpu_task_scheduler_->ScheduleGpuTask(std::move(task), locks_sync_tokens); gpu_task_scheduler_->ScheduleGpuTask(std::move(task), locks_sync_tokens);
} }
promotion_hint_info_map_.clear(); promotion_hint_info_map_.clear();
promotion_hint_requestor_set_.clear();
} }
} // namespace viz } // namespace viz
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_ANDROID_H_ #define COMPONENTS_VIZ_SERVICE_DISPLAY_OVERLAY_PROCESSOR_ANDROID_H_
#include "base/containers/circular_deque.h" #include "base/containers/circular_deque.h"
#include "base/synchronization/waitable_event.h"
#include "components/viz/service/display/display_resource_provider.h" #include "components/viz/service/display/display_resource_provider.h"
#include "components/viz/service/display/overlay_processor_using_strategy.h" #include "components/viz/service/display/overlay_processor_using_strategy.h"
...@@ -58,7 +57,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorAndroid ...@@ -58,7 +57,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorAndroid
// thread. These two methods are scheduled on the gpu thread to setup and // thread. These two methods are scheduled on the gpu thread to setup and
// teardown the gpu side receiver. // teardown the gpu side receiver.
void InitializeOverlayProcessorOnGpu( void InitializeOverlayProcessorOnGpu(
gpu::SharedImageManager* shared_image_manager); gpu::SharedImageManager* shared_image_manager,
base::WaitableEvent* event);
void DestroyOverlayProcessorOnGpu(base::WaitableEvent* event); void DestroyOverlayProcessorOnGpu(base::WaitableEvent* event);
void TakeOverlayCandidates(CandidateList* candidate_list) override; void TakeOverlayCandidates(CandidateList* candidate_list) override;
void NotifyOverlayPromotion( void NotifyOverlayPromotion(
...@@ -73,18 +73,10 @@ class VIZ_SERVICE_EXPORT OverlayProcessorAndroid ...@@ -73,18 +73,10 @@ class VIZ_SERVICE_EXPORT OverlayProcessorAndroid
// overlay, if one backs them with a SurfaceView. // overlay, if one backs them with a SurfaceView.
PromotionHintInfoMap promotion_hint_info_map_; PromotionHintInfoMap promotion_hint_info_map_;
// Set of resources that have requested a promotion hint that also have quads
// that use them.
ResourceIdSet promotion_hint_requestor_set_;
scoped_refptr<gpu::GpuTaskSchedulerHelper> gpu_task_scheduler_; scoped_refptr<gpu::GpuTaskSchedulerHelper> gpu_task_scheduler_;
const bool overlay_enabled_; const bool overlay_enabled_;
bool able_to_create_processor_on_gpu_ = false;
// This class is created, accessed, and destroyed on the gpu thread. // This class is created, accessed, and destroyed on the gpu thread.
std::unique_ptr<OverlayProcessorOnGpu> processor_on_gpu_; std::unique_ptr<OverlayProcessorOnGpu> processor_on_gpu_;
base::WaitableEvent gpu_init_event_{
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED};
OverlayCandidateList overlay_candidates_; OverlayCandidateList overlay_candidates_;
...@@ -93,7 +85,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorAndroid ...@@ -93,7 +85,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorAndroid
// Keep locks on overlay resources to keep them alive. Since we don't have // Keep locks on overlay resources to keep them alive. Since we don't have
// an exact signal on when the overlays are done presenting, use // an exact signal on when the overlays are done presenting, use
// OverlayPresentationComplete as a signal to clear locks from the older frames. // OverlayPresentationComplete as a signal to clear locks from the older
// frames.
base::circular_deque<std::vector<OverlayResourceLock>> pending_overlay_locks_; base::circular_deque<std::vector<OverlayResourceLock>> pending_overlay_locks_;
// Locks for overlays have been committed. |pending_overlay_locks_| will // Locks for overlays have been committed. |pending_overlay_locks_| will
// be moved to |committed_overlay_locks_| after OverlayPresentationComplete. // be moved to |committed_overlay_locks_| after OverlayPresentationComplete.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment