1 // Copyright 2018 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "tests/cefclient/browser/osr_render_handler_win.h"
6
7 #include "include/base/cef_callback.h"
8 #include "include/wrapper/cef_closure_task.h"
9 #include "include/wrapper/cef_helpers.h"
10 #include "tests/shared/browser/util_win.h"
11
12 namespace client {
13
OsrRenderHandlerWin(const OsrRendererSettings & settings,HWND hwnd)14 OsrRenderHandlerWin::OsrRenderHandlerWin(const OsrRendererSettings& settings,
15 HWND hwnd)
16 : settings_(settings),
17 hwnd_(hwnd),
18 begin_frame_pending_(false),
19 weak_factory_(this) {
20 CEF_REQUIRE_UI_THREAD();
21 DCHECK(hwnd_);
22 }
23
~OsrRenderHandlerWin()24 OsrRenderHandlerWin::~OsrRenderHandlerWin() {
25 CEF_REQUIRE_UI_THREAD();
26 }
27
SetBrowser(CefRefPtr<CefBrowser> browser)28 void OsrRenderHandlerWin::SetBrowser(CefRefPtr<CefBrowser> browser) {
29 CEF_REQUIRE_UI_THREAD();
30 browser_ = browser;
31 if (browser_ && settings_.external_begin_frame_enabled) {
32 // Start the BeginFrame timer.
33 Invalidate();
34 }
35 }
36
Invalidate()37 void OsrRenderHandlerWin::Invalidate() {
38 CEF_REQUIRE_UI_THREAD();
39 if (begin_frame_pending_) {
40 // The timer is already running.
41 return;
42 }
43
44 // Trigger the BeginFrame timer.
45 CHECK_GT(settings_.begin_frame_rate, 0);
46 const float delay_us = (1.0 / double(settings_.begin_frame_rate)) * 1000000.0;
47 TriggerBeginFrame(0, delay_us);
48 }
49
TriggerBeginFrame(uint64_t last_time_us,float delay_us)50 void OsrRenderHandlerWin::TriggerBeginFrame(uint64_t last_time_us,
51 float delay_us) {
52 if (begin_frame_pending_ && !settings_.external_begin_frame_enabled) {
53 // Render immediately and then wait for the next call to Invalidate() or
54 // On[Accelerated]Paint().
55 begin_frame_pending_ = false;
56 Render();
57 return;
58 }
59
60 const auto now = GetTimeNow();
61 float offset = now - last_time_us;
62 if (offset > delay_us) {
63 offset = delay_us;
64 }
65
66 if (!begin_frame_pending_) {
67 begin_frame_pending_ = true;
68 }
69
70 // Trigger again after the necessary delay to maintain the desired frame rate.
71 CefPostDelayedTask(TID_UI,
72 base::BindOnce(&OsrRenderHandlerWin::TriggerBeginFrame,
73 weak_factory_.GetWeakPtr(), now, delay_us),
74 int64(offset / 1000.0));
75
76 if (settings_.external_begin_frame_enabled && browser_) {
77 // We're running the BeginFrame timer. Trigger rendering via
78 // On[Accelerated]Paint().
79 browser_->GetHost()->SendExternalBeginFrame();
80 }
81 }
82
83 } // namespace client
84