Which compositor exists?
Aura makes browser process also use compositor. Let's classify which class is used in which case.
In renderer process
- RenderWidget owns RenderWidgetCompositor that is created by initializeLayerTreeView()
 - RenderWidgetCompositor owns cc::LayerTreeHost
 
In browser process when Aura is turned on
- [Desktop]RootWindowHost owns aura::RootWindow
 - aura::RootWindow owns ui::Compositor
 - ui::Compositor owns cc::LayerTreeHost
 
Overview
- render process: RenderWidget -> RenderWidgetCompositor : LayerTreeHostClient -> LayerTreeHost
 - browser process: RootWindow -> Compositor : LayerTreeHostClient -> LayerTreeHost
 - important relationship
- LayerTreeHost -> ThreadProxy : LayerTreeHostImplClient -> LayerTreeHostImpl
 - LayerTreeHost -> ThreadProxy : SchedulerClient -> Scheduler
 
 
OutputSurface lifecycle
Make accelerated surface or disable accelerated compositing
- WebViewImpl try to create compositor or disable accelerated compositing
void WebViewImpl::setIsAcceleratedCompositingActive(bool active) { ... m_client->initializeLayerTreeView(); m_layerTreeView = m_client->layerTreeView(); if (m_layerTreeView) { m_layerTreeView->setRootLayer(*m_rootLayer); ... } else { m_isAcceleratedCompositingActive = false; m_client->didDeactivateCompositor(); m_compositorCreationFailed = true; } ... }
 - RenderWidget::initializeLayerTreeView() fails if creating OutputSurface fails.
