browser_view_renderer.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. // Copyright 2014 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. #include "android_webview/browser/gfx/browser_view_renderer.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "android_webview/browser/gfx/browser_view_renderer_client.h"
  8. #include "android_webview/browser/gfx/compositor_frame_consumer.h"
  9. #include "android_webview/browser/gfx/root_frame_sink.h"
  10. #include "android_webview/browser/gfx/root_frame_sink_proxy.h"
  11. #include "android_webview/common/aw_features.h"
  12. #include "base/auto_reset.h"
  13. #include "base/check_op.h"
  14. #include "base/command_line.h"
  15. #include "base/memory/raw_ptr.h"
  16. #include "base/numerics/safe_conversions.h"
  17. #include "base/strings/string_number_conversions.h"
  18. #include "base/strings/stringprintf.h"
  19. #include "base/supports_user_data.h"
  20. #include "base/trace_event/traced_value.h"
  21. #include "cc/base/math_util.h"
  22. #include "components/viz/common/features.h"
  23. #include "components/viz/common/frame_sinks/copy_output_request.h"
  24. #include "components/viz/common/quads/compositor_frame.h"
  25. #include "content/public/browser/render_process_host.h"
  26. #include "content/public/browser/render_view_host.h"
  27. #include "content/public/browser/web_contents.h"
  28. #include "content/public/common/content_switches.h"
  29. #include "gpu/command_buffer/service/gpu_switches.h"
  30. #include "third_party/skia/include/core/SkBitmap.h"
  31. #include "third_party/skia/include/core/SkCanvas.h"
  32. #include "third_party/skia/include/core/SkPicture.h"
  33. #include "third_party/skia/include/core/SkPictureRecorder.h"
  34. #include "ui/gfx/geometry/point.h"
  35. #include "ui/gfx/geometry/point_conversions.h"
  36. #include "ui/gfx/geometry/point_f.h"
  37. #include "ui/gfx/geometry/vector2d_conversions.h"
  38. #include "ui/gfx/geometry/vector2d_f.h"
  39. namespace android_webview {
  40. namespace {
  41. const double kEpsilon = 1e-8;
  42. // Used to calculate memory allocation. Determined experimentally.
  43. const size_t kMemoryMultiplier = 20;
  44. const size_t kBytesPerPixel = 4;
  45. const size_t kMemoryAllocationStep = 5 * 1024 * 1024;
  46. uint64_t g_memory_override_in_bytes = 0u;
  47. const void* const kBrowserViewRendererUserDataKey =
  48. &kBrowserViewRendererUserDataKey;
  49. class BrowserViewRendererUserData : public base::SupportsUserData::Data {
  50. public:
  51. explicit BrowserViewRendererUserData(BrowserViewRenderer* ptr) : bvr_(ptr) {}
  52. static BrowserViewRenderer* GetBrowserViewRenderer(
  53. content::WebContents* web_contents) {
  54. if (!web_contents)
  55. return NULL;
  56. BrowserViewRendererUserData* data =
  57. static_cast<BrowserViewRendererUserData*>(
  58. web_contents->GetUserData(kBrowserViewRendererUserDataKey));
  59. return data ? data->bvr_.get() : NULL;
  60. }
  61. private:
  62. raw_ptr<BrowserViewRenderer> bvr_;
  63. };
  64. } // namespace
  65. // static
  66. void BrowserViewRenderer::CalculateTileMemoryPolicy() {
  67. base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
  68. // If the value was overridden on the command line, use the specified value.
  69. bool client_hard_limit_bytes_overridden =
  70. cl->HasSwitch(switches::kForceGpuMemAvailableMb);
  71. if (client_hard_limit_bytes_overridden) {
  72. base::StringToUint64(
  73. base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
  74. switches::kForceGpuMemAvailableMb),
  75. &g_memory_override_in_bytes);
  76. g_memory_override_in_bytes *= 1024 * 1024;
  77. }
  78. }
  79. // static
  80. BrowserViewRenderer* BrowserViewRenderer::FromWebContents(
  81. content::WebContents* web_contents) {
  82. return BrowserViewRendererUserData::GetBrowserViewRenderer(web_contents);
  83. }
  84. BrowserViewRenderer::BrowserViewRenderer(
  85. BrowserViewRendererClient* client,
  86. const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
  87. : client_(client),
  88. ui_task_runner_(ui_task_runner),
  89. current_compositor_frame_consumer_(nullptr),
  90. compositor_(nullptr),
  91. is_paused_(false),
  92. view_visible_(false),
  93. window_visible_(false),
  94. attached_to_window_(false),
  95. was_attached_(false),
  96. hardware_enabled_(false),
  97. dip_scale_(0.f),
  98. page_scale_factor_(1.f),
  99. min_page_scale_factor_(0.f),
  100. max_page_scale_factor_(0.f),
  101. on_new_picture_enable_(false),
  102. clear_view_(false),
  103. offscreen_pre_raster_(false) {
  104. begin_frame_source_ = std::make_unique<BeginFrameSourceWebView>();
  105. root_frame_sink_proxy_ = std::make_unique<RootFrameSinkProxy>(
  106. ui_task_runner_, this, begin_frame_source_.get());
  107. UpdateBeginFrameSource();
  108. }
  109. BrowserViewRenderer::~BrowserViewRenderer() {
  110. DCHECK(compositor_map_.empty());
  111. DCHECK(!current_compositor_frame_consumer_);
  112. // We need to destroy |root_frame_sink_proxy_| before |begin_frame_source_|;
  113. root_frame_sink_proxy_.reset();
  114. }
  115. base::WeakPtr<CompositorFrameProducer> BrowserViewRenderer::GetWeakPtr() {
  116. return weak_ptr_factory_.GetWeakPtr();
  117. }
  118. void BrowserViewRenderer::SetCurrentCompositorFrameConsumer(
  119. CompositorFrameConsumer* compositor_frame_consumer) {
  120. if (compositor_frame_consumer == current_compositor_frame_consumer_) {
  121. return;
  122. }
  123. current_compositor_frame_consumer_ = compositor_frame_consumer;
  124. if (current_compositor_frame_consumer_) {
  125. // Previous renderer will evict CompositorFrame, compositor needs to submit
  126. // next frames with new local surface id.
  127. if (compositor_)
  128. compositor_->WasEvicted();
  129. RootFrameSinkGetter root_sink_getter;
  130. if (root_frame_sink_proxy_)
  131. root_sink_getter = root_frame_sink_proxy_->GetRootFrameSinkCallback();
  132. current_compositor_frame_consumer_->SetCompositorFrameProducer(
  133. this, std::move(root_sink_getter));
  134. OnParentDrawDataUpdated(current_compositor_frame_consumer_);
  135. }
  136. }
  137. void BrowserViewRenderer::RegisterWithWebContents(
  138. content::WebContents* web_contents) {
  139. web_contents->SetUserData(
  140. kBrowserViewRendererUserDataKey,
  141. std::make_unique<BrowserViewRendererUserData>(this));
  142. }
  143. void BrowserViewRenderer::TrimMemory() {
  144. DCHECK(ui_task_runner_->BelongsToCurrentThread());
  145. TRACE_EVENT0("android_webview", "BrowserViewRenderer::TrimMemory");
  146. // Trimming memory might destroy HardwareRenderer which will evict
  147. // CompositorFrame, compositor needs to submit next frames with new local
  148. // surface id.
  149. if (compositor_)
  150. compositor_->WasEvicted();
  151. // Just set the memory limit to 0 and drop all tiles. This will be reset to
  152. // normal levels in the next DrawGL call.
  153. if (!offscreen_pre_raster_)
  154. ReleaseHardware();
  155. }
  156. gfx::Rect BrowserViewRenderer::ComputeTileRectAndUpdateMemoryPolicy() {
  157. if (!compositor_) {
  158. return gfx::Rect();
  159. }
  160. if (!hardware_enabled_) {
  161. compositor_->SetMemoryPolicy(0u);
  162. return gfx::Rect();
  163. }
  164. gfx::Transform transform_for_tile_priority =
  165. external_draw_constraints_.transform;
  166. gfx::Rect viewport_rect_for_tile_priority_in_view_space;
  167. gfx::Transform screen_to_view(gfx::Transform::kSkipInitialization);
  168. if (transform_for_tile_priority.GetInverse(&screen_to_view)) {
  169. // Convert from screen space to view space.
  170. viewport_rect_for_tile_priority_in_view_space =
  171. cc::MathUtil::ProjectEnclosingClippedRect(
  172. screen_to_view,
  173. gfx::Rect(external_draw_constraints_.viewport_size));
  174. }
  175. viewport_rect_for_tile_priority_in_view_space.Intersect(gfx::Rect(size_));
  176. size_t bytes_limit = 0u;
  177. if (g_memory_override_in_bytes) {
  178. bytes_limit = static_cast<size_t>(g_memory_override_in_bytes);
  179. } else {
  180. // Note we are using |last_on_draw_global_visible_rect_| rather than
  181. // |external_draw_constraints_.viewport_size|. This is to reduce budget
  182. // for a webview that's much smaller than the surface it's rendering.
  183. gfx::Rect interest_rect;
  184. if (offscreen_pre_raster_) {
  185. interest_rect = gfx::Rect(size_);
  186. } else {
  187. // Re-compute screen-space rect for computing tile budget, since tile is
  188. // rastered in screen space.
  189. gfx::Rect viewport_rect_for_tile_priority_in_screen_space =
  190. cc::MathUtil::ProjectEnclosingClippedRect(
  191. transform_for_tile_priority,
  192. viewport_rect_for_tile_priority_in_view_space);
  193. // Intersect by viewport size again, in case axis-aligning operations made
  194. // the rect bigger than necessary.
  195. viewport_rect_for_tile_priority_in_screen_space.Intersect(
  196. gfx::Rect(external_draw_constraints_.viewport_size));
  197. interest_rect = viewport_rect_for_tile_priority_in_screen_space.IsEmpty()
  198. ? last_on_draw_global_visible_rect_
  199. : viewport_rect_for_tile_priority_in_screen_space;
  200. }
  201. size_t width = interest_rect.width();
  202. size_t height = interest_rect.height();
  203. bytes_limit = kMemoryMultiplier * kBytesPerPixel * width * height;
  204. // Round up to a multiple of kMemoryAllocationStep.
  205. bytes_limit =
  206. (bytes_limit / kMemoryAllocationStep + 1) * kMemoryAllocationStep;
  207. }
  208. compositor_->SetMemoryPolicy(bytes_limit);
  209. return viewport_rect_for_tile_priority_in_view_space;
  210. }
  211. content::SynchronousCompositor* BrowserViewRenderer::FindCompositor(
  212. const viz::FrameSinkId& frame_sink_id) const {
  213. const auto& compositor_iterator = compositor_map_.find(frame_sink_id);
  214. if (compositor_iterator == compositor_map_.end())
  215. return nullptr;
  216. return compositor_iterator->second;
  217. }
  218. void BrowserViewRenderer::PrepareToDraw(const gfx::Point& scroll,
  219. const gfx::Rect& global_visible_rect) {
  220. last_on_draw_scroll_offset_ = scroll;
  221. last_on_draw_global_visible_rect_ = global_visible_rect;
  222. }
  223. bool BrowserViewRenderer::CanOnDraw() {
  224. if (!compositor_) {
  225. TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_NoCompositor",
  226. TRACE_EVENT_SCOPE_THREAD);
  227. return false;
  228. }
  229. if (clear_view_) {
  230. TRACE_EVENT_INSTANT0("android_webview", "EarlyOut_ClearView",
  231. TRACE_EVENT_SCOPE_THREAD);
  232. return false;
  233. }
  234. return true;
  235. }
  236. bool BrowserViewRenderer::OnDrawHardware() {
  237. DCHECK(current_compositor_frame_consumer_);
  238. TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware");
  239. const bool did_invalidate = did_invalidate_since_last_draw_;
  240. did_invalidate_since_last_draw_ = false;
  241. if (!CanOnDraw()) {
  242. return false;
  243. }
  244. current_compositor_frame_consumer_->SetScrollOffsetOnUI(
  245. last_on_draw_scroll_offset_);
  246. hardware_enabled_ = true;
  247. DoUpdateParentDrawData();
  248. // Do not override (ie leave empty) for offscreen raster.
  249. gfx::Size viewport_size_for_tile_priority =
  250. offscreen_pre_raster_ ? gfx::Size()
  251. : external_draw_constraints_.viewport_size;
  252. gfx::Rect viewport_rect_for_tile_priority_in_view_space =
  253. ComputeTileRectAndUpdateMemoryPolicy();
  254. // Explanation for the various viewports and transforms. There are:
  255. // * "default" viewport" (and identity transform) that's normally used by
  256. // compositor. This is |size_| in this file.
  257. // * "draw" viewport and transform. Compositor applies them at the root at
  258. // draw time. This is contained in SkCanvas for a software draw
  259. // * "tile" viewport and transform. These are set in hardware draw to
  260. // correctly prioritize and raster tiles.
  261. // The draw viewport was added to support software draw's ability to change
  262. // the viewport and transform at draw time to anything the embedding app
  263. // desires. However the tile system was not expecting its viewport to jump
  264. // around, and only move incrementally due to user input. This required adding
  265. // the tile viewport and transform. Tile and default are separate to reduce
  266. // memory in the case when only a small portion of webview (ie the default
  267. // viewport) is actually visible.
  268. // We intersect the tile viewport with the default viewport above so that the
  269. // tile viewport can only shrink and not grow from the default viewport. This
  270. // is because webview can also be small in relation to the surface size, so
  271. // and growing the tile viewport can cause more tiles to be rastered than
  272. // necessary.
  273. scoped_refptr<content::SynchronousCompositor::FrameFuture> future =
  274. compositor_->DemandDrawHwAsync(
  275. size_, viewport_rect_for_tile_priority_in_view_space,
  276. external_draw_constraints_.transform);
  277. CopyOutputRequestQueue requests;
  278. copy_requests_.swap(requests);
  279. for (auto& copy_request_ptr : requests) {
  280. if (!copy_request_ptr->has_result_task_runner())
  281. copy_request_ptr->set_result_task_runner(ui_task_runner_);
  282. }
  283. std::unique_ptr<ChildFrame> child_frame = std::make_unique<ChildFrame>(
  284. std::move(future), frame_sink_id_, viewport_size_for_tile_priority,
  285. external_draw_constraints_.transform, offscreen_pre_raster_, dip_scale_,
  286. std::move(requests), did_invalidate,
  287. begin_frame_source_->LastDispatchedBeginFrameArgs());
  288. ReturnUnusedResource(
  289. current_compositor_frame_consumer_->SetFrameOnUI(std::move(child_frame)));
  290. return true;
  291. }
  292. void BrowserViewRenderer::OnParentDrawDataUpdated(
  293. CompositorFrameConsumer* compositor_frame_consumer) {
  294. DCHECK(compositor_frame_consumer);
  295. if (compositor_frame_consumer != current_compositor_frame_consumer_)
  296. return;
  297. if (!DoUpdateParentDrawData())
  298. return;
  299. PostInvalidate(compositor_);
  300. ComputeTileRectAndUpdateMemoryPolicy();
  301. }
  302. bool BrowserViewRenderer::DoUpdateParentDrawData() {
  303. ParentCompositorDrawConstraints new_constraints;
  304. viz::FrameTimingDetailsMap new_timing_details;
  305. viz::FrameSinkId id;
  306. uint32_t frame_token = 0u;
  307. current_compositor_frame_consumer_->TakeParentDrawDataOnUI(
  308. &new_constraints, &id, &new_timing_details, &frame_token);
  309. content::SynchronousCompositor* compositor = FindCompositor(id);
  310. if (compositor) {
  311. compositor->DidPresentCompositorFrames(std::move(new_timing_details),
  312. frame_token);
  313. }
  314. if (external_draw_constraints_ == new_constraints)
  315. return false;
  316. external_draw_constraints_ = new_constraints;
  317. return true;
  318. }
  319. void BrowserViewRenderer::OnViewTreeForceDarkStateChanged(
  320. bool view_tree_force_dark_state) {
  321. client_->OnViewTreeForceDarkStateChanged(view_tree_force_dark_state);
  322. }
  323. void BrowserViewRenderer::ChildSurfaceWasEvicted() {
  324. if (compositor_)
  325. compositor_->WasEvicted();
  326. }
  327. void BrowserViewRenderer::RemoveCompositorFrameConsumer(
  328. CompositorFrameConsumer* consumer) {
  329. ReturnUncommittedFrames(consumer->PassUncommittedFrameOnUI());
  330. if (current_compositor_frame_consumer_ == consumer)
  331. SetCurrentCompositorFrameConsumer(nullptr);
  332. }
  333. void BrowserViewRenderer::ReturnUncommittedFrames(
  334. ChildFrameQueue child_frames) {
  335. for (auto& child_frame : child_frames)
  336. ReturnUnusedResource(std::move(child_frame));
  337. }
  338. void BrowserViewRenderer::ReturnUnusedResource(
  339. std::unique_ptr<ChildFrame> child_frame) {
  340. if (!child_frame.get() || !child_frame->frame.get())
  341. return;
  342. std::vector<viz::ReturnedResource> resources =
  343. viz::TransferableResource::ReturnResources(
  344. child_frame->frame->resource_list);
  345. content::SynchronousCompositor* compositor =
  346. FindCompositor(child_frame->frame_sink_id);
  347. if (compositor && !resources.empty())
  348. compositor->ReturnResources(child_frame->layer_tree_frame_sink_id,
  349. std::move(resources));
  350. }
  351. void BrowserViewRenderer::ReturnUsedResources(
  352. std::vector<viz::ReturnedResource> resources,
  353. const viz::FrameSinkId& frame_sink_id,
  354. uint32_t layer_tree_frame_sink_id) {
  355. content::SynchronousCompositor* compositor = FindCompositor(frame_sink_id);
  356. if (compositor && !resources.empty())
  357. compositor->ReturnResources(layer_tree_frame_sink_id, std::move(resources));
  358. has_rendered_frame_ = true;
  359. }
  360. bool BrowserViewRenderer::OnDrawSoftware(SkCanvas* canvas) {
  361. did_invalidate_since_last_draw_ = false;
  362. return CanOnDraw() && CompositeSW(canvas, /*software_canvas=*/true);
  363. }
  364. bool BrowserViewRenderer::NeedToDrawBackgroundColor() {
  365. return !has_rendered_frame_;
  366. }
  367. sk_sp<SkPicture> BrowserViewRenderer::CapturePicture(int width,
  368. int height) {
  369. TRACE_EVENT0("android_webview", "BrowserViewRenderer::CapturePicture");
  370. // Return empty Picture objects for empty SkPictures.
  371. if (width <= 0 || height <= 0) {
  372. SkPictureRecorder emptyRecorder;
  373. emptyRecorder.beginRecording(0, 0);
  374. return emptyRecorder.finishRecordingAsPicture();
  375. }
  376. SkPictureRecorder recorder;
  377. SkCanvas* rec_canvas = recorder.beginRecording(width, height);
  378. if (compositor_) {
  379. {
  380. // Reset scroll back to the origin, will go back to the old
  381. // value when scroll_reset is out of scope.
  382. base::AutoReset<gfx::PointF> scroll_reset(&scroll_offset_unscaled_,
  383. gfx::PointF());
  384. compositor_->DidChangeRootLayerScrollOffset(scroll_offset_unscaled_);
  385. CompositeSW(rec_canvas, /*software_canvas=*/false);
  386. }
  387. compositor_->DidChangeRootLayerScrollOffset(scroll_offset_unscaled_);
  388. }
  389. return recorder.finishRecordingAsPicture();
  390. }
  391. void BrowserViewRenderer::EnableOnNewPicture(bool enabled) {
  392. on_new_picture_enable_ = enabled;
  393. }
  394. void BrowserViewRenderer::ClearView() {
  395. TRACE_EVENT_INSTANT0("android_webview",
  396. "BrowserViewRenderer::ClearView",
  397. TRACE_EVENT_SCOPE_THREAD);
  398. if (clear_view_)
  399. return;
  400. clear_view_ = true;
  401. // Always invalidate ignoring the compositor to actually clear the webview.
  402. PostInvalidate(compositor_);
  403. }
  404. void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) {
  405. if (offscreen_pre_raster_ != enable) {
  406. offscreen_pre_raster_ = enable;
  407. ComputeTileRectAndUpdateMemoryPolicy();
  408. }
  409. }
  410. void BrowserViewRenderer::SetIsPaused(bool paused) {
  411. TRACE_EVENT_INSTANT1("android_webview",
  412. "BrowserViewRenderer::SetIsPaused",
  413. TRACE_EVENT_SCOPE_THREAD,
  414. "paused",
  415. paused);
  416. is_paused_ = paused;
  417. UpdateBeginFrameSource();
  418. }
  419. void BrowserViewRenderer::SetViewVisibility(bool view_visible) {
  420. TRACE_EVENT_INSTANT1("android_webview",
  421. "BrowserViewRenderer::SetViewVisibility",
  422. TRACE_EVENT_SCOPE_THREAD,
  423. "view_visible",
  424. view_visible);
  425. view_visible_ = view_visible;
  426. }
  427. void BrowserViewRenderer::SetWindowVisibility(bool window_visible) {
  428. TRACE_EVENT_INSTANT1("android_webview",
  429. "BrowserViewRenderer::SetWindowVisibility",
  430. TRACE_EVENT_SCOPE_THREAD,
  431. "window_visible",
  432. window_visible);
  433. window_visible_ = window_visible;
  434. UpdateBeginFrameSource();
  435. }
  436. void BrowserViewRenderer::OnSizeChanged(int width, int height) {
  437. TRACE_EVENT_INSTANT2("android_webview",
  438. "BrowserViewRenderer::OnSizeChanged",
  439. TRACE_EVENT_SCOPE_THREAD,
  440. "width",
  441. width,
  442. "height",
  443. height);
  444. size_.SetSize(width, height);
  445. if (offscreen_pre_raster_)
  446. ComputeTileRectAndUpdateMemoryPolicy();
  447. }
  448. void BrowserViewRenderer::OnAttachedToWindow(int width, int height) {
  449. TRACE_EVENT2("android_webview",
  450. "BrowserViewRenderer::OnAttachedToWindow",
  451. "width",
  452. width,
  453. "height",
  454. height);
  455. attached_to_window_ = true;
  456. was_attached_ = true;
  457. size_.SetSize(width, height);
  458. if (offscreen_pre_raster_)
  459. ComputeTileRectAndUpdateMemoryPolicy();
  460. UpdateBeginFrameSource();
  461. }
  462. void BrowserViewRenderer::OnDetachedFromWindow() {
  463. TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDetachedFromWindow");
  464. attached_to_window_ = false;
  465. ReleaseHardware();
  466. UpdateBeginFrameSource();
  467. }
  468. void BrowserViewRenderer::ZoomBy(float delta) {
  469. if (!compositor_)
  470. return;
  471. compositor_->SynchronouslyZoomBy(
  472. delta, gfx::Point(size_.width() / 2, size_.height() / 2));
  473. }
  474. void BrowserViewRenderer::OnComputeScroll(base::TimeTicks animation_time) {
  475. if (!compositor_)
  476. return;
  477. TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnComputeScroll");
  478. compositor_->OnComputeScroll(animation_time);
  479. }
  480. void BrowserViewRenderer::ReleaseHardware() {
  481. if (current_compositor_frame_consumer_) {
  482. ReturnUncommittedFrames(
  483. current_compositor_frame_consumer_->PassUncommittedFrameOnUI());
  484. }
  485. hardware_enabled_ = false;
  486. has_rendered_frame_ = false;
  487. ComputeTileRectAndUpdateMemoryPolicy();
  488. }
  489. bool BrowserViewRenderer::IsVisible() const {
  490. // Ignore |window_visible_| if |attached_to_window_| is false.
  491. return view_visible_ && (!attached_to_window_ || window_visible_);
  492. }
  493. bool BrowserViewRenderer::IsClientVisible() const {
  494. // When WebView is not paused, we declare it visible even before it is
  495. // attached to window to allow for background operations. If it ever gets
  496. // attached though, the WebView is visible as long as it is attached
  497. // to a window and the window is visible.
  498. return is_paused_
  499. ? false
  500. : !was_attached_ || (attached_to_window_ && window_visible_);
  501. }
  502. void BrowserViewRenderer::UpdateBeginFrameSource() {
  503. if (IsClientVisible()) {
  504. begin_frame_source_->SetParentSource(
  505. RootBeginFrameSourceWebView::GetInstance());
  506. } else {
  507. begin_frame_source_->SetParentSource(nullptr);
  508. }
  509. }
  510. gfx::Rect BrowserViewRenderer::GetScreenRect() const {
  511. return gfx::Rect(client_->GetLocationOnScreen(), size_);
  512. }
  513. void BrowserViewRenderer::DidInitializeCompositor(
  514. content::SynchronousCompositor* compositor,
  515. const viz::FrameSinkId& frame_sink_id) {
  516. TRACE_EVENT_INSTANT0("android_webview",
  517. "BrowserViewRenderer::DidInitializeCompositor",
  518. TRACE_EVENT_SCOPE_THREAD);
  519. DCHECK(compositor);
  520. // This assumes that a RenderViewHost has at most 1 synchronous compositor
  521. // througout its lifetime.
  522. DCHECK(compositor_map_.count(frame_sink_id) == 0);
  523. compositor_map_[frame_sink_id] = compositor;
  524. if (root_frame_sink_proxy_)
  525. root_frame_sink_proxy_->AddChildFrameSinkId(frame_sink_id);
  526. compositor->SetBeginFrameSource(begin_frame_source_.get());
  527. // At this point, the RVHChanged event for the new RVH that contains the
  528. // |compositor| might have been fired already, in which case just set the
  529. // current compositor with the new compositor.
  530. if (frame_sink_id == frame_sink_id_)
  531. SetActiveCompositor(compositor);
  532. }
  533. void BrowserViewRenderer::DidDestroyCompositor(
  534. content::SynchronousCompositor* compositor,
  535. const viz::FrameSinkId& frame_sink_id) {
  536. TRACE_EVENT_INSTANT0("android_webview",
  537. "BrowserViewRenderer::DidDestroyCompositor",
  538. TRACE_EVENT_SCOPE_THREAD);
  539. DCHECK(compositor_map_.count(frame_sink_id));
  540. if (compositor_ == compositor) {
  541. compositor_ = nullptr;
  542. copy_requests_.clear();
  543. }
  544. if (root_frame_sink_proxy_)
  545. root_frame_sink_proxy_->RemoveChildFrameSinkId(frame_sink_id);
  546. compositor_map_.erase(frame_sink_id);
  547. }
  548. void BrowserViewRenderer::SetActiveFrameSinkId(
  549. const viz::FrameSinkId& frame_sink_id) {
  550. frame_sink_id_ = frame_sink_id;
  551. SetActiveCompositor(FindCompositor(frame_sink_id));
  552. }
  553. void BrowserViewRenderer::SetActiveCompositor(
  554. content::SynchronousCompositor* compositor) {
  555. if (compositor_ == compositor)
  556. return;
  557. if (compositor_)
  558. compositor_->SetMemoryPolicy(0u);
  559. compositor_ = compositor;
  560. copy_requests_.clear();
  561. if (compositor_) {
  562. ComputeTileRectAndUpdateMemoryPolicy();
  563. compositor_->DidBecomeActive();
  564. }
  565. }
  566. void BrowserViewRenderer::SetDipScale(float dip_scale) {
  567. dip_scale_ = dip_scale;
  568. CHECK_GT(dip_scale_, 0.f);
  569. }
  570. gfx::Point BrowserViewRenderer::max_scroll_offset() const {
  571. DCHECK_GT(dip_scale_, 0.f);
  572. return gfx::ToCeiledPoint(
  573. gfx::ScalePoint(max_scroll_offset_unscaled_, page_scale_factor_));
  574. }
  575. void BrowserViewRenderer::ScrollTo(const gfx::Point& scroll_offset) {
  576. gfx::Point max_offset = max_scroll_offset();
  577. gfx::PointF scroll_offset_unscaled;
  578. // To preserve the invariant that scrolling to the maximum physical pixel
  579. // value also scrolls to the maximum dip pixel value we transform the physical
  580. // offset into the dip offset by using a proportion (instead of dividing by
  581. // dip_scale * page_scale_factor).
  582. if (max_offset.x()) {
  583. scroll_offset_unscaled.set_x(
  584. (scroll_offset.x() * max_scroll_offset_unscaled_.x()) / max_offset.x());
  585. }
  586. if (max_offset.y()) {
  587. scroll_offset_unscaled.set_y(
  588. (scroll_offset.y() * max_scroll_offset_unscaled_.y()) / max_offset.y());
  589. }
  590. DCHECK_LE(0.f, scroll_offset_unscaled.x());
  591. DCHECK_LE(0.f, scroll_offset_unscaled.y());
  592. DCHECK(scroll_offset_unscaled.x() < max_scroll_offset_unscaled_.x() ||
  593. scroll_offset_unscaled.x() - max_scroll_offset_unscaled_.x() <
  594. kEpsilon)
  595. << scroll_offset_unscaled.x() << " " << max_scroll_offset_unscaled_.x();
  596. DCHECK(scroll_offset_unscaled.y() < max_scroll_offset_unscaled_.y() ||
  597. scroll_offset_unscaled.y() - max_scroll_offset_unscaled_.y() <
  598. kEpsilon)
  599. << scroll_offset_unscaled.y() << " " << max_scroll_offset_unscaled_.y();
  600. if (scroll_offset_unscaled_ == scroll_offset_unscaled)
  601. return;
  602. scroll_offset_unscaled_ = scroll_offset_unscaled;
  603. TRACE_EVENT_INSTANT2("android_webview", "BrowserViewRenderer::ScrollTo",
  604. TRACE_EVENT_SCOPE_THREAD, "x",
  605. scroll_offset_unscaled.x(), "y",
  606. scroll_offset_unscaled.y());
  607. if (compositor_)
  608. compositor_->DidChangeRootLayerScrollOffset(scroll_offset_unscaled);
  609. }
  610. void BrowserViewRenderer::RestoreScrollAfterTransition(
  611. const gfx::Point& scroll_offset) {
  612. // Determine if the clipped scroll offset.
  613. gfx::Point clipped_offset = scroll_offset;
  614. clipped_offset.SetToMin(max_scroll_offset());
  615. // If the scroll will be clipped due to the max scroll then we haven't
  616. // received a ScrollStateUpdate with the revised max scroll values. This
  617. // situation occurs due to a race in exiting fullscreen mode request, we need
  618. // to wait for the max scroll values to be updated before applying the
  619. // restored scroll values.
  620. if (clipped_offset != scroll_offset) {
  621. scroll_on_scroll_state_update_ = scroll_offset;
  622. } else {
  623. ScrollTo(scroll_offset);
  624. }
  625. }
  626. void BrowserViewRenderer::DidUpdateContent(
  627. content::SynchronousCompositor* compositor) {
  628. TRACE_EVENT_INSTANT0("android_webview",
  629. "BrowserViewRenderer::DidUpdateContent",
  630. TRACE_EVENT_SCOPE_THREAD);
  631. if (compositor != compositor_)
  632. return;
  633. clear_view_ = false;
  634. if (on_new_picture_enable_)
  635. client_->OnNewPicture();
  636. }
  637. void BrowserViewRenderer::SetTotalRootLayerScrollOffset(
  638. const gfx::PointF& scroll_offset_unscaled) {
  639. if (scroll_offset_unscaled_ == scroll_offset_unscaled)
  640. return;
  641. scroll_offset_unscaled_ = scroll_offset_unscaled;
  642. gfx::Point max_offset = max_scroll_offset();
  643. gfx::Point scroll_offset;
  644. // For an explanation as to why this is done this way see the comment in
  645. // BrowserViewRenderer::ScrollTo.
  646. if (max_scroll_offset_unscaled_.x()) {
  647. scroll_offset.set_x(
  648. base::ClampRound((scroll_offset_unscaled.x() * max_offset.x()) /
  649. max_scroll_offset_unscaled_.x()));
  650. }
  651. if (max_scroll_offset_unscaled_.y()) {
  652. scroll_offset.set_y(
  653. base::ClampRound((scroll_offset_unscaled.y() * max_offset.y()) /
  654. max_scroll_offset_unscaled_.y()));
  655. }
  656. DCHECK_LE(0, scroll_offset.x());
  657. DCHECK_LE(0, scroll_offset.y());
  658. DCHECK_LE(scroll_offset.x(), max_offset.x());
  659. DCHECK_LE(scroll_offset.y(), max_offset.y());
  660. client_->ScrollContainerViewTo(scroll_offset);
  661. }
  662. void BrowserViewRenderer::UpdateRootLayerState(
  663. content::SynchronousCompositor* compositor,
  664. const gfx::PointF& total_scroll_offset,
  665. const gfx::PointF& total_max_scroll_offset,
  666. const gfx::SizeF& scrollable_size,
  667. float page_scale_factor,
  668. float min_page_scale_factor,
  669. float max_page_scale_factor) {
  670. if (compositor != compositor_)
  671. return;
  672. gfx::SizeF scrollable_size_dip = scrollable_size;
  673. scrollable_size_dip.Scale(1 / dip_scale_);
  674. TRACE_EVENT_INSTANT1(
  675. "android_webview", "BrowserViewRenderer::UpdateRootLayerState",
  676. TRACE_EVENT_SCOPE_THREAD, "state",
  677. RootLayerStateAsValue(total_scroll_offset, scrollable_size_dip));
  678. DCHECK_GE(total_max_scroll_offset.x(), 0.f);
  679. DCHECK_GE(total_max_scroll_offset.y(), 0.f);
  680. DCHECK_GT(page_scale_factor, 0.f);
  681. // SetDipScale should have been called at least once before this is called.
  682. DCHECK_GT(dip_scale_, 0.f);
  683. bool apply_scroll_to = false;
  684. if (max_scroll_offset_unscaled_ != total_max_scroll_offset ||
  685. scrollable_size_dip_ != scrollable_size_dip ||
  686. page_scale_factor_ != page_scale_factor ||
  687. min_page_scale_factor_ != min_page_scale_factor ||
  688. max_page_scale_factor_ != max_page_scale_factor) {
  689. max_scroll_offset_unscaled_ = total_max_scroll_offset;
  690. scrollable_size_dip_ = scrollable_size_dip;
  691. page_scale_factor_ = page_scale_factor;
  692. min_page_scale_factor_ = min_page_scale_factor;
  693. max_page_scale_factor_ = max_page_scale_factor;
  694. client_->UpdateScrollState(max_scroll_offset(), scrollable_size_dip,
  695. page_scale_factor, min_page_scale_factor,
  696. max_page_scale_factor);
  697. apply_scroll_to = scroll_on_scroll_state_update_.has_value();
  698. }
  699. SetTotalRootLayerScrollOffset(total_scroll_offset);
  700. if (apply_scroll_to) {
  701. ScrollTo(scroll_on_scroll_state_update_.value());
  702. scroll_on_scroll_state_update_.reset();
  703. }
  704. }
  705. std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
  706. BrowserViewRenderer::RootLayerStateAsValue(
  707. const gfx::PointF& total_scroll_offset,
  708. const gfx::SizeF& scrollable_size_dip) {
  709. std::unique_ptr<base::trace_event::TracedValue> state(
  710. new base::trace_event::TracedValue());
  711. state->SetDouble("total_scroll_offset.x", total_scroll_offset.x());
  712. state->SetDouble("total_scroll_offset.y", total_scroll_offset.y());
  713. state->SetDouble("max_scroll_offset_unscaled.x",
  714. max_scroll_offset_unscaled_.x());
  715. state->SetDouble("max_scroll_offset_unscaled.y",
  716. max_scroll_offset_unscaled_.y());
  717. state->SetDouble("scrollable_size_dip.width", scrollable_size_dip.width());
  718. state->SetDouble("scrollable_size_dip.height", scrollable_size_dip.height());
  719. state->SetDouble("page_scale_factor", page_scale_factor_);
  720. return std::move(state);
  721. }
  722. void BrowserViewRenderer::DidOverscroll(
  723. content::SynchronousCompositor* compositor,
  724. const gfx::Vector2dF& accumulated_overscroll,
  725. const gfx::Vector2dF& latest_overscroll_delta,
  726. const gfx::Vector2dF& current_fling_velocity) {
  727. if (compositor != compositor_)
  728. return;
  729. const float physical_pixel_scale = dip_scale_ * page_scale_factor_;
  730. if (accumulated_overscroll == latest_overscroll_delta)
  731. overscroll_rounding_error_ = gfx::Vector2dF();
  732. gfx::Vector2dF scaled_overscroll_delta =
  733. gfx::ScaleVector2d(latest_overscroll_delta, physical_pixel_scale);
  734. gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d(
  735. scaled_overscroll_delta + overscroll_rounding_error_);
  736. overscroll_rounding_error_ =
  737. scaled_overscroll_delta - rounded_overscroll_delta;
  738. gfx::Vector2dF fling_velocity_pixels =
  739. gfx::ScaleVector2d(current_fling_velocity, physical_pixel_scale);
  740. client_->DidOverscroll(rounded_overscroll_delta, fling_velocity_pixels,
  741. begin_frame_source_->inside_begin_frame());
  742. }
  743. ui::TouchHandleDrawable* BrowserViewRenderer::CreateDrawable() {
  744. return client_->CreateDrawable();
  745. }
  746. void BrowserViewRenderer::CopyOutput(
  747. content::SynchronousCompositor* compositor,
  748. std::unique_ptr<viz::CopyOutputRequest> copy_request) {
  749. if (compositor != compositor_ || !hardware_enabled_)
  750. return;
  751. copy_requests_.emplace_back(std::move(copy_request));
  752. PostInvalidate(compositor_);
  753. }
  754. void BrowserViewRenderer::Invalidate() {
  755. if (compositor_)
  756. compositor_->DidInvalidate();
  757. PostInvalidate(compositor_);
  758. }
  759. void BrowserViewRenderer::ReturnResourcesFromViz(
  760. viz::FrameSinkId frame_sink_id,
  761. uint32_t layer_tree_frame_sink_id,
  762. std::vector<viz::ReturnedResource> resources) {
  763. ReturnUsedResources(std::move(resources), frame_sink_id,
  764. layer_tree_frame_sink_id);
  765. }
  766. void BrowserViewRenderer::OnCompositorFrameTransitionDirectiveProcessed(
  767. viz::FrameSinkId frame_sink_id,
  768. uint32_t layer_tree_frame_sink_id,
  769. uint32_t sequence_id) {
  770. content::SynchronousCompositor* compositor = FindCompositor(frame_sink_id);
  771. if (compositor) {
  772. compositor->OnCompositorFrameTransitionDirectiveProcessed(
  773. layer_tree_frame_sink_id, sequence_id);
  774. }
  775. }
  776. void BrowserViewRenderer::OnInputEvent() {
  777. if (root_frame_sink_proxy_)
  778. root_frame_sink_proxy_->OnInputEvent();
  779. }
  780. void BrowserViewRenderer::AddBeginFrameCompletionCallback(
  781. base::OnceClosure callback) {
  782. begin_frame_source_->AddBeginFrameCompletionCallback(std::move(callback));
  783. }
  784. void BrowserViewRenderer::PostInvalidate(
  785. content::SynchronousCompositor* compositor) {
  786. TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate",
  787. TRACE_EVENT_SCOPE_THREAD);
  788. if (compositor != compositor_)
  789. return;
  790. did_invalidate_since_last_draw_ = true;
  791. client_->PostInvalidate(
  792. RootBeginFrameSourceWebView::GetInstance()->inside_begin_frame());
  793. }
  794. bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas, bool software_canvas) {
  795. DCHECK(compositor_);
  796. return compositor_->DemandDrawSw(canvas, software_canvas);
  797. }
  798. std::string BrowserViewRenderer::ToString() const {
  799. std::string str;
  800. base::StringAppendF(&str, "is_paused: %d ", is_paused_);
  801. base::StringAppendF(&str, "view_visible: %d ", view_visible_);
  802. base::StringAppendF(&str, "window_visible: %d ", window_visible_);
  803. base::StringAppendF(&str, "dip_scale: %f ", dip_scale_);
  804. base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_);
  805. base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str());
  806. base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_);
  807. base::StringAppendF(&str,
  808. "global visible rect: %s ",
  809. last_on_draw_global_visible_rect_.ToString().c_str());
  810. base::StringAppendF(&str, "scroll_offset_unscaled: %s ",
  811. scroll_offset_unscaled_.ToString().c_str());
  812. base::StringAppendF(&str,
  813. "overscroll_rounding_error_: %s ",
  814. overscroll_rounding_error_.ToString().c_str());
  815. base::StringAppendF(
  816. &str, "on_new_picture_enable: %d ", on_new_picture_enable_);
  817. base::StringAppendF(&str, "clear_view: %d ", clear_view_);
  818. return str;
  819. }
  820. } // namespace android_webview