1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125

android_webview / browser / gfx / display_webview.cc [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.

#include "android_webview/browser/gfx/display_webview.h"

#include "android_webview/browser/gfx/overlay_processor_webview.h"
#include "android_webview/browser/gfx/root_frame_sink.h"
#include "base/memory/ptr_util.h"
#include "components/viz/common/features.h"
#include "components/viz/service/display/overlay_processor_stub.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "gpu/config/gpu_finch_features.h"

namespace android_webview {

std::unique_ptr<DisplayWebView> DisplayWebView::Create(
    const viz::RendererSettings& settings,
    const viz::DebugRendererSettings* debug_settings,
    const viz::FrameSinkId& frame_sink_id,
    std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
        gpu_dependency,
    std::unique_ptr<viz::OutputSurface> output_surface,
    viz::FrameSinkManagerImpl* frame_sink_manager,
    RootFrameSink* root_frame_sink) {
  std::unique_ptr<viz::OverlayProcessorInterface> overlay_processor;
  OverlayProcessorWebView* overlay_processor_webview_raw = nullptr;
  if (features::IsAndroidSurfaceControlEnabled()) {
    // TODO(crbug.com/40113791): This is to help triage bugs on pre-release
    // android. Remove this log once feature is controlled only by feature flag
    // or launched.
    LOG(WARNING) << "WebView overlays are enabled!";
    auto overlay_processor_webview = std::make_unique<OverlayProcessorWebView>(
        gpu_dependency.get(), frame_sink_manager);
    overlay_processor_webview_raw = overlay_processor_webview.get();
    overlay_processor = std::move(overlay_processor_webview);
  } else {
    overlay_processor = std::make_unique<viz::OverlayProcessorStub>();
  }

  auto scheduler = std::make_unique<DisplaySchedulerWebView>(
      root_frame_sink, overlay_processor_webview_raw);

  return base::WrapUnique(new DisplayWebView(
      settings, debug_settings, frame_sink_id, std::move(gpu_dependency),
      std::move(output_surface), std::move(overlay_processor),
      std::move(scheduler), overlay_processor_webview_raw, frame_sink_manager,
      root_frame_sink));
}

DisplayWebView::DisplayWebView(
    const viz::RendererSettings& settings,
    const viz::DebugRendererSettings* debug_settings,
    const viz::FrameSinkId& frame_sink_id,
    std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
        gpu_dependency,
    std::unique_ptr<viz::OutputSurface> output_surface,
    std::unique_ptr<viz::OverlayProcessorInterface> overlay_processor,
    std::unique_ptr<viz::DisplaySchedulerBase> scheduler,
    OverlayProcessorWebView* overlay_processor_webview,
    viz::FrameSinkManagerImpl* frame_sink_manager,
    RootFrameSink* root_frame_sink)
    : viz::Display(/*bitmap_manager=*/nullptr,
                   /*shared_image_manager=*/nullptr,
                   /*gpu_scheduler=*/nullptr,
                   settings,
                   debug_settings,
                   frame_sink_id,
                   std::move(gpu_dependency),
                   std::move(output_surface),
                   std::move(overlay_processor),
                   std::move(scheduler),
                   /*current_task_runner=*/nullptr),
      overlay_processor_webview_(overlay_processor_webview),
      frame_sink_manager_(frame_sink_manager),
      root_frame_sink_(root_frame_sink),
      use_new_invalidate_heuristic_(
          features::UseWebViewNewInvalidateHeuristic()) {
  if (overlay_processor_webview_) {
    frame_sink_manager_observation_.Observe(frame_sink_manager);
  }
}

DisplayWebView::~DisplayWebView() = default;

void DisplayWebView::OnFrameSinkDidFinishFrame(
    const viz::FrameSinkId& frame_sink_id,
    const viz::BeginFrameArgs& args) {
  DCHECK(overlay_processor_webview_);
  auto surface_id =
      overlay_processor_webview_->GetOverlaySurfaceId(frame_sink_id);
  if (surface_id.is_valid()) {
    auto* surface =
        frame_sink_manager_->surface_manager()->GetSurfaceForId(surface_id);
    DCHECK(surface);

    if (use_new_invalidate_heuristic_) {
      // For overlays we are going to display this frame immediately, so commit
      // it.
      surface->CommitFramesRecursively(
          [](const viz::SurfaceId&, const viz::BeginFrameId&) { return true; });
    }

    // TODO(vasilyt): We don't need full aggregation here as we don't need
    // aggregated frame.
    aggregator_->Aggregate(current_surface_id_, base::TimeTicks::Now(),
                           gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(),
                           ++swapped_trace_id_);
    auto* resolved_data = aggregator_->GetLatestFrameData(surface_id);
    if (resolved_data) {
      if (!overlay_processor_webview_->ProcessForFrameSinkId(frame_sink_id,
                                                             resolved_data)) {
        // If we failed to update overlay buffer, we need to invalidate to make
        // sure full draw happens.
        root_frame_sink_->InvalidateForOverlays();
      }
    }
  }
}

const base::flat_set<viz::SurfaceId>& DisplayWebView::GetContainedSurfaceIds() {
  return aggregator_->previous_contained_surfaces();
}

}  // namespace android_webview