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, &params);
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