1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "android_webview/browser/gfx/display_scheduler_webview.h"
6 #include "android_webview/browser/gfx/root_frame_sink.h"
7 
8 namespace android_webview {
DisplaySchedulerWebView(RootFrameSink * root_frame_sink)9 DisplaySchedulerWebView::DisplaySchedulerWebView(RootFrameSink* root_frame_sink)
10     : root_frame_sink_(root_frame_sink) {}
~DisplaySchedulerWebView()11 DisplaySchedulerWebView::~DisplaySchedulerWebView() {
12   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
13 }
14 
ForceImmediateSwapIfPossible()15 void DisplaySchedulerWebView::ForceImmediateSwapIfPossible() {
16   // We can't swap immediately
17   NOTREACHED();
18 }
SetNeedsOneBeginFrame(bool needs_draw)19 void DisplaySchedulerWebView::SetNeedsOneBeginFrame(bool needs_draw) {
20   // Used with De-Jelly and headless begin frames
21   NOTREACHED();
22 }
DidSwapBuffers()23 void DisplaySchedulerWebView::DidSwapBuffers() {
24   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
25 
26   bool needs_draw = false;
27   for (auto it = damaged_frames_.begin(); it != damaged_frames_.end();) {
28     DCHECK_GT(it->second, 0);
29     if (!--it->second) {
30       it = damaged_frames_.erase(it);
31     } else {
32       if (!needs_draw) {
33         TRACE_EVENT_INSTANT2(
34             "android_webview",
35             "DisplaySchedulerWebView::DidSwapBuffers first needs_draw",
36             TRACE_EVENT_SCOPE_THREAD, "frame_sink_id", it->first.ToString(),
37             "damage_count", it->second);
38       }
39       needs_draw = true;
40       ++it;
41     }
42   }
43 
44   root_frame_sink_->SetNeedsDraw(needs_draw);
45 }
OutputSurfaceLost()46 void DisplaySchedulerWebView::OutputSurfaceLost() {
47   // WebView can't handle surface lost so this isn't called.
48   NOTREACHED();
49 }
OnDisplayDamaged(viz::SurfaceId surface_id)50 void DisplaySchedulerWebView::OnDisplayDamaged(viz::SurfaceId surface_id) {
51   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
52   // We don't need to track damage of root frame sink as we submit frame to it
53   // at DrawAndSwap and Root Renderer sink because Android View.Invalidation is
54   // handled by SynchronousCompositorHost.
55   if (surface_id.frame_sink_id() != root_frame_sink_->root_frame_sink_id() &&
56       !root_frame_sink_->IsChildSurface(surface_id.frame_sink_id())) {
57     int count = damaged_frames_[surface_id.frame_sink_id()] + 1;
58 
59     TRACE_EVENT_INSTANT2(
60         "android_webview", "DisplaySchedulerWebView::OnDisplayDamaged",
61         TRACE_EVENT_SCOPE_THREAD, "frame_sink_id",
62         surface_id.frame_sink_id().ToString(), "damage_count", count);
63 
64     // Clamp value to max two frames. Two is enough to keep invalidation
65     // working, but will prevent number going too high in case if kModeDraw
66     // doesn't happen for some time.
67     damaged_frames_[surface_id.frame_sink_id()] = std::min(2, count);
68 
69     root_frame_sink_->SetNeedsDraw(true);
70   }
71 }
72 }  // namespace android_webview
73