void RenderWidget::initializeLayerTreeView() { compositor_ = RenderWidgetCompositor::Create( this, is_threaded_compositing_enabled_); if (!compositor_) return; compositor_->setViewportSize(size_, physical_backing_size_); if (init_complete_) compositor_->setSurfaceReady(); } scoped_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create( RenderWidget* widget, bool threaded) { scoped_ptr<RenderWidgetCompositor> compositor( new RenderWidgetCompositor(widget, threaded)); CommandLine* cmd = CommandLine::ForCurrentProcess(); cc::LayerTreeSettings settings; settings.throttle_frame_production = !cmd->HasSwitch(switches::kDisableGpuVsync); // settings... if (!compositor->initialize(settings)) return scoped_ptr<RenderWidgetCompositor>(); return compositor.Pass(); } bool RenderWidgetCompositor::initialize(cc::LayerTreeSettings settings) { scoped_refptr<base::MessageLoopProxy> compositor_message_loop_proxy = RenderThreadImpl::current()->compositor_message_loop_proxy(); layer_tree_host_ = cc::LayerTreeHost::Create( this, NULL, settings, compositor_message_loop_proxy); return layer_tree_host_; } bool LayerTreeHost::Initialize( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { if (impl_task_runner.get()) return InitializeProxy(ThreadProxy::Create(this, impl_task_runner)); else return InitializeProxy(SingleThreadProxy::Create(this)); } bool LayerTreeHost::InitializeProxy(scoped_ptr<Proxy> proxy) { TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal"); scoped_ptr<OutputSurface> output_surface(CreateOutputSurface()); if (!output_surface) return false; // HERE!!! CAN FAIL!!!! proxy_ = proxy.Pass(); proxy_->Start(output_surface.Pass()); return true; } void ThreadProxy::Start(scoped_ptr<OutputSurface> first_output_surface) { DCHECK(IsMainThread()); DCHECK(Proxy::HasImplThread()); DCHECK(first_output_surface); // Create LayerTreeHostImpl. DebugScopedSetMainThreadBlocked main_thread_blocked(this); CompletionEvent completion; Proxy::ImplThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&ThreadProxy::InitializeImplOnImplThread, base::Unretained(this), &completion)); completion.Wait(); main_thread_weak_ptr_ = weak_factory_.GetWeakPtr(); first_output_surface_ = first_output_surface.Pass(); started_ = true; } void ThreadProxy::InitializeImplOnImplThread(CompletionEvent* completion) { TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread"); DCHECK(IsImplThread()); layer_tree_host_impl_ = layer_tree_host_->CreateLayerTreeHostImpl(this); const LayerTreeSettings& settings = layer_tree_host_->settings(); SchedulerSettings scheduler_settings; scheduler_settings.deadline_scheduling_enabled = settings.deadline_scheduling_enabled; scheduler_settings.impl_side_painting = settings.impl_side_painting; scheduler_settings.timeout_and_draw_when_animation_checkerboards = settings.timeout_and_draw_when_animation_checkerboards; scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = settings.maximum_number_of_failed_draws_before_draw_is_forced_; scheduler_settings.using_synchronous_renderer_compositor = settings.using_synchronous_renderer_compositor; scheduler_settings.throttle_frame_production = settings.throttle_frame_production; scheduler_on_impl_thread_ = Scheduler::Create(this, scheduler_settings); scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible()); impl_thread_weak_ptr_ = weak_factory_on_impl_thread_.GetWeakPtr(); completion->Signal(); }
 
What's happen when creating OutputSurface
what is OutputSurface
- It is something like GraphicsContext3D for LayerTreeHost
 - OutputSurface own ContextProvider that owns WebGraphicsContext3D
 
in render process
- LayerTreeHost::CreateOutputSurface() -> RenderWidgetCompositor::CreateOutputSurface() -> RenderWidget::CreateOutputSurface()
scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { ... // 1. Create ContextProvider scoped_refptr<ContextProviderCommandBuffer> context_provider; context_provider = ContextProviderCommandBuffer::Create( CreateGraphicsContext3D(attributes), "RenderCompositor"); uint32 output_surface_id = next_output_surface_id_++; if (!context_provider.get()) { /// CAN FAIL!!!! ONLY Renderer can fail. if (!command_line.HasSwitch(switches::kEnableSoftwareCompositing)) return scoped_ptr<cc::OutputSurface>(); // 2. Software fallback return scoped_ptr<cc::OutputSurface>(new CompositorOutputSurface(... } // 3. Create OutputSurface if (command_line.HasSwitch(switches::kEnableDelegatedRenderer) && !command_line.HasSwitch(switches::kDisableDelegatedRenderer)) { DCHECK(is_threaded_compositing_enabled_); return scoped_ptr<cc::OutputSurface>( new DelegatedCompositorOutputSurface( routing_id(), output_surface_id, context_provider, scoped_ptr<cc::SoftwareOutputDevice>())); } if (command_line.HasSwitch(cc::switches::kCompositeToMailbox)) { return scoped_ptr<cc::OutputSurface>( new MailboxOutputSurface( routing_id(), output_surface_id, context_provider, scoped_ptr<cc::SoftwareOutputDevice>(), format)); } bool use_swap_compositor_frame_message = false; return scoped_ptr<cc::OutputSurface>( new CompositorOutputSurface( routing_id(), output_surface_id, context_provider, scoped_ptr<cc::SoftwareOutputDevice>(), use_swap_compositor_frame_message)); }
 
In browser process
- LayerTreeHost::CreateOutputSurface() -> Compositor::CreateOutputSurface() -> GpuProcessTransportFactory::CreateOutputSurface()
scoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface( ui::Compositor* compositor) { ... scoped_refptr<ContextProviderCommandBuffer> context_provider; ... CommandLine* command_line = CommandLine::ForCurrentProcess(); if (!command_line->HasSwitch(switches::kUIEnableSoftwareCompositing)) { context_provider = ContextProviderCommandBuffer::Create( GpuProcessTransportFactory::CreateContextCommon( swap_client_weak_ptr, data->surface_id), "Compositor"); } // Software surface if (!context_provider.get()) { scoped_ptr<SoftwareBrowserCompositorOutputSurface> surface = SoftwareBrowserCompositorOutputSurface::Create( CreateSoftwareOutputDevice(compositor)); return surface.PassAs<cc::OutputSurface>(); } ... scoped_ptr<BrowserCompositorOutputSurface> surface( new BrowserCompositorOutputSurface( context_provider, per_compositor_data_[compositor]->surface_id, &output_surface_map_, base::MessageLoopProxy::current().get(), compositor->AsWeakPtr())); ... return surface.PassAs<cc::OutputSurface>(); }
 
NOTE: Failure of OutputSurface creation.
- If Browser process fails, it creates SoftwareBrowserCompositorOutputSurface.
 - If Render process fails and !kEnableSoftwareCompositing, it does not create OutputSurface.
- and Render process does not do accelerated compositing.
 
 
What's happen when creating ContextProviderCommandBuffer
- OutputSurface -> ContextProviderCommandBuffer -> WebGraphicsContext3DCommandBufferImpl -> GLES2Implementation
 - Under WebGraphicsContext3D, refer to How GPU Process work in multi process
 
scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) {
  ...
  scoped_refptr<ContextProviderCommandBuffer> context_provider;
  if (!fallback) {
    context_provider = ContextProviderCommandBuffer::Create(
        CreateGraphicsContext3D(attributes),
        "RenderCompositor");
  }
  ...
}
scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
RenderWidget::CreateGraphicsContext3D(
    const WebKit::WebGraphicsContext3D::Attributes& attributes) {
  ...
  scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
      new WebGraphicsContext3DCommandBufferImpl(
          surface_id(),
          GetURLForGraphicsContext3D(),
          gpu_channel_host.get(),
          swap_client,
          attributes,
          false /* bind generates resources */,
          limits));
  return context.Pass();
}
How impl thread get ownership of gl context.
// in impl thread
void Scheduler::ProcessScheduledActions() {
  ...
    action = state_machine_.NextAction();
  ...
    switch (action) {
  ...
      case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
        client_->ScheduledActionBeginOutputSurfaceCreation();
        break;
  ...
}
void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
  ...
  Proxy::MainThreadTaskRunner()->PostTask(
      FROM_HERE,
      base::Bind(&ThreadProxy::CreateAndInitializeOutputSurface,
                 main_thread_weak_ptr_));
}
in main thread
void ThreadProxy::CreateAndInitializeOutputSurface() {
  ...
  layer_tree_host_->DidLoseOutputSurface();
  output_surface_creation_callback_.Reset(base::Bind(
      &ThreadProxy::DoCreateAndInitializeOutputSurface,
      base::Unretained(this)));
  output_surface_creation_callback_.callback().Run();
}
void ThreadProxy::DoCreateAndInitializeOutputSurface() {
  ...
  scoped_ptr<OutputSurface> output_surface = first_output_surface_.Pass();
  if (!output_surface)
    // when reusing compositor
    output_surface = layer_tree_host_->CreateOutputSurface();
  RendererCapabilities capabilities;
  bool success = !!output_surface;
  if (!success) {
    OnOutputSurfaceInitializeAttempted(false, capabilities);
    return;
  }
  scoped_refptr<ContextProvider> offscreen_context_provider;
  // if filter exists,
  if (created_offscreen_context_provider_) {
    offscreen_context_provider =
        layer_tree_host_->client()->OffscreenContextProvider();
    success = !!offscreen_context_provider.get();
    if (!success) {
      OnOutputSurfaceInitializeAttempted(false, capabilities);
      return;
    }
  }
  success = false;
  {
    // Make a blocking call to InitializeOutputSurfaceOnImplThread. The results
    // of that call are pushed into the success and capabilities local
    // variables.
    CompletionEvent completion;
    DebugScopedSetMainThreadBlocked main_thread_blocked(this);
    Proxy::ImplThreadTaskRunner()->PostTask(
        FROM_HERE,
        base::Bind(&ThreadProxy::InitializeOutputSurfaceOnImplThread,
                   impl_thread_weak_ptr_,
                   &completion,
                   base::Passed(&output_surface),
                   offscreen_context_provider,
                   &success,
                   &capabilities));
    // Main thread waits for impl thread done.
    completion.Wait();
  }
  OnOutputSurfaceInitializeAttempted(success, capabilities);
}
in impl thread
void ThreadProxy::InitializeOutputSurfaceOnImplThread(
    CompletionEvent* completion,
    scoped_ptr<OutputSurface> output_surface,
    scoped_refptr<ContextProvider> offscreen_context_provider,
    bool* success,
    RendererCapabilities* capabilities) {
  ...
  *success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
  ...
}
bool LayerTreeHostImpl::InitializeRenderer(
    scoped_ptr<OutputSurface> output_surface) {
  ...
  // Note: order is important here.
  renderer_.reset();
  tile_manager_.reset();
  resource_provider_.reset();
  output_surface_.reset();
  // Create or Own above important instances in reverse order
  if (!output_surface->BindToClient(this))
    return false;
  scoped_ptr<ResourceProvider> resource_provider =
      ResourceProvider::Create(output_surface.get(),
                               shared_bitmap_manager_,
                               settings_.highp_threshold_min,
                               settings_.use_rgba_4444_textures,
                               settings_.texture_id_allocation_chunk_size);
  if (!resource_provider)
    return false;
  if (output_surface->capabilities().deferred_gl_initialization)
    EnforceZeroBudget(true);
  bool skip_gl_renderer = false;
  CreateAndSetRenderer(
      output_surface.get(), resource_provider.get(), skip_gl_renderer);
  if (!renderer_)
    return false;
  if (settings_.impl_side_painting) {
    CreateAndSetTileManager(resource_provider.get(),
                            output_surface->context_provider().get(),
                            GetRendererCapabilities().using_map_image);
  }
  // Setup BeginImplFrameEmulation if it's not supported natively
  if (!settings_.begin_impl_frame_scheduling_enabled) {
    const base::TimeDelta display_refresh_interval =
      base::TimeDelta::FromMicroseconds(
          base::Time::kMicrosecondsPerSecond /
          settings_.refresh_rate);
    output_surface->InitializeBeginImplFrameEmulation(
        proxy_->ImplThreadTaskRunner(),
        settings_.throttle_frame_production,
        display_refresh_interval);
  }
  int max_frames_pending =
      output_surface->capabilities().max_frames_pending;
  if (max_frames_pending <= 0)
    max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING;
  output_surface->SetMaxFramesPending(max_frames_pending);
  resource_provider_ = resource_provider.Pass();
  output_surface_ = output_surface.Pass();
  client_->OnCanDrawStateChanged(CanDraw());
  return true;
}
- Q: Why this complex ownership transfer of OutputSurface is needed?
- A: unfortunately, connecting GPU Process IPC is possible in only main thread.
 
 - Note
- TileManager in LayerTreeHostImpl is created if impl-side painting.
 - LayerTreeHost owns PrioritizedResourceManager if not impl-side painting.
 - ResourceProvider in LayerTreeHostImpl is null if software rendering mode.
 - Renderer consists of GLRenderer, SoftwareRenderer and DelegatingRenderer
 
 - Important relationship
- LayerTreeHostImpl : RendererClient -> Renderer
 - LayerTreeHostImpl : TileManagerClient -> TileManager
 - LayerTreeHostImpl : OutputSurfaceClient -> OutputSurface
 
 
Complexity originated by Android SynchronousCompositor
LayerTreeHostImpl, OutputSurface and etc.. has special methods only for Android. Ignore it when reading code.
- How to go through this fxxx code. When SynchronousCompositorFactory::GetInstance() exists,
- AwContents -> InProcessViewRenderer -...-> SynchronousCompositor -> SynchronousCompositorOutputSurface
 
 
scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) {
#if defined(OS_ANDROID)
  if (SynchronousCompositorFactory* factory =
      SynchronousCompositorFactory::GetInstance()) {
    return factory->CreateOutputSurface(routing_id());
  }
#endif
  ...
}
scoped_refptr<cc::ContextProvider>
RenderThreadImpl::SharedMainThreadContextProvider() {
  DCHECK(IsMainThread());
#if defined(OS_ANDROID)
  if (SynchronousCompositorFactory* factory =
      SynchronousCompositorFactory::GetInstance())
    return factory->GetOffscreenContextProviderForMainThread();
#endif
  ...
}
- What kind of methods exists
 
