[go: nahoru, domu]

blob: 1fe7626b5a570ffb896376493f8d3c6235e83db5 [file] [log] [blame]
sievers@chromium.org16383382012-09-05 23:57:261// 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
dtrainor@chromium.org92fa4d292012-10-16 20:31:517#include <android/bitmap.h>
sievers@chromium.orgfd7a8572012-09-18 19:32:058#include <android/native_window_jni.h>
avib533f5d2015-12-25 03:11:159#include <stdint.h>
danakj15ec5242016-06-15 22:13:3710#include <unordered_set>
dchenga45aa7d62015-12-30 01:56:1211#include <utility>
sievers@chromium.orgfd7a8572012-09-18 19:32:0512
sievers@chromium.orgccf558a2013-03-07 03:58:1813#include "base/android/jni_android.h"
14#include "base/android/scoped_java_ref.h"
sievers148fedf2015-10-02 00:12:0415#include "base/auto_reset.h"
sievers@chromium.org16383382012-09-05 23:57:2616#include "base/bind.h"
mkosiba@chromium.org88dfc7c2012-10-01 16:25:1317#include "base/command_line.h"
reveman@chromium.org354c448d2014-04-06 04:29:0118#include "base/containers/hash_tables.h"
aelias@chromium.org8f3ffdc62012-11-15 05:28:2619#include "base/lazy_instance.h"
sievers@chromium.org16383382012-09-05 23:57:2620#include "base/logging.h"
dcheng92ae1412016-04-09 02:52:2421#include "base/memory/ptr_util.h"
aeliasd880a3d2014-08-26 00:46:2022#include "base/memory/weak_ptr.h"
danakj@chromium.org810d40b72013-06-20 18:26:1523#include "base/single_thread_task_runner.h"
sievers@chromium.orgccf558a2013-03-07 03:58:1824#include "base/synchronization/lock.h"
jinsukkim2cd51092016-02-17 02:14:0725#include "base/sys_info.h"
reveman34b7a1522015-03-23 20:27:4726#include "base/threading/simple_thread.h"
scottmg@chromium.org14b2f172013-06-15 15:25:1427#include "base/threading/thread.h"
reveman@chromium.org82efc0d2014-03-31 06:45:0228#include "base/threading/thread_checker.h"
gab30f26df2016-05-11 19:37:5529#include "base/threading/thread_task_runner_handle.h"
loysoab32ee72016-06-08 03:33:1830#include "cc/animation/animation_host.h"
ernstm@chromium.org58e2ad852014-02-21 23:57:0331#include "cc/base/switches.h"
jamesr@chromium.org3052b10f2013-03-18 07:41:2132#include "cc/input/input_handler.h"
jamesr@chromium.orgcc3cfaa2013-03-18 09:05:5233#include "cc/layers/layer.h"
feng@chromium.orgdbafd6c2013-07-12 03:30:3334#include "cc/output/compositor_frame.h"
jamesr@chromium.org7f0d825f2013-03-18 07:24:3035#include "cc/output/context_provider.h"
36#include "cc/output/output_surface.h"
sieversdf212b32014-10-09 20:40:1437#include "cc/output/output_surface_client.h"
kylechar5344b39e2016-10-06 23:51:1938#include "cc/output/output_surface_frame.h"
danakj8eb035c02016-06-17 22:41:3239#include "cc/output/texture_mailbox_deleter.h"
sohan.jyoti2986bd482016-05-09 17:44:1240#include "cc/output/vulkan_in_process_context_provider.h"
ericrk4e3aa5a2015-12-01 03:53:5641#include "cc/raster/single_thread_task_graph_runner.h"
khushalsagar8ec07402016-09-10 03:13:1942#include "cc/resources/ui_resource_manager.h"
danakjc7afae52017-06-20 21:12:4143#include "cc/surfaces/direct_layer_tree_frame_sink.h"
danakj324faea2016-06-11 01:39:3144#include "cc/surfaces/display.h"
danakj8eb035c02016-06-17 22:41:3245#include "cc/surfaces/display_scheduler.h"
khushalsagar31690fb2017-02-28 23:23:4846#include "cc/surfaces/frame_sink_id_allocator.h"
khushalsagare0e4486e2017-01-25 03:15:0347#include "cc/trees/layer_tree_host.h"
loysoa6edaaf2015-05-25 03:26:4448#include "cc/trees/layer_tree_settings.h"
kylecharcb5882d2017-06-05 13:41:3449#include "components/viz/host/frame_sink_manager_host.h"
Fady Samuel279f5f02017-06-14 23:23:0050#include "components/viz/service/display_compositor/compositor_overlay_candidate_validator_android.h"
51#include "components/viz/service/display_compositor/gl_helper.h"
52#include "components/viz/service/display_compositor/host_shared_bitmap_manager.h"
53#include "components/viz/service/frame_sinks/mojo_frame_sink_manager.h"
54#include "content/browser/compositor/surface_utils.h"
khushalsagar31690fb2017-02-28 23:23:4855#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
reveman22dd9292014-10-13 20:52:0556#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
jbauman78f9b572014-11-18 06:01:5657#include "content/browser/gpu/compositor_util.h"
sieversdf212b32014-10-09 20:40:1458#include "content/browser/renderer_host/render_widget_host_impl.h"
sunnyps8f9139e2017-05-12 17:53:2559#include "content/common/gpu_stream_constants.h"
loysoa6edaaf2015-05-25 03:26:4460#include "content/public/browser/android/compositor.h"
skyostil@chromium.orgf5f534b2013-07-10 17:59:5061#include "content/public/browser/android/compositor_client.h"
loyso85a000a2015-06-02 01:31:2762#include "content/public/common/content_switches.h"
sieversdf212b32014-10-09 20:40:1463#include "gpu/command_buffer/client/context_support.h"
jamesr@chromium.orga770f2a2014-01-07 22:29:2364#include "gpu/command_buffer/client/gles2_interface.h"
penghuang346a46f92016-03-31 21:37:5265#include "gpu/ipc/client/command_buffer_proxy_impl.h"
66#include "gpu/ipc/client/gpu_channel_host.h"
jcivellic9a964032016-10-17 18:22:2067#include "gpu/ipc/common/gpu_surface_tracker.h"
qyearsleydb0a34872017-03-14 03:24:3168#include "gpu/vulkan/features.h"
sohan.jyoti2986bd482016-05-09 17:44:1269#include "gpu/vulkan/vulkan_surface.h"
sadrul85cc5d82016-12-20 03:37:4170#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
dtrainor@chromium.org92fa4d292012-10-16 20:31:5171#include "third_party/khronos/GLES2/gl2.h"
72#include "third_party/khronos/GLES2/gl2ext.h"
powei@chromium.org80ee2332014-02-06 18:31:0773#include "third_party/skia/include/core/SkMallocPixelRef.h"
jaekyune4f9eed2015-02-24 02:06:5874#include "ui/android/window_android.h"
boliu4868d412017-01-10 19:13:0575#include "ui/display/display.h"
76#include "ui/display/screen.h"
achaulkec8c2db2015-05-29 16:35:0377#include "ui/gfx/swap_result.h"
dtrainor@chromium.org92fa4d292012-10-16 20:31:5178
ccameron433204252016-05-09 20:57:5579namespace gpu {
80struct GpuProcessHostedCALayerTreeParamsMac;
81}
82
sieversdf212b32014-10-09 20:40:1483namespace content {
84
sievers@chromium.org16383382012-09-05 23:57:2685namespace {
86
khushalsagar31690fb2017-02-28 23:23:4887// The client_id used here should not conflict with the client_id generated
88// from RenderWidgetHostImpl.
89constexpr uint32_t kDefaultClientId = 0u;
90
91class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner {
92 public:
93 SingleThreadTaskGraphRunner() {
94 Start("CompositorTileWorker1", base::SimpleThread::Options());
95 }
96
97 ~SingleThreadTaskGraphRunner() override { Shutdown(); }
98};
99
100struct CompositorDependencies {
kylecharbfc507f2017-04-26 00:13:08101 CompositorDependencies() : frame_sink_id_allocator(kDefaultClientId) {
danakjaee67172017-06-13 16:37:02102 // TODO(danakj): Don't make a MojoFrameSinkManager when display is in the
103 // Gpu process, instead get the mojo pointer from the Gpu process.
104 frame_sink_manager =
105 base::MakeUnique<viz::MojoFrameSinkManager>(false, nullptr);
Fady Samuel279f5f02017-06-14 23:23:00106 surface_utils::ConnectWithInProcessFrameSinkManager(
danakjaee67172017-06-13 16:37:02107 &frame_sink_manager_host, frame_sink_manager.get());
kylecharbfc507f2017-04-26 00:13:08108 }
khushalsagar31690fb2017-02-28 23:23:48109
110 SingleThreadTaskGraphRunner task_graph_runner;
kylecharcb5882d2017-06-05 13:41:34111 viz::FrameSinkManagerHost frame_sink_manager_host;
khushalsagar31690fb2017-02-28 23:23:48112 cc::FrameSinkIdAllocator frame_sink_id_allocator;
danakjaee67172017-06-13 16:37:02113 // This is owned here so that SurfaceManager will be accessible in process
114 // when display is in the same process. Other than using SurfaceManager,
115 // access to |in_process_frame_sink_manager_| should happen via
116 // |frame_sink_manager_host_| instead which uses Mojo. See
117 // http://crbug.com/657959.
118 std::unique_ptr<viz::MojoFrameSinkManager> frame_sink_manager;
khushalsagar31690fb2017-02-28 23:23:48119
qyearsleydb0a34872017-03-14 03:24:31120#if BUILDFLAG(ENABLE_VULKAN)
khushalsagar31690fb2017-02-28 23:23:48121 scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider;
122#endif
123};
124
scottmg5e65e3a2017-03-08 08:48:46125base::LazyInstance<CompositorDependencies>::DestructorAtExit
126 g_compositor_dependencies = LAZY_INSTANCE_INITIALIZER;
khushalsagar31690fb2017-02-28 23:23:48127
briandersonebd2c9a2015-10-01 17:40:13128const unsigned int kMaxDisplaySwapBuffers = 1U;
sievers@chromium.org41256cd2014-05-27 22:45:34129
qyearsleydb0a34872017-03-14 03:24:31130#if BUILDFLAG(ENABLE_VULKAN)
khushalsagar31690fb2017-02-28 23:23:48131scoped_refptr<cc::VulkanContextProvider> GetSharedVulkanContextProvider() {
132 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
133 switches::kEnableVulkan)) {
134 scoped_refptr<cc::VulkanContextProvider> context_provider =
135 g_compositor_dependencies.Get().vulkan_context_provider;
136 if (!*context_provider)
137 *context_provider = cc::VulkanInProcessContextProvider::Create();
138 return *context_provider;
139 }
140 return nullptr;
141}
142#endif
143
boliu4868d412017-01-10 19:13:05144gpu::SharedMemoryLimits GetCompositorContextSharedMemoryLimits(
145 gfx::NativeWindow window) {
khushalsagarc81e43b2016-08-09 02:15:51146 constexpr size_t kBytesPerPixel = 4;
boliu4868d412017-01-10 19:13:05147 const gfx::Size size = display::Screen::GetScreen()
148 ->GetDisplayNearestWindow(window)
149 .GetSizeInPixel();
khushalsagarc81e43b2016-08-09 02:15:51150 const size_t full_screen_texture_size_in_bytes =
boliu4868d412017-01-10 19:13:05151 size.width() * size.height() * kBytesPerPixel;
khushalsagarc81e43b2016-08-09 02:15:51152
153 gpu::SharedMemoryLimits limits;
154 // This limit is meant to hold the contents of the display compositor
155 // drawing the scene. See discussion here:
156 // https://codereview.chromium.org/1900993002/diff/90001/content/browser/renderer_host/compositor_impl_android.cc?context=3&column_width=80&tab_spaces=8
157 limits.command_buffer_size = 64 * 1024;
158 // These limits are meant to hold the uploads for the browser UI without
159 // any excess space.
160 limits.start_transfer_buffer_size = 64 * 1024;
161 limits.min_transfer_buffer_size = 64 * 1024;
162 limits.max_transfer_buffer_size = full_screen_texture_size_in_bytes;
163 // Texture uploads may use mapped memory so give a reasonable limit for
164 // them.
165 limits.mapped_memory_reclaim_limit = full_screen_texture_size_in_bytes;
166
167 return limits;
168}
169
170gpu::gles2::ContextCreationAttribHelper GetCompositorContextAttributes(
171 bool has_transparent_background) {
172 // This is used for the browser compositor (offscreen) and for the display
173 // compositor (onscreen), so ask for capabilities needed by either one.
174 // The default framebuffer for an offscreen context is not used, so it does
175 // not need alpha, stencil, depth, antialiasing. The display compositor does
176 // not use these things either, except for alpha when it has a transparent
177 // background.
178 gpu::gles2::ContextCreationAttribHelper attributes;
179 attributes.alpha_size = -1;
180 attributes.stencil_size = 0;
181 attributes.depth_size = 0;
182 attributes.samples = 0;
183 attributes.sample_buffers = 0;
184 attributes.bind_generates_resource = false;
185
186 if (has_transparent_background) {
187 attributes.alpha_size = 8;
aeliase678aa42017-04-14 22:41:04188 } else if (base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) {
khushalsagarc81e43b2016-08-09 02:15:51189 // In this case we prefer to use RGB565 format instead of RGBA8888 if
190 // possible.
191 // TODO(danakj): GpuCommandBufferStub constructor checks for alpha == 0 in
192 // order to enable 565, but it should avoid using 565 when -1s are
193 // specified
194 // (IOW check that a <= 0 && rgb > 0 && rgb <= 565) then alpha should be
195 // -1.
liberato3fbc8b72017-03-21 18:38:18196 // TODO(liberato): This condition is memorized in ComositorView.java, to
197 // avoid using two surfaces temporarily during alpha <-> no alpha
198 // transitions. If these mismatch, then we risk a power regression if the
199 // SurfaceView is not marked as eOpaque (FORMAT_OPAQUE), and we have an
200 // EGL surface with an alpha channel. SurfaceFlinger needs at least one of
201 // those hints to optimize out alpha blending.
khushalsagarc81e43b2016-08-09 02:15:51202 attributes.alpha_size = 0;
203 attributes.red_size = 5;
204 attributes.green_size = 6;
205 attributes.blue_size = 5;
206 }
207
208 return attributes;
209}
210
khushalsagar003796ca2017-03-08 01:28:29211void CreateContextProviderAfterGpuChannelEstablished(
212 gpu::SurfaceHandle handle,
213 gpu::gles2::ContextCreationAttribHelper attributes,
214 gpu::SharedMemoryLimits shared_memory_limits,
215 Compositor::ContextProviderCallback callback,
216 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
217 if (!gpu_channel_host)
218 callback.Run(nullptr);
219
sunnyps8f9139e2017-05-12 17:53:25220 int32_t stream_id = kGpuStreamIdDefault;
221 gpu::SchedulingPriority stream_priority = kGpuStreamPriorityUI;
222
khushalsagar003796ca2017-03-08 01:28:29223 constexpr bool automatic_flushes = false;
224 constexpr bool support_locking = false;
sunnyps8f9139e2017-05-12 17:53:25225
khushalsagar003796ca2017-03-08 01:28:29226 scoped_refptr<ui::ContextProviderCommandBuffer> context_provider =
227 new ui::ContextProviderCommandBuffer(
sunnyps8f9139e2017-05-12 17:53:25228 std::move(gpu_channel_host), stream_id, stream_priority, handle,
khushalsagar003796ca2017-03-08 01:28:29229 GURL(std::string("chrome://gpu/Compositor::CreateContextProvider")),
230 automatic_flushes, support_locking, shared_memory_limits, attributes,
231 nullptr /* shared_context */,
232 ui::command_buffer_metrics::CONTEXT_TYPE_UNKNOWN);
233 callback.Run(std::move(context_provider));
234}
235
danakj1120f4c2016-09-15 02:05:32236class AndroidOutputSurface : public cc::OutputSurface {
brianderson@chromium.orgdf3c24c2013-06-19 03:54:35237 public:
boliue07c48a2017-03-10 05:46:51238 AndroidOutputSurface(
239 scoped_refptr<ui::ContextProviderCommandBuffer> context_provider,
240 base::Closure swap_buffers_callback)
danakje41d978a2016-09-19 21:09:28241 : cc::OutputSurface(std::move(context_provider)),
boliue07c48a2017-03-10 05:46:51242 swap_buffers_callback_(std::move(swap_buffers_callback)),
watkb9c0f2fe2015-11-25 00:44:54243 overlay_candidate_validator_(
xing.xue334e562017-05-17 19:08:10244 new viz::CompositorOverlayCandidateValidatorAndroid()),
danakj94486a42016-10-25 22:31:12245 weak_ptr_factory_(this) {
briandersonebd2c9a2015-10-01 17:40:13246 capabilities_.max_frames_pending = kMaxDisplaySwapBuffers;
brianderson@chromium.orgdf3c24c2013-06-19 03:54:35247 }
feng@chromium.orgdbafd6c2013-07-12 03:30:33248
danakj1120f4c2016-09-15 02:05:32249 ~AndroidOutputSurface() override = default;
jbauman9ebeafa2015-07-28 22:46:51250
kylechar5344b39e2016-10-06 23:51:19251 void SwapBuffers(cc::OutputSurfaceFrame frame) override {
mfomitchev598a7692017-04-11 00:30:31252 GetCommandBufferProxy()->AddLatencyInfo(frame.latency_info);
halliwell55723a72017-02-22 22:24:03253 if (frame.sub_buffer_rect) {
254 DCHECK(frame.sub_buffer_rect->IsEmpty());
watkc7589a8d2015-12-04 03:48:59255 context_provider_->ContextSupport()->CommitOverlayPlanes();
256 } else {
watkc7589a8d2015-12-04 03:48:59257 context_provider_->ContextSupport()->Swap();
258 }
feng@chromium.orgdbafd6c2013-07-12 03:30:33259 }
aeliasd880a3d2014-08-26 00:46:20260
danakj94486a42016-10-25 22:31:12261 void BindToClient(cc::OutputSurfaceClient* client) override {
262 DCHECK(client);
263 DCHECK(!client_);
264 client_ = client;
sieversdf212b32014-10-09 20:40:14265 GetCommandBufferProxy()->SetSwapBuffersCompletionCallback(
danakj94486a42016-10-25 22:31:12266 base::Bind(&AndroidOutputSurface::OnSwapBuffersCompleted,
267 weak_ptr_factory_.GetWeakPtr()));
aeliasd880a3d2014-08-26 00:46:20268 }
269
danakj1c77b832016-09-26 21:26:09270 void EnsureBackbuffer() override {}
271
272 void DiscardBackbuffer() override {
273 context_provider()->ContextGL()->DiscardBackbufferCHROMIUM();
274 }
275
276 void BindFramebuffer() override {
277 context_provider()->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
278 }
279
jbauman2a2ad222017-03-02 00:35:13280 void SetDrawRectangle(const gfx::Rect& rect) override {}
281
danakj70ffc43c2016-10-10 21:47:30282 void Reshape(const gfx::Size& size,
283 float device_scale_factor,
284 const gfx::ColorSpace& color_space,
reveman9413cff2017-01-18 03:05:48285 bool has_alpha,
286 bool use_stencil) override {
danakj70ffc43c2016-10-10 21:47:30287 context_provider()->ContextGL()->ResizeCHROMIUM(
288 size.width(), size.height(), device_scale_factor, has_alpha);
289 }
290
watkb9c0f2fe2015-11-25 00:44:54291 cc::OverlayCandidateValidator* GetOverlayCandidateValidator() const override {
292 return overlay_candidate_validator_.get();
293 }
294
danakj1c77b832016-09-26 21:26:09295 bool IsDisplayedAsOverlayPlane() const override { return false; }
296 unsigned GetOverlayTextureId() const override { return 0; }
297 bool SurfaceIsSuspendForRecycle() const override { return false; }
298 bool HasExternalStencilTest() const override { return false; }
299 void ApplyExternalStencil() override {}
300
danakja85bd242016-06-22 22:25:49301 uint32_t GetFramebufferCopyTextureFormat() override {
sadrul85cc5d82016-12-20 03:37:41302 auto* gl =
303 static_cast<ui::ContextProviderCommandBuffer*>(context_provider());
danakja85bd242016-06-22 22:25:49304 return gl->GetCopyTextureInternalFormat();
305 }
306
sieversdf212b32014-10-09 20:40:14307 private:
penghuang346a46f92016-03-31 21:37:52308 gpu::CommandBufferProxyImpl* GetCommandBufferProxy() {
sadrul85cc5d82016-12-20 03:37:41309 ui::ContextProviderCommandBuffer* provider_command_buffer =
310 static_cast<ui::ContextProviderCommandBuffer*>(context_provider_.get());
penghuang346a46f92016-03-31 21:37:52311 gpu::CommandBufferProxyImpl* command_buffer_proxy =
sieversdf212b32014-10-09 20:40:14312 provider_command_buffer->GetCommandBufferProxy();
313 DCHECK(command_buffer_proxy);
314 return command_buffer_proxy;
315 }
316
ccameron433204252016-05-09 20:57:55317 void OnSwapBuffersCompleted(
318 const std::vector<ui::LatencyInfo>& latency_info,
319 gfx::SwapResult result,
320 const gpu::GpuProcessHostedCALayerTreeParamsMac* params_mac) {
mfomitchev60addc8d2017-04-04 17:14:55321 RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
danakj440bc682016-10-14 19:56:48322 client_->DidReceiveSwapBuffersAck();
boliue07c48a2017-03-10 05:46:51323 swap_buffers_callback_.Run();
sieversdf212b32014-10-09 20:40:14324 }
325
enne19c108582016-04-14 03:35:32326 private:
danakj94486a42016-10-25 22:31:12327 cc::OutputSurfaceClient* client_ = nullptr;
boliue07c48a2017-03-10 05:46:51328 base::Closure swap_buffers_callback_;
dcheng92ae1412016-04-09 02:52:24329 std::unique_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator_;
danakj94486a42016-10-25 22:31:12330 base::WeakPtrFactory<AndroidOutputSurface> weak_ptr_factory_;
sievers48c068d2016-01-06 00:14:43331};
332
qyearsleydb0a34872017-03-14 03:24:31333#if BUILDFLAG(ENABLE_VULKAN)
sohan.jyoti2986bd482016-05-09 17:44:12334class VulkanOutputSurface : public cc::OutputSurface {
335 public:
danakj8eb035c02016-06-17 22:41:32336 explicit VulkanOutputSurface(
danakjdaad1d12016-10-11 00:00:34337 scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider,
338 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
339 : OutputSurface(std::move(vulkan_context_provider)),
340 task_runner_(std::move(task_runner)),
341 weak_ptr_factory_(this) {}
sohan.jyoti2986bd482016-05-09 17:44:12342
343 ~VulkanOutputSurface() override { Destroy(); }
344
345 bool Initialize(gfx::AcceleratedWidget widget) {
346 DCHECK(!surface_);
347 std::unique_ptr<gpu::VulkanSurface> surface(
348 gpu::VulkanSurface::CreateViewSurface(widget));
349 if (!surface->Initialize(vulkan_context_provider()->GetDeviceQueue(),
350 gpu::VulkanSurface::DEFAULT_SURFACE_FORMAT)) {
351 return false;
352 }
353 surface_ = std::move(surface);
354
355 return true;
356 }
357
sohan.jyoti13587c62016-05-13 01:33:15358 bool BindToClient(cc::OutputSurfaceClient* client) override {
359 if (!OutputSurface::BindToClient(client))
360 return false;
sohan.jyoti13587c62016-05-13 01:33:15361 return true;
362 }
363
fsamueld63137a2016-06-24 23:39:51364 void SwapBuffers(cc::CompositorFrame frame) override {
sohan.jyoti2986bd482016-05-09 17:44:12365 surface_->SwapBuffers();
danakjdaad1d12016-10-11 00:00:34366 task_runner_->PostTask(FROM_HERE,
danakj440bc682016-10-14 19:56:48367 base::Bind(&VulkanOutputSurface::SwapBuffersAck,
danakjdaad1d12016-10-11 00:00:34368 weak_ptr_factory_.GetWeakPtr()));
sohan.jyoti2986bd482016-05-09 17:44:12369 }
370
371 void Destroy() {
372 if (surface_) {
373 surface_->Destroy();
374 surface_.reset();
375 }
376 }
377
danakjdaad1d12016-10-11 00:00:34378 private:
danakj440bc682016-10-14 19:56:48379 void SwapBuffersAck() { client_->DidReceiveSwapBuffersAck(); }
sohan.jyoti2986bd482016-05-09 17:44:12380
sohan.jyoti2986bd482016-05-09 17:44:12381 std::unique_ptr<gpu::VulkanSurface> surface_;
danakjdaad1d12016-10-11 00:00:34382 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
383 base::WeakPtrFactory<VulkanOutputSurface> weak_ptr_factory_;
sohan.jyoti2986bd482016-05-09 17:44:12384
385 DISALLOW_COPY_AND_ASSIGN(VulkanOutputSurface);
386};
387#endif
388
sievers@chromium.orgfd7a8572012-09-18 19:32:05389static bool g_initialized = false;
390
ericrk4e3aa5a2015-12-01 03:53:56391} // anonymous namespace
sievers@chromium.org16383382012-09-05 23:57:26392
sievers@chromium.org16383382012-09-05 23:57:26393// static
powei@chromium.orgaca40ac2013-11-21 21:35:28394Compositor* Compositor::Create(CompositorClient* client,
395 gfx::NativeWindow root_window) {
396 return client ? new CompositorImpl(client, root_window) : NULL;
sievers@chromium.org16383382012-09-05 23:57:26397}
398
399// static
400void Compositor::Initialize() {
sievers@chromium.orgd32353f2012-11-16 23:49:32401 DCHECK(!CompositorImpl::IsInitialized());
sievers@chromium.orgfd7a8572012-09-18 19:32:05402 g_initialized = true;
aelias@chromium.org8f3ffdc62012-11-15 05:28:26403}
404
405// static
khushalsagar003796ca2017-03-08 01:28:29406void Compositor::CreateContextProvider(
407 gpu::SurfaceHandle handle,
408 gpu::gles2::ContextCreationAttribHelper attributes,
409 gpu::SharedMemoryLimits shared_memory_limits,
410 ContextProviderCallback callback) {
411 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
412 base::Bind(&CreateContextProviderAfterGpuChannelEstablished, handle,
413 attributes, shared_memory_limits, callback));
414}
415
416// static
khushalsagar31690fb2017-02-28 23:23:48417cc::SurfaceManager* CompositorImpl::GetSurfaceManager() {
danakjaee67172017-06-13 16:37:02418 return g_compositor_dependencies.Get().frame_sink_manager->surface_manager();
kylechar69bd9162017-04-10 23:45:48419}
420
421// static
kylecharcb5882d2017-06-05 13:41:34422viz::FrameSinkManagerHost* CompositorImpl::GetFrameSinkManagerHost() {
kylechar69bd9162017-04-10 23:45:48423 return &g_compositor_dependencies.Get().frame_sink_manager_host;
khushalsagar31690fb2017-02-28 23:23:48424}
425
426// static
427cc::FrameSinkId CompositorImpl::AllocateFrameSinkId() {
428 return g_compositor_dependencies.Get()
429 .frame_sink_id_allocator.NextFrameSinkId();
430}
431
432// static
sievers@chromium.orgfd7a8572012-09-18 19:32:05433bool CompositorImpl::IsInitialized() {
434 return g_initialized;
435}
436
powei@chromium.orgaca40ac2013-11-21 21:35:28437CompositorImpl::CompositorImpl(CompositorClient* client,
438 gfx::NativeWindow root_window)
khushalsagar31690fb2017-02-28 23:23:48439 : frame_sink_id_(AllocateFrameSinkId()),
enne131f1db2016-04-18 19:32:51440 resource_manager_(root_window),
leandrogracia@chromium.orgd9c747af2012-12-03 14:54:35441 window_(NULL),
pimana333e3d2016-04-27 02:37:25442 surface_handle_(gpu::kNullSurfaceHandle),
powei@chromium.orgaca40ac2013-11-21 21:35:28443 client_(client),
sievers@chromium.org5aba5bc2014-05-13 22:40:59444 root_window_(root_window),
sievers@chromium.org41256cd2014-05-27 22:45:34445 needs_animate_(false),
boliuba835902017-02-28 04:10:15446 pending_frames_(0U),
sieversbce219232015-02-09 21:01:49447 num_successive_context_creation_failures_(0),
danakjc7afae52017-06-20 21:12:41448 layer_tree_frame_sink_request_pending_(false),
sievers@chromium.orgaee59bb2014-05-31 04:58:45449 weak_factory_(this) {
khushalsagar31690fb2017-02-28 23:23:48450 GetSurfaceManager()->RegisterFrameSinkId(frame_sink_id_);
sievers@chromium.org24a65cc2012-10-15 17:53:46451 DCHECK(client);
powei@chromium.orgaca40ac2013-11-21 21:35:28452 DCHECK(root_window);
sievers481b7fe2016-07-21 17:03:59453 DCHECK(root_window->GetLayer() == nullptr);
454 root_window->SetLayer(cc::Layer::Create());
sievers962aa7212016-08-12 18:26:14455 readback_layer_tree_ = cc::Layer::Create();
456 readback_layer_tree_->SetHideLayerAndSubtree(true);
457 root_window->GetLayer()->AddChild(readback_layer_tree_);
powei@chromium.org0809f7e22014-03-20 00:05:45458 root_window->AttachCompositor(this);
sievers148fedf2015-10-02 00:12:04459 CreateLayerTreeHost();
khushalsagar8ec07402016-09-10 03:13:19460 resource_manager_.Init(host_->GetUIResourceManager());
sievers@chromium.org16383382012-09-05 23:57:26461}
462
463CompositorImpl::~CompositorImpl() {
powei@chromium.orgaca40ac2013-11-21 21:35:28464 root_window_->DetachCompositor();
sievers481b7fe2016-07-21 17:03:59465 root_window_->SetLayer(nullptr);
epenner@chromium.org822f0c442013-04-18 05:03:07466 // Clean-up any surface references.
467 SetSurface(NULL);
khushalsagar31690fb2017-02-28 23:23:48468 GetSurfaceManager()->InvalidateFrameSinkId(frame_sink_id_);
sievers@chromium.org16383382012-09-05 23:57:26469}
470
wjmacleana755e302017-04-20 00:43:16471bool CompositorImpl::IsForSubframe() {
472 return false;
473}
474
jaekyunf229b812014-12-11 02:49:10475ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() {
sievers148fedf2015-10-02 00:12:04476 return *this;
powei@chromium.org4825cbf2014-06-13 07:15:45477}
478
jaekyund5de7e42014-12-04 16:19:13479ui::ResourceManager& CompositorImpl::GetResourceManager() {
480 return resource_manager_;
481}
482
leandrogracia@chromium.orgd9c747af2012-12-03 14:54:35483void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
dcheng165763c2014-10-07 04:14:54484 if (subroot_layer_.get()) {
aelias@chromium.org25950ad2014-07-18 18:30:01485 subroot_layer_->RemoveFromParent();
486 subroot_layer_ = NULL;
487 }
sievers481b7fe2016-07-21 17:03:59488 if (root_window_->GetLayer()) {
489 subroot_layer_ = root_window_->GetLayer();
490 root_window_->GetLayer()->AddChild(root_layer);
aelias@chromium.org25950ad2014-07-18 18:30:01491 }
sievers@chromium.org16383382012-09-05 23:57:26492}
493
sieverse018d323c2015-10-15 20:41:20494void CompositorImpl::SetSurface(jobject surface) {
495 JNIEnv* env = base::android::AttachCurrentThread();
jcivellic9a964032016-10-17 18:22:20496 gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get();
sievers@chromium.orgfd7a8572012-09-18 19:32:05497
498 if (window_) {
sieverse8d881d2015-08-06 20:01:35499 // Shut down GL context before unregistering surface.
500 SetVisible(false);
pimana333e3d2016-04-27 02:37:25501 tracker->RemoveSurface(surface_handle_);
sievers@chromium.orgfd7a8572012-09-18 19:32:05502 ANativeWindow_release(window_);
503 window_ = NULL;
pimana333e3d2016-04-27 02:37:25504 surface_handle_ = gpu::kNullSurfaceHandle;
sievers@chromium.orgfd7a8572012-09-18 19:32:05505 }
506
sieverse018d323c2015-10-15 20:41:20507 ANativeWindow* window = NULL;
508 if (surface) {
509 // Note: This ensures that any local references used by
510 // ANativeWindow_fromSurface are released immediately. This is needed as a
511 // workaround for https://code.google.com/p/android/issues/detail?id=68174
512 base::android::ScopedJavaLocalFrame scoped_local_reference_frame(env);
513 window = ANativeWindow_fromSurface(env, surface);
514 }
515
sievers@chromium.org16383382012-09-05 23:57:26516 if (window) {
sievers@chromium.orgfd7a8572012-09-18 19:32:05517 window_ = window;
518 ANativeWindow_acquire(window);
danakjc7afae52017-06-20 21:12:41519 // Register first, SetVisible() might create a LayerTreeFrameSink.
liberatod90f48c2017-05-01 23:44:50520 surface_handle_ = tracker->AddSurfaceForNativeWidget(
521 gpu::GpuSurfaceTracker::SurfaceRecord(window, surface));
sieverse018d323c2015-10-15 20:41:20522 SetVisible(true);
523 ANativeWindow_release(window);
sievers@chromium.orgccf558a2013-03-07 03:58:18524 }
525}
526
auygunb2101b62014-12-08 10:46:23527void CompositorImpl::CreateLayerTreeHost() {
528 DCHECK(!host_);
sievers148fedf2015-10-02 00:12:04529
auygunb2101b62014-12-08 10:46:23530 cc::LayerTreeSettings settings;
Bo Liu5364de182015-05-21 03:48:29531 settings.use_zero_copy = true;
auygunb2101b62014-12-08 10:46:23532
533 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
534 settings.initial_debug_state.SetRecordRenderingStats(
535 command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
dongseong.hwange095dfa2016-02-04 11:21:39536 settings.initial_debug_state.show_fps_counter =
537 command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
sievers48c068d2016-01-06 00:14:43538 settings.single_thread_proxy_scheduler = true;
auygunb2101b62014-12-08 10:46:23539
loyso2cb3f32f2016-11-08 07:08:34540 animation_host_ = cc::AnimationHost::CreateMainInstance();
541
khushalsagare0e4486e2017-01-25 03:15:03542 cc::LayerTreeHost::InitParams params;
sadrul6780f3da2015-05-11 17:01:52543 params.client = this;
khushalsagar31690fb2017-02-28 23:23:48544 params.task_graph_runner = &g_compositor_dependencies.Get().task_graph_runner;
sadrul6780f3da2015-05-11 17:01:52545 params.main_task_runner = base::ThreadTaskRunnerHandle::Get();
546 params.settings = &settings;
loyso2cb3f32f2016-11-08 07:08:34547 params.mutator_host = animation_host_.get();
khushalsagare0e4486e2017-01-25 03:15:03548 host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
khushalsagarcebe4942016-09-07 23:27:01549 DCHECK(!host_->IsVisible());
khushalsagarb69ba9452017-01-27 22:20:07550 host_->SetRootLayer(root_window_->GetLayer());
fsamuelb6acafa2016-10-04 03:21:52551 host_->SetFrameSinkId(frame_sink_id_);
khushalsagarb69ba9452017-01-27 22:20:07552 host_->SetViewportSize(size_);
jinsukkimd4b3f4e42016-11-23 02:10:13553 SetHasTransparentBackground(false);
khushalsagarb69ba9452017-01-27 22:20:07554 host_->SetDeviceScaleFactor(1);
jdduke17112572014-12-10 23:02:59555
556 if (needs_animate_)
557 host_->SetNeedsAnimate();
auygunb2101b62014-12-08 10:46:23558}
559
sievers@chromium.orgd32353f2012-11-16 23:49:32560void CompositorImpl::SetVisible(bool visible) {
jdduke76f34772015-03-26 03:44:53561 TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible);
sievers@chromium.orgd32353f2012-11-16 23:49:32562 if (!visible) {
khushalsagarcebe4942016-09-07 23:27:01563 DCHECK(host_->IsVisible());
sievers962aa7212016-08-12 18:26:14564
565 // Make a best effort to try to complete pending readbacks.
566 // TODO(crbug.com/637035): Consider doing this in a better way,
567 // ideally with the guarantee of readbacks completing.
568 if (display_.get() && HavePendingReadbacks())
569 display_->ForceImmediateDrawAndSwapIfPossible();
570
sievers148fedf2015-10-02 00:12:04571 host_->SetVisible(false);
danakjc7afae52017-06-20 21:12:41572 host_->ReleaseLayerTreeFrameSink();
573 has_layer_tree_frame_sink_ = false;
boliuba835902017-02-28 04:10:15574 pending_frames_ = 0;
Alex Zhangd3b9d652017-06-09 18:48:55575 if (display_) {
576 GetSurfaceManager()->UnregisterBeginFrameSource(
577 root_window_->GetBeginFrameSource());
578 }
danakj324faea2016-06-11 01:39:31579 display_.reset();
sievers148fedf2015-10-02 00:12:04580 } else {
581 host_->SetVisible(true);
danakjc7afae52017-06-20 21:12:41582 if (layer_tree_frame_sink_request_pending_)
583 HandlePendingLayerTreeFrameSinkRequest();
sievers@chromium.org16383382012-09-05 23:57:26584 }
585}
586
587void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
588 if (size_ == size)
589 return;
590
591 size_ = size;
joth@chromium.org19728482012-11-20 03:39:01592 if (host_)
khushalsagarb69ba9452017-01-27 22:20:07593 host_->SetViewportSize(size);
danakj324faea2016-06-11 01:39:31594 if (display_)
595 display_->Resize(size);
sievers481b7fe2016-07-21 17:03:59596 root_window_->GetLayer()->SetBounds(size);
sievers@chromium.org16383382012-09-05 23:57:26597}
598
jinsukkimd4b3f4e42016-11-23 02:10:13599void CompositorImpl::SetHasTransparentBackground(bool transparent) {
600 has_transparent_background_ = transparent;
601 if (host_) {
khushalsagarb69ba9452017-01-27 22:20:07602 host_->set_has_transparent_background(transparent);
jinsukkimd4b3f4e42016-11-23 02:10:13603
604 // Give a delay in setting the background color to avoid the color for
605 // the normal mode (white) affecting the UI transition.
606 base::ThreadTaskRunnerHandle::Get().get()->PostDelayedTask(
607 FROM_HERE,
608 base::Bind(&CompositorImpl::SetBackgroundColor,
609 weak_factory_.GetWeakPtr(),
610 transparent ? SK_ColorBLACK : SK_ColorWHITE),
611 base::TimeDelta::FromMilliseconds(500));
612 }
613}
614
615void CompositorImpl::SetBackgroundColor(int color) {
khushalsagarb69ba9452017-01-27 22:20:07616 host_->set_background_color(color);
trchen@chromium.orgd66ddad2014-01-09 02:16:00617}
618
sievers@chromium.org5aba5bc2014-05-13 22:40:59619void CompositorImpl::SetNeedsComposite() {
khushalsagarcebe4942016-09-07 23:27:01620 if (!host_->IsVisible())
sievers@chromium.org5aba5bc2014-05-13 22:40:59621 return;
sievers6414a452016-04-22 21:33:20622 TRACE_EVENT0("compositor", "Compositor::SetNeedsComposite");
sievers48c068d2016-01-06 00:14:43623 host_->SetNeedsAnimate();
sievers@chromium.org5aba5bc2014-05-13 22:40:59624}
625
wkorman7265db012015-11-03 04:08:25626void CompositorImpl::UpdateLayerTreeHost() {
wkorman7265db012015-11-03 04:08:25627 client_->UpdateLayerTreeHost();
sievers48c068d2016-01-06 00:14:43628 if (needs_animate_) {
629 needs_animate_ = false;
630 root_window_->Animate(base::TimeTicks::Now());
631 }
sievers@chromium.org5aba5bc2014-05-13 22:40:59632}
633
danakjc7afae52017-06-20 21:12:41634void CompositorImpl::RequestNewLayerTreeFrameSink() {
635 DCHECK(!layer_tree_frame_sink_request_pending_)
636 << "LayerTreeFrameSink request is already pending?";
khushalsagarc81e43b2016-08-09 02:15:51637
danakjc7afae52017-06-20 21:12:41638 layer_tree_frame_sink_request_pending_ = true;
639 HandlePendingLayerTreeFrameSinkRequest();
enne2097cab2014-09-25 20:16:31640}
641
danakjc7afae52017-06-20 21:12:41642void CompositorImpl::DidInitializeLayerTreeFrameSink() {
643 layer_tree_frame_sink_request_pending_ = false;
644 has_layer_tree_frame_sink_ = true;
starazaa231112017-02-07 17:53:24645 for (auto& frame_sink_id : pending_child_frame_sink_ids_)
646 AddChildFrameSink(frame_sink_id);
647
648 pending_child_frame_sink_ids_.clear();
sieversbce219232015-02-09 21:01:49649}
650
danakjc7afae52017-06-20 21:12:41651void CompositorImpl::DidFailToInitializeLayerTreeFrameSink() {
danakj801bcef92016-11-01 20:18:38652 // The context is bound/initialized before handing it to the
danakjc7afae52017-06-20 21:12:41653 // LayerTreeFrameSink.
danakj801bcef92016-11-01 20:18:38654 NOTREACHED();
enne7f8fdde2014-12-10 21:32:09655}
656
danakjc7afae52017-06-20 21:12:41657void CompositorImpl::HandlePendingLayerTreeFrameSinkRequest() {
658 DCHECK(layer_tree_frame_sink_request_pending_);
khushalsagarc81e43b2016-08-09 02:15:51659
660 // We might have been made invisible now.
khushalsagarcebe4942016-09-07 23:27:01661 if (!host_->IsVisible())
sievers589235a2015-02-11 01:48:51662 return;
663
qyearsleydb0a34872017-03-14 03:24:31664#if BUILDFLAG(ENABLE_VULKAN)
khushalsagarc81e43b2016-08-09 02:15:51665 CreateVulkanOutputSurface()
666 if (display_)
667 return;
668#endif
669
khushalsagar31690fb2017-02-28 23:23:48670#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
671 defined(SYZYASAN) || defined(CYGPROFILE_INSTRUMENTATION)
672 const int64_t kGpuChannelTimeoutInSeconds = 40;
673#else
674 // The GPU watchdog timeout is 15 seconds (1.5x the kGpuTimeout value due to
675 // logic in GpuWatchdogThread). Make this slightly longer to give the GPU a
676 // chance to crash itself before crashing the browser.
677 const int64_t kGpuChannelTimeoutInSeconds = 20;
678#endif
679
680 // Start the timer first, if the result comes synchronously, we want it to
681 // stop in the callback.
682 establish_gpu_channel_timeout_.Start(
683 FROM_HERE, base::TimeDelta::FromSeconds(kGpuChannelTimeoutInSeconds),
684 this, &CompositorImpl::OnGpuChannelTimeout);
685
khushalsagarc81e43b2016-08-09 02:15:51686 DCHECK(surface_handle_ != gpu::kNullSurfaceHandle);
khushalsagar31690fb2017-02-28 23:23:48687 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(base::Bind(
khushalsagar8ecea2e72016-09-02 20:25:57688 &CompositorImpl::OnGpuChannelEstablished, weak_factory_.GetWeakPtr()));
khushalsagarc81e43b2016-08-09 02:15:51689}
690
khushalsagar31690fb2017-02-28 23:23:48691void CompositorImpl::OnGpuChannelTimeout() {
692 LOG(FATAL) << "Timed out waiting for GPU channel.";
693}
694
qyearsleydb0a34872017-03-14 03:24:31695#if BUILDFLAG(ENABLE_VULKAN)
khushalsagarc81e43b2016-08-09 02:15:51696void CompositorImpl::CreateVulkanOutputSurface() {
697 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
698 switches::kEnableVulkan))
699 return;
700
khushalsagarc81e43b2016-08-09 02:15:51701 scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider =
khushalsagar31690fb2017-02-28 23:23:48702 GetSharedVulkanContextProvider();
danakj1120f4c2016-09-15 02:05:32703 if (!vulkan_context_provider)
khushalsagarc81e43b2016-08-09 02:15:51704 return;
705
boliu1021ed202017-03-03 20:13:40706 // TODO(crbug.com/582558): Need to match GL and implement DidSwapBuffers.
danakjdaad1d12016-10-11 00:00:34707 auto vulkan_surface = base::MakeUnique<VulkanOutputSurface>(
708 vulkan_context_provider, base::ThreadTaskRunnerHandle::Get());
danakj1120f4c2016-09-15 02:05:32709 if (!vulkan_surface->Initialize(window_))
710 return;
711
712 InitializeDisplay(std::move(vulkan_surface),
khushalsagarc81e43b2016-08-09 02:15:51713 std::move(vulkan_context_provider), nullptr);
714}
sohan.jyoti2986bd482016-05-09 17:44:12715#endif
jinsukkim25219612016-01-20 23:24:07716
khushalsagar8ecea2e72016-09-02 20:25:57717void CompositorImpl::OnGpuChannelEstablished(
khushalsagar31690fb2017-02-28 23:23:48718 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
719 establish_gpu_channel_timeout_.Stop();
720
khushalsagar2010e7d2016-09-06 05:45:43721 // We might end up queing multiple GpuChannel requests for the same
danakjc7afae52017-06-20 21:12:41722 // LayerTreeFrameSink request as the visibility of the compositor changes, so
723 // the LayerTreeFrameSink request could have been handled already.
724 if (!layer_tree_frame_sink_request_pending_)
khushalsagar2010e7d2016-09-06 05:45:43725 return;
sievers@chromium.org2b594b12013-03-06 01:02:12726
khushalsagar31690fb2017-02-28 23:23:48727 if (!gpu_channel_host) {
danakjc7afae52017-06-20 21:12:41728 HandlePendingLayerTreeFrameSinkRequest();
khushalsagar31690fb2017-02-28 23:23:48729 return;
khushalsagar8ecea2e72016-09-02 20:25:57730 }
khushalsagar31690fb2017-02-28 23:23:48731
732 // We don't need the context anymore if we are invisible.
733 if (!host_->IsVisible())
734 return;
735
736 DCHECK(window_);
737 DCHECK_NE(surface_handle_, gpu::kNullSurfaceHandle);
sunnyps8f9139e2017-05-12 17:53:25738
739 int32_t stream_id = kGpuStreamIdDefault;
740 gpu::SchedulingPriority stream_priority = kGpuStreamPriorityUI;
741
khushalsagar31690fb2017-02-28 23:23:48742 constexpr bool support_locking = false;
743 constexpr bool automatic_flushes = false;
sunnyps8f9139e2017-05-12 17:53:25744
khushalsagar31690fb2017-02-28 23:23:48745 ui::ContextProviderCommandBuffer* shared_context = nullptr;
746 scoped_refptr<ui::ContextProviderCommandBuffer> context_provider =
747 new ui::ContextProviderCommandBuffer(
sunnyps8f9139e2017-05-12 17:53:25748 std::move(gpu_channel_host), stream_id, stream_priority,
749 surface_handle_,
khushalsagar31690fb2017-02-28 23:23:48750 GURL(std::string("chrome://gpu/CompositorImpl::") +
751 std::string("CompositorContextProvider")),
752 automatic_flushes, support_locking,
753 GetCompositorContextSharedMemoryLimits(root_window_),
754 GetCompositorContextAttributes(has_transparent_background_),
755 shared_context,
756 ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
757 if (!context_provider->BindToCurrentThread()) {
758 LOG(ERROR) << "Failed to init ContextProvider for compositor.";
759 LOG_IF(FATAL, ++num_successive_context_creation_failures_ >= 2)
760 << "Too many context creation failures. Giving up... ";
danakjc7afae52017-06-20 21:12:41761 HandlePendingLayerTreeFrameSinkRequest();
khushalsagarcfd16cd2017-04-04 18:47:48762 return;
khushalsagar31690fb2017-02-28 23:23:48763 }
764
boliue07c48a2017-03-10 05:46:51765 // Unretained is safe this owns cc::Display which owns OutputSurface.
766 auto display_output_surface = base::MakeUnique<AndroidOutputSurface>(
767 context_provider,
768 base::Bind(&CompositorImpl::DidSwapBuffers, base::Unretained(this)));
hzl1fa94872017-03-09 00:21:38769 InitializeDisplay(std::move(display_output_surface), nullptr,
770 std::move(context_provider));
khushalsagarc81e43b2016-08-09 02:15:51771}
danakj@chromium.org0634cdd42013-08-16 00:46:09772
khushalsagarc81e43b2016-08-09 02:15:51773void CompositorImpl::InitializeDisplay(
774 std::unique_ptr<cc::OutputSurface> display_output_surface,
775 scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider,
776 scoped_refptr<cc::ContextProvider> context_provider) {
danakjc7afae52017-06-20 21:12:41777 DCHECK(layer_tree_frame_sink_request_pending_);
danakj6f4e1e22016-04-20 03:27:34778
boliuba835902017-02-28 04:10:15779 pending_frames_ = 0;
danakj801bcef92016-11-01 20:18:38780 num_successive_context_creation_failures_ = 0;
781
782 if (context_provider) {
783 gpu_capabilities_ = context_provider->ContextCapabilities();
784 } else {
785 // TODO(danakj): Populate gpu_capabilities_ for VulkanContextProvider.
786 }
danakj6f4e1e22016-04-20 03:27:34787
khushalsagar31690fb2017-02-28 23:23:48788 cc::SurfaceManager* manager = GetSurfaceManager();
danakj8eb035c02016-06-17 22:41:32789 auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
danakj8eb035c02016-06-17 22:41:32790 std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
Alex Zhangd3b9d652017-06-09 18:48:55791 root_window_->GetBeginFrameSource(), task_runner,
792 display_output_surface->capabilities().max_frames_pending));
danakj8eb035c02016-06-17 22:41:32793
Alex Zhang903cb6a2017-06-12 20:31:37794 cc::RendererSettings renderer_settings;
795 renderer_settings.allow_antialiasing = false;
796 renderer_settings.highp_threshold_min = 2048;
danakj8eb035c02016-06-17 22:41:32797 display_.reset(new cc::Display(
xing.xue334e562017-05-17 19:08:10798 viz::HostSharedBitmapManager::current(),
Alex Zhang903cb6a2017-06-12 20:31:37799 BrowserGpuMemoryBufferManager::current(), renderer_settings,
800 frame_sink_id_, std::move(display_output_surface), std::move(scheduler),
danakj8eb035c02016-06-17 22:41:32801 base::MakeUnique<cc::TextureMailboxDeleter>(task_runner)));
sohan.jyoti2986bd482016-05-09 17:44:12802
danakjc7afae52017-06-20 21:12:41803 auto layer_tree_frame_sink =
pimanc44437a22016-10-29 00:09:22804 vulkan_context_provider
danakjc7afae52017-06-20 21:12:41805 ? base::MakeUnique<cc::DirectLayerTreeFrameSink>(
pimanc44437a22016-10-29 00:09:22806 frame_sink_id_, manager, display_.get(),
807 vulkan_context_provider)
danakjc7afae52017-06-20 21:12:41808 : base::MakeUnique<cc::DirectLayerTreeFrameSink>(
pimanc44437a22016-10-29 00:09:22809 frame_sink_id_, manager, display_.get(), context_provider,
810 nullptr, BrowserGpuMemoryBufferManager::current(),
xing.xue334e562017-05-17 19:08:10811 viz::HostSharedBitmapManager::current());
jbauman78f9b572014-11-18 06:01:56812
danakj6f2861b2016-08-17 02:10:17813 display_->SetVisible(true);
danakj324faea2016-06-11 01:39:31814 display_->Resize(size_);
Alex Zhangd3b9d652017-06-09 18:48:55815 GetSurfaceManager()->RegisterBeginFrameSource(
816 root_window_->GetBeginFrameSource(), frame_sink_id_);
danakjc7afae52017-06-20 21:12:41817 host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
aeliasd880a3d2014-08-26 00:46:20818}
819
boliue07c48a2017-03-10 05:46:51820void CompositorImpl::DidSwapBuffers() {
821 client_->DidSwapBuffers();
822}
823
sievers148fedf2015-10-02 00:12:04824cc::UIResourceId CompositorImpl::CreateUIResource(
825 cc::UIResourceClient* client) {
sievers6414a452016-04-22 21:33:20826 TRACE_EVENT0("compositor", "CompositorImpl::CreateUIResource");
khushalsagar8ec07402016-09-10 03:13:19827 return host_->GetUIResourceManager()->CreateUIResource(client);
sievers148fedf2015-10-02 00:12:04828}
829
830void CompositorImpl::DeleteUIResource(cc::UIResourceId resource_id) {
sievers6414a452016-04-22 21:33:20831 TRACE_EVENT0("compositor", "CompositorImpl::DeleteUIResource");
khushalsagar8ec07402016-09-10 03:13:19832 host_->GetUIResourceManager()->DeleteUIResource(resource_id);
sievers148fedf2015-10-02 00:12:04833}
834
835bool CompositorImpl::SupportsETC1NonPowerOfTwo() const {
836 return gpu_capabilities_.texture_format_etc1_npot;
837}
838
danakj6c872fc02016-10-22 04:29:49839void CompositorImpl::DidSubmitCompositorFrame() {
840 TRACE_EVENT0("compositor", "CompositorImpl::DidSubmitCompositorFrame");
boliuba835902017-02-28 04:10:15841 pending_frames_++;
sievers@chromium.org5aba5bc2014-05-13 22:40:59842}
843
danakj9d124422016-10-14 03:15:08844void CompositorImpl::DidReceiveCompositorFrameAck() {
845 TRACE_EVENT0("compositor", "CompositorImpl::DidReceiveCompositorFrameAck");
boliuba835902017-02-28 04:10:15846 DCHECK_GT(pending_frames_, 0U);
847 pending_frames_--;
848 client_->DidSwapFrame(pending_frames_);
jamesr@chromium.org4d7e46a2013-11-08 05:33:40849}
850
danakjc7afae52017-06-20 21:12:41851void CompositorImpl::DidLoseLayerTreeFrameSink() {
852 TRACE_EVENT0("compositor", "CompositorImpl::DidLoseLayerTreeFrameSink");
853 has_layer_tree_frame_sink_ = false;
boliuba835902017-02-28 04:10:15854 client_->DidSwapFrame(0);
jamesr@chromium.orgfa8d3962012-11-19 22:18:34855}
856
powei@chromium.orgaca40ac2013-11-21 21:35:28857void CompositorImpl::DidCommit() {
858 root_window_->OnCompositingDidCommit();
859}
860
sievers02d8a97d2016-08-12 01:06:49861void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) {
sievers962aa7212016-08-12 18:26:14862 readback_layer_tree_->AddChild(layer);
sievers02d8a97d2016-08-12 01:06:49863}
864
danakj@chromium.org2e6f39e2014-05-15 19:36:36865void CompositorImpl::RequestCopyOfOutputOnRootLayer(
dcheng92ae1412016-04-09 02:52:24866 std::unique_ptr<cc::CopyOutputRequest> request) {
sievers481b7fe2016-07-21 17:03:59867 root_window_->GetLayer()->RequestCopyOfOutput(std::move(request));
danakj@chromium.org2e6f39e2014-05-15 19:36:36868}
869
sievers@chromium.org41256cd2014-05-27 22:45:34870void CompositorImpl::SetNeedsAnimate() {
jdduke17112572014-12-10 23:02:59871 needs_animate_ = true;
khushalsagarcebe4942016-09-07 23:27:01872 if (!host_->IsVisible())
sievers@chromium.org41256cd2014-05-27 22:45:34873 return;
874
sievers6414a452016-04-22 21:33:20875 TRACE_EVENT0("compositor", "Compositor::SetNeedsAnimate");
sievers@chromium.org41256cd2014-05-27 22:45:34876 host_->SetNeedsAnimate();
sievers@chromium.org5aba5bc2014-05-13 22:40:59877}
878
fsamuele0f705b2016-10-01 14:07:14879cc::FrameSinkId CompositorImpl::GetFrameSinkId() {
fsamuelb6acafa2016-10-04 03:21:52880 return frame_sink_id_;
ennea487a272016-09-30 19:56:18881}
882
starazaa231112017-02-07 17:53:24883void CompositorImpl::AddChildFrameSink(const cc::FrameSinkId& frame_sink_id) {
danakjc7afae52017-06-20 21:12:41884 if (has_layer_tree_frame_sink_) {
khushalsagar31690fb2017-02-28 23:23:48885 GetSurfaceManager()->RegisterFrameSinkHierarchy(frame_sink_id_,
886 frame_sink_id);
starazaa231112017-02-07 17:53:24887 } else {
888 pending_child_frame_sink_ids_.insert(frame_sink_id);
889 }
890}
891
892void CompositorImpl::RemoveChildFrameSink(
893 const cc::FrameSinkId& frame_sink_id) {
894 auto it = pending_child_frame_sink_ids_.find(frame_sink_id);
895 if (it != pending_child_frame_sink_ids_.end()) {
896 pending_child_frame_sink_ids_.erase(it);
897 return;
898 }
khushalsagar31690fb2017-02-28 23:23:48899 GetSurfaceManager()->UnregisterFrameSinkHierarchy(frame_sink_id_,
900 frame_sink_id);
starazaa231112017-02-07 17:53:24901}
902
sievers962aa7212016-08-12 18:26:14903bool CompositorImpl::HavePendingReadbacks() {
904 return !readback_layer_tree_->children().empty();
905}
906
powei@chromium.org0809f7e22014-03-20 00:05:45907} // namespace content