1 // Copyright (c) 2012 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 "content/browser/renderer_host/compositor_impl_android.h"
6
7 #include <android/bitmap.h>
8 #include <android/native_window_jni.h>
9 #include <stdint.h>
10
11 #include <string>
12 #include <unordered_set>
13 #include <utility>
14 #include <vector>
15
16 #include "base/android/application_status_listener.h"
17 #include "base/android/jni_android.h"
18 #include "base/android/scoped_java_ref.h"
19 #include "base/auto_reset.h"
20 #include "base/bind.h"
21 #include "base/command_line.h"
22 #include "base/lazy_instance.h"
23 #include "base/logging.h"
24 #include "base/memory/weak_ptr.h"
25 #include "base/metrics/histogram_macros.h"
26 #include "base/single_thread_task_runner.h"
27 #include "base/synchronization/lock.h"
28 #include "base/threading/simple_thread.h"
29 #include "base/threading/thread.h"
30 #include "base/threading/thread_checker.h"
31 #include "base/threading/thread_task_runner_handle.h"
32 #include "cc/animation/animation_host.h"
33 #include "cc/base/switches.h"
34 #include "cc/input/input_handler.h"
35 #include "cc/layers/layer.h"
36 #include "cc/metrics/begin_main_frame_metrics.h"
37 #include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
38 #include "cc/resources/ui_resource_manager.h"
39 #include "cc/trees/layer_tree_host.h"
40 #include "cc/trees/layer_tree_settings.h"
41 #include "components/viz/common/features.h"
42 #include "components/viz/common/gpu/context_provider.h"
43 #include "components/viz/common/quads/compositor_frame.h"
44 #include "components/viz/common/surfaces/local_surface_id.h"
45 #include "components/viz/common/viz_utils.h"
46 #include "components/viz/host/host_display_client.h"
47 #include "content/browser/compositor/surface_utils.h"
48 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
49 #include "content/browser/gpu/compositor_util.h"
50 #include "content/browser/gpu/gpu_process_host.h"
51 #include "content/browser/renderer_host/compositor_dependencies_android.h"
52 #include "content/browser/renderer_host/render_widget_host_impl.h"
53 #include "content/public/browser/android/compositor.h"
54 #include "content/public/browser/android/compositor_client.h"
55 #include "content/public/browser/browser_thread.h"
56 #include "content/public/common/content_features.h"
57 #include "content/public/common/content_switches.h"
58 #include "content/public/common/gpu_stream_constants.h"
59 #include "gpu/command_buffer/client/context_support.h"
60 #include "gpu/command_buffer/client/gles2_interface.h"
61 #include "gpu/command_buffer/common/swap_buffers_complete_params.h"
62 #include "gpu/command_buffer/common/swap_buffers_flags.h"
63 #include "gpu/ipc/client/command_buffer_proxy_impl.h"
64 #include "gpu/ipc/client/gpu_channel_host.h"
65 #include "gpu/ipc/common/gpu_surface_tracker.h"
66 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
67 #include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
68 #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h"
69 #include "third_party/khronos/GLES2/gl2.h"
70 #include "third_party/khronos/GLES2/gl2ext.h"
71 #include "third_party/skia/include/core/SkMallocPixelRef.h"
72 #include "ui/android/window_android.h"
73 #include "ui/display/display.h"
74 #include "ui/display/display_transform.h"
75 #include "ui/display/screen.h"
76 #include "ui/gfx/ca_layer_params.h"
77 #include "ui/gfx/swap_result.h"
78 #include "ui/latency/latency_tracker.h"
79
80 namespace content {
81
82 namespace {
83
84 static const char* kBrowser = "Browser";
85
86 // NOINLINE to make sure crashes use this for magic signature.
FatalSurfaceFailure()87 NOINLINE void FatalSurfaceFailure() {
88 LOG(FATAL) << "Fatal surface initialization failure";
89 }
90
GetCompositorContextSharedMemoryLimits(gfx::NativeWindow window)91 gpu::SharedMemoryLimits GetCompositorContextSharedMemoryLimits(
92 gfx::NativeWindow window) {
93 const gfx::Size screen_size = display::Screen::GetScreen()
94 ->GetDisplayNearestWindow(window)
95 .GetSizeInPixel();
96 return gpu::SharedMemoryLimits::ForDisplayCompositor(screen_size);
97 }
98
GetCompositorContextAttributes(const gfx::ColorSpace & display_color_space,bool requires_alpha_channel)99 gpu::ContextCreationAttribs GetCompositorContextAttributes(
100 const gfx::ColorSpace& display_color_space,
101 bool requires_alpha_channel) {
102 // This is used for the browser compositor (offscreen) and for the display
103 // compositor (onscreen), so ask for capabilities needed by either one.
104 // The default framebuffer for an offscreen context is not used, so it does
105 // not need alpha, stencil, depth, antialiasing. The display compositor does
106 // not use these things either, except for alpha when it has a transparent
107 // background.
108 gpu::ContextCreationAttribs attributes;
109 attributes.alpha_size = -1;
110 attributes.stencil_size = 0;
111 attributes.depth_size = 0;
112 attributes.samples = 0;
113 attributes.sample_buffers = 0;
114 attributes.bind_generates_resource = false;
115 if (display_color_space == gfx::ColorSpace::CreateSRGB()) {
116 attributes.color_space = gpu::COLOR_SPACE_SRGB;
117 } else if (display_color_space == gfx::ColorSpace::CreateDisplayP3D65()) {
118 attributes.color_space = gpu::COLOR_SPACE_DISPLAY_P3;
119 } else {
120 // We don't support HDR on Android yet, but when we do, this function should
121 // be updated to support it.
122 DCHECK(!display_color_space.IsHDR());
123
124 attributes.color_space = gpu::COLOR_SPACE_UNSPECIFIED;
125 DLOG(ERROR) << "Android color space is neither sRGB nor P3, output color "
126 "will be incorrect.";
127 }
128
129 if (requires_alpha_channel) {
130 attributes.alpha_size = 8;
131 } else if (viz::PreferRGB565ResourcesForDisplay()) {
132 // In this case we prefer to use RGB565 format instead of RGBA8888 if
133 // possible.
134 // TODO(danakj): CommandBufferStub constructor checks for alpha == 0
135 // in order to enable 565, but it should avoid using 565 when -1s are
136 // specified
137 // (IOW check that a <= 0 && rgb > 0 && rgb <= 565) then alpha should be
138 // -1.
139 // TODO(liberato): This condition is memorized in ComositorView.java, to
140 // avoid using two surfaces temporarily during alpha <-> no alpha
141 // transitions. If these mismatch, then we risk a power regression if the
142 // SurfaceView is not marked as eOpaque (FORMAT_OPAQUE), and we have an
143 // EGL surface with an alpha channel. SurfaceFlinger needs at least one of
144 // those hints to optimize out alpha blending.
145 attributes.alpha_size = 0;
146 attributes.red_size = 5;
147 attributes.green_size = 6;
148 attributes.blue_size = 5;
149 }
150
151 attributes.enable_swap_timestamps_if_supported = true;
152
153 return attributes;
154 }
155
CreateContextProviderAfterGpuChannelEstablished(gpu::SurfaceHandle handle,gpu::ContextCreationAttribs attributes,gpu::SharedMemoryLimits shared_memory_limits,Compositor::ContextProviderCallback callback,scoped_refptr<gpu::GpuChannelHost> gpu_channel_host)156 void CreateContextProviderAfterGpuChannelEstablished(
157 gpu::SurfaceHandle handle,
158 gpu::ContextCreationAttribs attributes,
159 gpu::SharedMemoryLimits shared_memory_limits,
160 Compositor::ContextProviderCallback callback,
161 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
162 if (!gpu_channel_host) {
163 std::move(callback).Run(nullptr);
164 return;
165 }
166
167 gpu::GpuChannelEstablishFactory* factory =
168 BrowserGpuChannelHostFactory::instance();
169
170 int32_t stream_id = kGpuStreamIdDefault;
171 gpu::SchedulingPriority stream_priority = kGpuStreamPriorityUI;
172
173 constexpr bool automatic_flushes = false;
174 constexpr bool support_locking = false;
175 constexpr bool support_grcontext = false;
176
177 auto context_provider =
178 base::MakeRefCounted<viz::ContextProviderCommandBuffer>(
179 std::move(gpu_channel_host), factory->GetGpuMemoryBufferManager(),
180 stream_id, stream_priority, handle,
181 GURL(std::string("chrome://gpu/Compositor::CreateContextProvider")),
182 automatic_flushes, support_locking, support_grcontext,
183 shared_memory_limits, attributes,
184 viz::command_buffer_metrics::ContextType::UNKNOWN);
185 std::move(callback).Run(std::move(context_provider));
186 }
187
188 static bool g_initialized = false;
189
190 } // anonymous namespace
191
192 // An implementation of HostDisplayClient which handles swap callbacks.
193 class CompositorImpl::AndroidHostDisplayClient : public viz::HostDisplayClient {
194 public:
AndroidHostDisplayClient(CompositorImpl * compositor)195 explicit AndroidHostDisplayClient(CompositorImpl* compositor)
196 : HostDisplayClient(gfx::kNullAcceleratedWidget),
197 compositor_(compositor) {}
198
199 // viz::mojom::DisplayClient implementation:
DidCompleteSwapWithSize(const gfx::Size & pixel_size)200 void DidCompleteSwapWithSize(const gfx::Size& pixel_size) override {
201 compositor_->DidSwapBuffers(pixel_size);
202 }
OnContextCreationResult(gpu::ContextResult context_result)203 void OnContextCreationResult(gpu::ContextResult context_result) override {
204 compositor_->OnContextCreationResult(context_result);
205 }
SetWideColorEnabled(bool enabled)206 void SetWideColorEnabled(bool enabled) override {
207 // TODO(cblume): Add support for multiple compositors.
208 // If one goes wide, all should go wide.
209 if (compositor_->root_window_)
210 compositor_->root_window_->SetWideColorEnabled(enabled);
211 }
SetPreferredRefreshRate(float refresh_rate)212 void SetPreferredRefreshRate(float refresh_rate) override {
213 if (compositor_->root_window_)
214 compositor_->root_window_->SetPreferredRefreshRate(refresh_rate);
215 }
216
217 private:
218 CompositorImpl* compositor_;
219 };
220
221 class CompositorImpl::ScopedCachedBackBuffer {
222 public:
ScopedCachedBackBuffer(const viz::FrameSinkId & root_sink_id)223 ScopedCachedBackBuffer(const viz::FrameSinkId& root_sink_id) {
224 cache_id_ =
225 GetHostFrameSinkManager()->CacheBackBufferForRootSink(root_sink_id);
226 }
~ScopedCachedBackBuffer()227 ~ScopedCachedBackBuffer() {
228 GetHostFrameSinkManager()->EvictCachedBackBuffer(cache_id_);
229 }
230
231 private:
232 uint32_t cache_id_;
233 };
234
235 class CompositorImpl::ReadbackRefImpl
236 : public ui::WindowAndroidCompositor::ReadbackRef {
237 public:
238 explicit ReadbackRefImpl(base::WeakPtr<CompositorImpl> weakptr);
239 ~ReadbackRefImpl() override;
240
241 private:
242 base::WeakPtr<CompositorImpl> compositor_weakptr_;
243 };
244
ReadbackRefImpl(base::WeakPtr<CompositorImpl> weakptr)245 CompositorImpl::ReadbackRefImpl::ReadbackRefImpl(
246 base::WeakPtr<CompositorImpl> weakptr)
247 : compositor_weakptr_(weakptr) {}
248
~ReadbackRefImpl()249 CompositorImpl::ReadbackRefImpl::~ReadbackRefImpl() {
250 DCHECK_CURRENTLY_ON(BrowserThread::UI);
251 if (compositor_weakptr_)
252 compositor_weakptr_->DecrementPendingReadbacks();
253 }
254
255 // static
Create(CompositorClient * client,gfx::NativeWindow root_window)256 Compositor* Compositor::Create(CompositorClient* client,
257 gfx::NativeWindow root_window) {
258 return client ? new CompositorImpl(client, root_window) : nullptr;
259 }
260
261 // static
Initialize()262 void Compositor::Initialize() {
263 DCHECK(!CompositorImpl::IsInitialized());
264 g_initialized = true;
265 }
266
267 // static
CreateContextProvider(gpu::SurfaceHandle handle,gpu::ContextCreationAttribs attributes,gpu::SharedMemoryLimits shared_memory_limits,ContextProviderCallback callback)268 void Compositor::CreateContextProvider(
269 gpu::SurfaceHandle handle,
270 gpu::ContextCreationAttribs attributes,
271 gpu::SharedMemoryLimits shared_memory_limits,
272 ContextProviderCallback callback) {
273 DCHECK_CURRENTLY_ON(BrowserThread::UI);
274 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
275 base::BindOnce(&CreateContextProviderAfterGpuChannelEstablished, handle,
276 attributes, shared_memory_limits, std::move(callback)));
277 }
278
279 // static
IsInitialized()280 bool CompositorImpl::IsInitialized() {
281 return g_initialized;
282 }
283
CompositorImpl(CompositorClient * client,gfx::NativeWindow root_window)284 CompositorImpl::CompositorImpl(CompositorClient* client,
285 gfx::NativeWindow root_window)
286 : frame_sink_id_(AllocateFrameSinkId()),
287 resource_manager_(root_window),
288 window_(nullptr),
289 surface_handle_(gpu::kNullSurfaceHandle),
290 client_(client),
291 needs_animate_(false),
292 pending_frames_(0U),
293 layer_tree_frame_sink_request_pending_(false) {
294 DCHECK(client);
295
296 SetRootWindow(root_window);
297
298 // Listen to display density change events and update painted device scale
299 // factor accordingly.
300 display::Screen::GetScreen()->AddObserver(this);
301 }
302
~CompositorImpl()303 CompositorImpl::~CompositorImpl() {
304 display::Screen::GetScreen()->RemoveObserver(this);
305 DetachRootWindow();
306 // Clean-up any surface references.
307 SetSurface(nullptr, false);
308
309 BrowserGpuChannelHostFactory::instance()->MaybeCloseChannel();
310 }
311
DetachRootWindow()312 void CompositorImpl::DetachRootWindow() {
313 root_window_->DetachCompositor();
314 root_window_->SetLayer(nullptr);
315 }
316
GetUIResourceProvider()317 ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() {
318 return *this;
319 }
320
GetResourceManager()321 ui::ResourceManager& CompositorImpl::GetResourceManager() {
322 return resource_manager_;
323 }
324
SetRootWindow(gfx::NativeWindow root_window)325 void CompositorImpl::SetRootWindow(gfx::NativeWindow root_window) {
326 DCHECK(root_window);
327 DCHECK(!root_window->GetLayer());
328
329 // TODO(mthiesse): Right now we only support swapping the root window without
330 // a surface. If we want to support swapping with a surface we need to
331 // handle visibility, swapping begin frame sources, etc.
332 // These checks ensure we have no begin frame source, and that we don't need
333 // to register one on the new window.
334 DCHECK(!window_);
335
336 scoped_refptr<cc::Layer> root_layer;
337 if (root_window_) {
338 root_layer = root_window_->GetLayer();
339 DetachRootWindow();
340 }
341
342 root_window_ = root_window;
343 if (base::FeatureList::IsEnabled(features::kForce60HzRefreshRate))
344 root_window_->SetForce60HzRefreshRate();
345 root_window_->SetLayer(root_layer ? root_layer : cc::Layer::Create());
346 root_window_->GetLayer()->SetBounds(size_);
347 root_window->AttachCompositor(this);
348 if (!host_) {
349 CreateLayerTreeHost();
350 resource_manager_.Init(host_->GetUIResourceManager());
351 }
352 host_->SetRootLayer(root_window_->GetLayer());
353 host_->SetViewportRectAndScale(gfx::Rect(size_), root_window_->GetDipScale(),
354 GenerateLocalSurfaceId());
355 }
356
SetRootLayer(scoped_refptr<cc::Layer> root_layer)357 void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
358 if (subroot_layer_.get()) {
359 subroot_layer_->RemoveFromParent();
360 subroot_layer_ = nullptr;
361 }
362 if (root_layer.get() && root_window_->GetLayer()) {
363 subroot_layer_ = root_window_->GetLayer();
364 subroot_layer_->AddChild(root_layer);
365 }
366 }
367
SetSurface(const base::android::JavaRef<jobject> & surface,bool can_be_used_with_surface_control)368 void CompositorImpl::SetSurface(const base::android::JavaRef<jobject>& surface,
369 bool can_be_used_with_surface_control) {
370 can_be_used_with_surface_control &=
371 !root_window_->ApplyDisableSurfaceControlWorkaround();
372
373 JNIEnv* env = base::android::AttachCurrentThread();
374 gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get();
375
376 if (window_) {
377 // Shut down GL context before unregistering surface.
378 SetVisible(false);
379 tracker->RemoveSurface(surface_handle_);
380 ANativeWindow_release(window_);
381 window_ = nullptr;
382 surface_handle_ = gpu::kNullSurfaceHandle;
383 }
384
385 ANativeWindow* window = nullptr;
386 if (surface) {
387 // Note: This ensures that any local references used by
388 // ANativeWindow_fromSurface are released immediately. This is needed as a
389 // workaround for https://code.google.com/p/android/issues/detail?id=68174
390 base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env);
391 window = ANativeWindow_fromSurface(env, surface.obj());
392 }
393
394 if (window) {
395 window_ = window;
396 ANativeWindow_acquire(window);
397 // Register first, SetVisible() might create a LayerTreeFrameSink.
398 surface_handle_ = tracker->AddSurfaceForNativeWidget(
399 gpu::GpuSurfaceTracker::SurfaceRecord(
400 window, surface, can_be_used_with_surface_control));
401 SetVisible(true);
402 ANativeWindow_release(window);
403 }
404 }
405
SetBackgroundColor(int color)406 void CompositorImpl::SetBackgroundColor(int color) {
407 DCHECK(host_);
408 host_->set_background_color(color);
409 }
410
CreateLayerTreeHost()411 void CompositorImpl::CreateLayerTreeHost() {
412 DCHECK(!host_);
413
414 cc::LayerTreeSettings settings;
415 settings.use_zero_copy = true;
416
417 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
418 settings.initial_debug_state.SetRecordRenderingStats(
419 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
420 settings.initial_debug_state.show_fps_counter =
421 command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
422 if (command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders))
423 settings.initial_debug_state.show_debug_borders.set();
424 settings.single_thread_proxy_scheduler = true;
425 settings.use_painted_device_scale_factor = true;
426 // TODO(crbug.com/933846): LatencyRecovery is causing jank on Android. Disable
427 // for now, with a plan to disable more widely once viz launches.
428 settings.enable_impl_latency_recovery = false;
429 settings.enable_main_latency_recovery = false;
430
431 animation_host_ = cc::AnimationHost::CreateMainInstance();
432
433 cc::LayerTreeHost::InitParams params;
434 params.client = this;
435 params.task_graph_runner =
436 CompositorDependenciesAndroid::Get().GetTaskGraphRunner();
437 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
438 params.settings = &settings;
439 params.mutator_host = animation_host_.get();
440 host_ = cc::LayerTreeHost::CreateSingleThreaded(this, std::move(params));
441 DCHECK(!host_->IsVisible());
442 host_->SetViewportRectAndScale(gfx::Rect(size_), root_window_->GetDipScale(),
443 GenerateLocalSurfaceId());
444 const auto& display_props =
445 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window_);
446 host_->set_display_transform_hint(
447 display::DisplayRotationToOverlayTransform(display_props.rotation()));
448
449 if (needs_animate_)
450 host_->SetNeedsAnimate();
451 }
452
SetVisible(bool visible)453 void CompositorImpl::SetVisible(bool visible) {
454 TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible);
455
456 if (!visible) {
457 DCHECK(host_->IsVisible());
458 // Tear down the display first, synchronously completing any pending
459 // draws/readbacks if poosible.
460 TearDownDisplayAndUnregisterRootFrameSink();
461 // Hide the LayerTreeHost and release its frame sink.
462 host_->SetVisible(false);
463 host_->ReleaseLayerTreeFrameSink();
464 pending_frames_ = 0;
465
466 // Notify CompositorDependenciesAndroid of visibility changes last, to
467 // ensure that we don't disable the GPU watchdog until sync IPCs above are
468 // completed.
469 CompositorDependenciesAndroid::Get().OnCompositorHidden(this);
470 } else {
471 DCHECK(!host_->IsVisible());
472 CompositorDependenciesAndroid::Get().OnCompositorVisible(this);
473 RegisterRootFrameSink();
474 host_->SetVisible(true);
475 has_submitted_frame_since_became_visible_ = false;
476 if (layer_tree_frame_sink_request_pending_)
477 HandlePendingLayerTreeFrameSinkRequest();
478 }
479 }
480
TearDownDisplayAndUnregisterRootFrameSink()481 void CompositorImpl::TearDownDisplayAndUnregisterRootFrameSink() {
482 // Make a best effort to try to complete pending readbacks.
483 // TODO(crbug.com/637035): Consider doing this in a better way,
484 // ideally with the guarantee of readbacks completing.
485 if (display_private_ && pending_readbacks_) {
486 // Note that while this is not a Sync IPC, the call to
487 // InvalidateFrameSinkId below will end up triggering a sync call to
488 // FrameSinkManager::DestroyCompositorFrameSink, as this is the root
489 // frame sink. Because |display_private_| is an associated remote to
490 // FrameSinkManager, this subsequent sync call will ensure ordered
491 // execution of this call.
492 display_private_->ForceImmediateDrawAndSwapIfPossible();
493 }
494 GetHostFrameSinkManager()->InvalidateFrameSinkId(frame_sink_id_);
495 display_private_.reset();
496 }
497
RegisterRootFrameSink()498 void CompositorImpl::RegisterRootFrameSink() {
499 GetHostFrameSinkManager()->RegisterFrameSinkId(
500 frame_sink_id_, this, viz::ReportFirstSurfaceActivation::kNo);
501 GetHostFrameSinkManager()->SetFrameSinkDebugLabel(frame_sink_id_,
502 "CompositorImpl");
503 for (auto& frame_sink_id : pending_child_frame_sink_ids_)
504 AddChildFrameSink(frame_sink_id);
505 pending_child_frame_sink_ids_.clear();
506 }
507
SetWindowBounds(const gfx::Size & size)508 void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
509 if (size_ == size)
510 return;
511
512 size_ = size;
513 if (host_) {
514 // TODO(ccameron): Ensure a valid LocalSurfaceId here.
515 host_->SetViewportRectAndScale(gfx::Rect(size_),
516 root_window_->GetDipScale(),
517 GenerateLocalSurfaceId());
518 }
519
520 if (display_private_)
521 display_private_->Resize(size);
522
523 root_window_->GetLayer()->SetBounds(size);
524 }
525
GetWindowBounds()526 const gfx::Size& CompositorImpl::GetWindowBounds() {
527 return size_;
528 }
529
SetRequiresAlphaChannel(bool flag)530 void CompositorImpl::SetRequiresAlphaChannel(bool flag) {
531 requires_alpha_channel_ = flag;
532 }
533
SetNeedsComposite()534 void CompositorImpl::SetNeedsComposite() {
535 if (!host_->IsVisible())
536 return;
537 TRACE_EVENT0("compositor", "Compositor::SetNeedsComposite");
538 host_->SetNeedsAnimate();
539 }
540
SetNeedsRedraw()541 void CompositorImpl::SetNeedsRedraw() {
542 host_->SetNeedsRedrawRect(host_->device_viewport_rect());
543 }
544
DidUpdateLayers()545 void CompositorImpl::DidUpdateLayers() {
546 // Dump property trees and layers if run with:
547 // --vmodule=compositor_impl_android=3
548 VLOG(3) << "After updating layers:\n"
549 << "property trees:\n"
550 << host_->property_trees()->ToString() << "\n"
551 << "cc::Layers:\n"
552 << host_->LayersAsString();
553 }
554
BeginMainFrame(const viz::BeginFrameArgs & args)555 void CompositorImpl::BeginMainFrame(const viz::BeginFrameArgs& args) {
556 latest_frame_time_ = args.frame_time;
557 }
558
UpdateLayerTreeHost()559 void CompositorImpl::UpdateLayerTreeHost() {
560 DCHECK(!latest_frame_time_.is_null());
561 client_->UpdateLayerTreeHost();
562 if (needs_animate_) {
563 needs_animate_ = false;
564 root_window_->Animate(latest_frame_time_);
565 }
566 }
567
RequestNewLayerTreeFrameSink()568 void CompositorImpl::RequestNewLayerTreeFrameSink() {
569 DCHECK(!layer_tree_frame_sink_request_pending_)
570 << "LayerTreeFrameSink request is already pending?";
571
572 layer_tree_frame_sink_request_pending_ = true;
573 HandlePendingLayerTreeFrameSinkRequest();
574 }
575
DidInitializeLayerTreeFrameSink()576 void CompositorImpl::DidInitializeLayerTreeFrameSink() {
577 layer_tree_frame_sink_request_pending_ = false;
578 }
579
DidFailToInitializeLayerTreeFrameSink()580 void CompositorImpl::DidFailToInitializeLayerTreeFrameSink() {
581 layer_tree_frame_sink_request_pending_ = false;
582 base::ThreadTaskRunnerHandle::Get()->PostTask(
583 FROM_HERE, base::BindOnce(&CompositorImpl::RequestNewLayerTreeFrameSink,
584 weak_factory_.GetWeakPtr()));
585 }
586
HandlePendingLayerTreeFrameSinkRequest()587 void CompositorImpl::HandlePendingLayerTreeFrameSinkRequest() {
588 DCHECK(layer_tree_frame_sink_request_pending_);
589
590 // We might have been made invisible now.
591 if (!host_->IsVisible())
592 return;
593
594 DCHECK(surface_handle_ != gpu::kNullSurfaceHandle);
595 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(base::BindOnce(
596 &CompositorImpl::OnGpuChannelEstablished, weak_factory_.GetWeakPtr()));
597 }
598
OnGpuChannelEstablished(scoped_refptr<gpu::GpuChannelHost> gpu_channel_host)599 void CompositorImpl::OnGpuChannelEstablished(
600 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
601 // At this point we know we have a valid GPU process, establish our viz
602 // connection if needed.
603 CompositorDependenciesAndroid::Get().TryEstablishVizConnectionIfNeeded();
604
605 // We might end up queing multiple GpuChannel requests for the same
606 // LayerTreeFrameSink request as the visibility of the compositor changes, so
607 // the LayerTreeFrameSink request could have been handled already.
608 if (!layer_tree_frame_sink_request_pending_)
609 return;
610
611 if (!gpu_channel_host) {
612 HandlePendingLayerTreeFrameSinkRequest();
613 return;
614 }
615
616 // We don't need the context anymore if we are invisible.
617 if (!host_->IsVisible()) {
618 return;
619 }
620
621 DCHECK(window_);
622 DCHECK_NE(surface_handle_, gpu::kNullSurfaceHandle);
623
624 gpu::GpuChannelEstablishFactory* factory =
625 BrowserGpuChannelHostFactory::instance();
626
627 int32_t stream_id = kGpuStreamIdDefault;
628 gpu::SchedulingPriority stream_priority = kGpuStreamPriorityUI;
629
630 constexpr bool support_locking = false;
631 constexpr bool automatic_flushes = false;
632 constexpr bool support_grcontext = true;
633 display_color_spaces_ = display::Screen::GetScreen()
634 ->GetDisplayNearestWindow(root_window_)
635 .color_spaces();
636
637 auto context_provider =
638 base::MakeRefCounted<viz::ContextProviderCommandBuffer>(
639 std::move(gpu_channel_host), factory->GetGpuMemoryBufferManager(),
640 stream_id, stream_priority, gpu::kNullSurfaceHandle,
641 GURL(std::string("chrome://gpu/CompositorImpl::") +
642 std::string("CompositorContextProvider")),
643 automatic_flushes, support_locking, support_grcontext,
644 GetCompositorContextSharedMemoryLimits(root_window_),
645 GetCompositorContextAttributes(
646 display_color_spaces_.GetRasterColorSpace(),
647 requires_alpha_channel_),
648 viz::command_buffer_metrics::ContextType::BROWSER_COMPOSITOR);
649 auto result = context_provider->BindToCurrentThread();
650
651 if (result == gpu::ContextResult::kFatalFailure) {
652 LOG(FATAL) << "Fatal failure in creating offscreen context";
653 }
654
655 if (result != gpu::ContextResult::kSuccess) {
656 HandlePendingLayerTreeFrameSinkRequest();
657 return;
658 }
659
660 InitializeVizLayerTreeFrameSink(std::move(context_provider));
661 }
662
DidSwapBuffers(const gfx::Size & swap_size)663 void CompositorImpl::DidSwapBuffers(const gfx::Size& swap_size) {
664 client_->DidSwapBuffers(swap_size);
665
666 if (swap_completed_with_size_for_testing_)
667 swap_completed_with_size_for_testing_.Run(swap_size);
668 }
669
CreateUIResource(cc::UIResourceClient * client)670 cc::UIResourceId CompositorImpl::CreateUIResource(
671 cc::UIResourceClient* client) {
672 TRACE_EVENT0("compositor", "CompositorImpl::CreateUIResource");
673 return host_->GetUIResourceManager()->CreateUIResource(client);
674 }
675
DeleteUIResource(cc::UIResourceId resource_id)676 void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) {
677 TRACE_EVENT0("compositor", "CompositorImpl::DeleteUIResource");
678 host_->GetUIResourceManager()->DeleteUIResource(resource_id);
679 }
680
SupportsETC1NonPowerOfTwo() const681 bool CompositorImpl::SupportsETC1NonPowerOfTwo() const {
682 return gpu_capabilities_.texture_format_etc1_npot;
683 }
684
DidSubmitCompositorFrame()685 void CompositorImpl::DidSubmitCompositorFrame() {
686 TRACE_EVENT0("compositor", "CompositorImpl::DidSubmitCompositorFrame");
687 pending_frames_++;
688 has_submitted_frame_since_became_visible_ = true;
689 }
690
DidReceiveCompositorFrameAck()691 void CompositorImpl::DidReceiveCompositorFrameAck() {
692 TRACE_EVENT0("compositor", "CompositorImpl::DidReceiveCompositorFrameAck");
693 DCHECK_GT(pending_frames_, 0U);
694 pending_frames_--;
695 client_->DidSwapFrame(pending_frames_);
696 }
697
DidLoseLayerTreeFrameSink()698 void CompositorImpl::DidLoseLayerTreeFrameSink() {
699 TRACE_EVENT0("compositor", "CompositorImpl::DidLoseLayerTreeFrameSink");
700 client_->DidSwapFrame(0);
701 }
702
DidCommit(base::TimeTicks)703 void CompositorImpl::DidCommit(base::TimeTicks) {
704 root_window_->OnCompositingDidCommit();
705 }
706
707 std::unique_ptr<cc::BeginMainFrameMetrics>
GetBeginMainFrameMetrics()708 CompositorImpl::GetBeginMainFrameMetrics() {
709 return nullptr;
710 }
711
712 std::unique_ptr<ui::WindowAndroidCompositor::ReadbackRef>
TakeReadbackRef()713 CompositorImpl::TakeReadbackRef() {
714 ++pending_readbacks_;
715 return std::make_unique<ReadbackRefImpl>(weak_factory_.GetWeakPtr());
716 }
717
RequestCopyOfOutputOnRootLayer(std::unique_ptr<viz::CopyOutputRequest> request)718 void CompositorImpl::RequestCopyOfOutputOnRootLayer(
719 std::unique_ptr<viz::CopyOutputRequest> request) {
720 root_window_->GetLayer()->RequestCopyOfOutput(std::move(request));
721 }
722
SetNeedsAnimate()723 void CompositorImpl::SetNeedsAnimate() {
724 needs_animate_ = true;
725 if (!host_->IsVisible())
726 return;
727
728 TRACE_EVENT0("compositor", "Compositor::SetNeedsAnimate");
729 host_->SetNeedsAnimate();
730 }
731
GetFrameSinkId()732 viz::FrameSinkId CompositorImpl::GetFrameSinkId() {
733 return frame_sink_id_;
734 }
735
AddChildFrameSink(const viz::FrameSinkId & frame_sink_id)736 void CompositorImpl::AddChildFrameSink(const viz::FrameSinkId& frame_sink_id) {
737 if (GetHostFrameSinkManager()->IsFrameSinkIdRegistered(frame_sink_id_)) {
738 bool result = GetHostFrameSinkManager()->RegisterFrameSinkHierarchy(
739 frame_sink_id_, frame_sink_id);
740 DCHECK(result);
741 } else {
742 pending_child_frame_sink_ids_.insert(frame_sink_id);
743 }
744 }
745
RemoveChildFrameSink(const viz::FrameSinkId & frame_sink_id)746 void CompositorImpl::RemoveChildFrameSink(
747 const viz::FrameSinkId& frame_sink_id) {
748 auto it = pending_child_frame_sink_ids_.find(frame_sink_id);
749 if (it != pending_child_frame_sink_ids_.end()) {
750 pending_child_frame_sink_ids_.erase(it);
751 return;
752 }
753 GetHostFrameSinkManager()->UnregisterFrameSinkHierarchy(frame_sink_id_,
754 frame_sink_id);
755 }
756
OnDisplayMetricsChanged(const display::Display & display,uint32_t changed_metrics)757 void CompositorImpl::OnDisplayMetricsChanged(const display::Display& display,
758 uint32_t changed_metrics) {
759 if (display.id() != display::Screen::GetScreen()
760 ->GetDisplayNearestWindow(root_window_)
761 .id()) {
762 return;
763 }
764
765 if (changed_metrics & display::DisplayObserver::DisplayMetric::
766 DISPLAY_METRIC_DEVICE_SCALE_FACTOR) {
767 // TODO(ccameron): This is transiently incorrect -- |size_| must be
768 // recalculated here as well. Is the call in SetWindowBounds sufficient?
769 host_->SetViewportRectAndScale(gfx::Rect(size_),
770 root_window_->GetDipScale(),
771 GenerateLocalSurfaceId());
772 }
773
774 if (changed_metrics &
775 display::DisplayObserver::DisplayMetric::DISPLAY_METRIC_ROTATION) {
776 host_->set_display_transform_hint(
777 display::DisplayRotationToOverlayTransform(display.rotation()));
778 }
779 }
780
IsDrawingFirstVisibleFrame() const781 bool CompositorImpl::IsDrawingFirstVisibleFrame() const {
782 return !has_submitted_frame_since_became_visible_;
783 }
784
SetVSyncPaused(bool paused)785 void CompositorImpl::SetVSyncPaused(bool paused) {
786 if (vsync_paused_ == paused)
787 return;
788
789 vsync_paused_ = paused;
790 if (display_private_)
791 display_private_->SetVSyncPaused(paused);
792 }
793
OnUpdateRefreshRate(float refresh_rate)794 void CompositorImpl::OnUpdateRefreshRate(float refresh_rate) {
795 if (display_private_)
796 display_private_->UpdateRefreshRate(refresh_rate);
797 }
798
OnUpdateSupportedRefreshRates(const std::vector<float> & supported_refresh_rates)799 void CompositorImpl::OnUpdateSupportedRefreshRates(
800 const std::vector<float>& supported_refresh_rates) {
801 if (display_private_)
802 display_private_->SetSupportedRefreshRates(supported_refresh_rates);
803 }
804
InitializeVizLayerTreeFrameSink(scoped_refptr<viz::ContextProviderCommandBuffer> context_provider)805 void CompositorImpl::InitializeVizLayerTreeFrameSink(
806 scoped_refptr<viz::ContextProviderCommandBuffer> context_provider) {
807 DCHECK(root_window_);
808
809 pending_frames_ = 0;
810 gpu_capabilities_ = context_provider->ContextCapabilities();
811 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
812 base::ThreadTaskRunnerHandle::Get();
813
814 auto root_params = viz::mojom::RootCompositorFrameSinkParams::New();
815
816 // Android requires swap size notifications.
817 root_params->send_swap_size_notifications = true;
818
819 // Create interfaces for a root CompositorFrameSink.
820 mojo::PendingAssociatedRemote<viz::mojom::CompositorFrameSink> sink_remote;
821 root_params->compositor_frame_sink =
822 sink_remote.InitWithNewEndpointAndPassReceiver();
823 mojo::PendingReceiver<viz::mojom::CompositorFrameSinkClient> client_receiver =
824 root_params->compositor_frame_sink_client
825 .InitWithNewPipeAndPassReceiver();
826 display_private_.reset();
827 root_params->display_private =
828 display_private_.BindNewEndpointAndPassReceiver();
829 display_client_ = std::make_unique<AndroidHostDisplayClient>(this);
830 root_params->display_client = display_client_->GetBoundRemote(task_runner);
831
832 const auto& display_props =
833 display::Screen::GetScreen()->GetDisplayNearestWindow(root_window_);
834
835 viz::RendererSettings renderer_settings;
836 renderer_settings.partial_swap_enabled = true;
837 renderer_settings.allow_antialiasing = false;
838 renderer_settings.highp_threshold_min = 2048;
839 renderer_settings.requires_alpha_channel = requires_alpha_channel_;
840 renderer_settings.initial_screen_size = display_props.GetSizeInPixel();
841 renderer_settings.use_skia_renderer = features::IsUsingSkiaRenderer();
842 renderer_settings.color_space = display_color_spaces_.GetOutputColorSpace(
843 gfx::ContentColorUsage::kHDR, requires_alpha_channel_);
844
845 root_params->frame_sink_id = frame_sink_id_;
846 root_params->widget = surface_handle_;
847 root_params->gpu_compositing = true;
848 root_params->renderer_settings = renderer_settings;
849 root_params->refresh_rate = root_window_->GetRefreshRate();
850
851 GetHostFrameSinkManager()->CreateRootCompositorFrameSink(
852 std::move(root_params));
853
854 // Create LayerTreeFrameSink with the browser end of CompositorFrameSink.
855 cc::mojo_embedder::AsyncLayerTreeFrameSink::InitParams params;
856 params.compositor_task_runner = task_runner;
857 params.gpu_memory_buffer_manager =
858 BrowserGpuChannelHostFactory::instance()->GetGpuMemoryBufferManager();
859 params.pipes.compositor_frame_sink_associated_remote = std::move(sink_remote);
860 params.pipes.client_receiver = std::move(client_receiver);
861 params.client_name = kBrowser;
862 auto layer_tree_frame_sink =
863 std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
864 std::move(context_provider), nullptr, ¶ms);
865 host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
866 display_private_->SetDisplayVisible(true);
867 display_private_->Resize(size_);
868 display_private_->SetDisplayColorSpaces(display_color_spaces_);
869 display_private_->SetVSyncPaused(vsync_paused_);
870 display_private_->SetSupportedRefreshRates(
871 root_window_->GetSupportedRefreshRates());
872 }
873
GenerateLocalSurfaceId()874 viz::LocalSurfaceId CompositorImpl::GenerateLocalSurfaceId() {
875 local_surface_id_allocator_.GenerateId();
876 return local_surface_id_allocator_.GetCurrentLocalSurfaceId();
877 }
878
OnContextCreationResult(gpu::ContextResult context_result)879 void CompositorImpl::OnContextCreationResult(
880 gpu::ContextResult context_result) {
881 if (!gpu::IsFatalOrSurfaceFailure(context_result)) {
882 num_of_consecutive_surface_failures_ = 0u;
883 return;
884 }
885
886 OnFatalOrSurfaceContextCreationFailure(context_result);
887 }
888
OnFatalOrSurfaceContextCreationFailure(gpu::ContextResult context_result)889 void CompositorImpl::OnFatalOrSurfaceContextCreationFailure(
890 gpu::ContextResult context_result) {
891 DCHECK(gpu::IsFatalOrSurfaceFailure(context_result));
892 LOG_IF(FATAL, context_result == gpu::ContextResult::kFatalFailure)
893 << "Fatal error making Gpu context";
894
895 constexpr size_t kMaxConsecutiveSurfaceFailures = 10u;
896 if (++num_of_consecutive_surface_failures_ > kMaxConsecutiveSurfaceFailures)
897 FatalSurfaceFailure();
898
899 if (context_result == gpu::ContextResult::kSurfaceFailure) {
900 SetSurface(nullptr, false);
901 client_->RecreateSurface();
902 }
903 }
904
OnFirstSurfaceActivation(const viz::SurfaceInfo & info)905 void CompositorImpl::OnFirstSurfaceActivation(const viz::SurfaceInfo& info) {
906 NOTREACHED();
907 }
908
CacheBackBufferForCurrentSurface()909 void CompositorImpl::CacheBackBufferForCurrentSurface() {
910 if (window_ && display_private_) {
911 cached_back_buffer_ =
912 std::make_unique<ScopedCachedBackBuffer>(frame_sink_id_);
913 }
914 }
915
EvictCachedBackBuffer()916 void CompositorImpl::EvictCachedBackBuffer() {
917 cached_back_buffer_.reset();
918 }
919
RequestPresentationTimeForNextFrame(PresentationTimeCallback callback)920 void CompositorImpl::RequestPresentationTimeForNextFrame(
921 PresentationTimeCallback callback) {
922 host_->RequestPresentationTimeForNextFrame(std::move(callback));
923 }
924
DecrementPendingReadbacks()925 void CompositorImpl::DecrementPendingReadbacks() {
926 DCHECK_GT(pending_readbacks_, 0u);
927 --pending_readbacks_;
928 }
929
930 } // namespace content
931