// Use ContextProviderInProcess instead of ContextProviderCommandBuffer
// Call OutputSurface::InitializeAndSetContext3d()
bool SynchronousCompositorOutputSurface::InitializeHwDraw(
    scoped_refptr<gfx::GLSurface> surface,
    scoped_refptr<cc::ContextProvider> offscreen_context_provider) {
  DCHECK(CalledOnValidThread());
  DCHECK(HasClient());
  DCHECK(!context_provider_);
  DCHECK(surface);
  scoped_refptr<cc::ContextProvider> onscreen_context_provider =
      webkit::gpu::ContextProviderInProcess::Create(
          CreateWebGraphicsContext3D(surface), "SynchronousCompositor");
  return InitializeAndSetContext3d(onscreen_context_provider,
                                   offscreen_context_provider);
}
// Only here use LayerTreeHostImpl::DeferredInitialize(). Time to blame.
bool OutputSurface::InitializeAndSetContext3d(
  ..
    if (client_->DeferredInitialize(offscreen_context_provider))
  ..
}
// Only here use LayerTreeHostImpl::ReleaseGL(). Time to blame.
void SynchronousCompositorOutputSurface::ReleaseHwDraw() {
  cc::OutputSurface::ReleaseGL();
}
TINN GOLD LLC - ITALIAN Art | TINN GOLD LLC
ReplyDeleteTINN ford edge titanium GOLD LLC. $2.00 CAD (tax) ion titanium hair color / 0.10%. FREE titanium curling iron shipping babyliss nano titanium at TINN GOLD LLC. TINN GOLD LLC. titanium block