Skip to content

Commit

Permalink
Add InProcessContextProvider and update InProcessCommandBuffer
Browse files Browse the repository at this point in the history
The Mus-Gpu Display Compositor will use an InProcessContextProvider and
InProcessCommandBuffer in place of SurfacesContextProvider,
GpuChannelHost, and CommandBufferProxyImpl to avoid the IPC overhead of
those classes. This CL introduces InProcessContextProvider and allows
InProcessCommandBuffer to coexist with GpuCommandBufferStubs
on the same thread.

In particular, when an InProcessCommandBuffer hits a sync token, it
will now get descheduled if specified by
InProcessCommandBuffer::Service until the token is passed. At that
point, it will finish the flush and run all the operations that have
been queued up since the command buffer was descheduled. This enables
other command buffers on the same thread to make progress.

BUG=661278
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel

Review-Url: https://codereview.chromium.org/2498053004
Cr-Commit-Position: refs/heads/master@{#433313}
  • Loading branch information
fsamuel authored and Commit bot committed Nov 18, 2016
1 parent 602bcba commit edc0c2c
Show file tree
Hide file tree
Showing 40 changed files with 915 additions and 243 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ AwRenderThreadContextProvider::AwRenderThreadContextProvider(
limits.min_transfer_buffer_size = 64 * 1024;

context_.reset(gpu::GLInProcessContext::Create(
service, surface, surface->IsOffscreen(), gfx::kNullAcceleratedWidget,
service, surface, surface->IsOffscreen(), gpu::kNullSurfaceHandle,
nullptr /* share_context */, attributes, limits, nullptr, nullptr,
nullptr));

Expand Down
4 changes: 4 additions & 0 deletions android_webview/browser/deferred_gpu_command_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,8 @@ void DeferredGpuCommandService::Release() const {
base::RefCountedThreadSafe<DeferredGpuCommandService>::Release();
}

bool DeferredGpuCommandService::BlockThreadOnWaitSyncToken() const {
return true;
}

} // namespace android_webview
1 change: 1 addition & 0 deletions android_webview/browser/deferred_gpu_command_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class DeferredGpuCommandService

void AddRef() const override;
void Release() const override;
bool BlockThreadOnWaitSyncToken() const override;

protected:
~DeferredGpuCommandService() override;
Expand Down
1 change: 1 addition & 0 deletions blimp/client/app/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ source_set("app") {
"//cc/surfaces",
"//components/safe_json",
"//components/url_formatter",
"//gpu/ipc/common",
"//skia",
"//ui/events",
"//ui/gfx/geometry",
Expand Down
21 changes: 19 additions & 2 deletions blimp/client/app/compositor/browser_compositor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,38 @@
#include "blimp/client/support/compositor/blimp_context_provider.h"
#include "cc/output/context_provider.h"

#if !defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
#include "gpu/ipc/common/gpu_surface_tracker.h"
#endif

namespace blimp {
namespace client {

BrowserCompositor::BrowserCompositor(
CompositorDependencies* compositor_dependencies)
: BlimpEmbedderCompositor(compositor_dependencies) {}

BrowserCompositor::~BrowserCompositor() = default;
BrowserCompositor::~BrowserCompositor() {
#if !defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
if (surface_handle_ != gpu::kNullSurfaceHandle)
gpu::GpuSurfaceTracker::Get()->RemoveSurface(surface_handle_);
#endif
}

void BrowserCompositor::SetAcceleratedWidget(gfx::AcceleratedWidget widget) {
scoped_refptr<cc::ContextProvider> provider;

if (widget != gfx::kNullAcceleratedWidget) {
DCHECK_EQ(gpu::kNullSurfaceHandle, surface_handle_);
#if !defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
surface_handle_ =
gpu::GpuSurfaceTracker::Get()->AddSurfaceForNativeWidget(widget);
#else
surface_handle_ = widget;
#endif
provider = BlimpContextProvider::Create(
widget, compositor_dependencies()->GetGpuMemoryBufferManager());
surface_handle_,
compositor_dependencies()->GetGpuMemoryBufferManager());
}

SetContextProvider(std::move(provider));
Expand Down
2 changes: 2 additions & 0 deletions blimp/client/app/compositor/browser_compositor.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "base/macros.h"
#include "blimp/client/support/compositor/blimp_embedder_compositor.h"
#include "gpu/ipc/common/surface_handle.h"
#include "ui/gfx/native_widget_types.h"

namespace blimp {
Expand Down Expand Up @@ -37,6 +38,7 @@ class BrowserCompositor : public BlimpEmbedderCompositor {
// BlimpEmbedderCompositor implementation.
void DidReceiveCompositorFrameAck() override;

gpu::SurfaceHandle surface_handle_ = gpu::kNullSurfaceHandle;
base::Closure did_complete_swap_buffers_;

private:
Expand Down
1 change: 1 addition & 0 deletions blimp/client/support/compositor/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ source_set("compositor") {
"//gpu/command_buffer/client:gles2_c_lib",
"//gpu/command_buffer/client:gles2_implementation",
"//gpu/ipc:gl_in_process_context",
"//gpu/ipc/common",
"//ui/gl",
]

Expand Down
6 changes: 3 additions & 3 deletions blimp/client/support/compositor/blimp_context_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ namespace client {

// static
scoped_refptr<BlimpContextProvider> BlimpContextProvider::Create(
gfx::AcceleratedWidget widget,
gpu::SurfaceHandle widget,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) {
return new BlimpContextProvider(widget, gpu_memory_buffer_manager);
}

BlimpContextProvider::BlimpContextProvider(
gfx::AcceleratedWidget widget,
gpu::SurfaceHandle widget,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) {
context_thread_checker_.DetachFromThread();

Expand All @@ -45,7 +45,7 @@ BlimpContextProvider::BlimpContextProvider(

context_.reset(gpu::GLInProcessContext::Create(
nullptr /* service */, nullptr /* surface */,
widget == gfx::kNullAcceleratedWidget /* is_offscreen */, widget,
widget == gpu::kNullSurfaceHandle /* is_offscreen */, widget,
nullptr /* share_context */, attribs_for_gles2, gpu::SharedMemoryLimits(),
gpu_memory_buffer_manager, nullptr /* memory_limits */,
base::ThreadTaskRunnerHandle::Get()));
Expand Down
5 changes: 3 additions & 2 deletions blimp/client/support/compositor/blimp_context_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
#include "cc/output/context_provider.h"
#include "gpu/ipc/common/surface_handle.h"
#include "gpu/ipc/gl_in_process_context.h"
#include "ui/gl/gl_surface.h"

Expand All @@ -27,7 +28,7 @@ namespace client {
class BlimpContextProvider : public cc::ContextProvider {
public:
static scoped_refptr<BlimpContextProvider> Create(
gfx::AcceleratedWidget widget,
gpu::SurfaceHandle widget,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);

// cc::ContextProvider implementation.
Expand All @@ -44,7 +45,7 @@ class BlimpContextProvider : public cc::ContextProvider {
const LostContextCallback& lost_context_callback) override;

protected:
BlimpContextProvider(gfx::AcceleratedWidget widget,
BlimpContextProvider(gpu::SurfaceHandle widget,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);
~BlimpContextProvider() override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "cc/output/context_provider.h"
#include "cc/surfaces/surface_manager.h"
#include "cc/trees/layer_tree_settings.h"
#include "gpu/ipc/common/surface_handle.h"

namespace blimp {
namespace client {
Expand Down Expand Up @@ -38,7 +39,7 @@ cc::FrameSinkId CompositorDependenciesImpl::AllocateFrameSinkId() {
void CompositorDependenciesImpl::GetContextProviders(
const CompositorDependencies::ContextProviderCallback& callback) {
scoped_refptr<cc::ContextProvider> compositor_context =
BlimpContextProvider::Create(gfx::kNullAcceleratedWidget,
BlimpContextProvider::Create(gpu::kNullSurfaceHandle,
gpu_memory_buffer_manager_.get());

// TODO(khushalsagar): Make a worker context and bind to the current thread.
Expand Down
1 change: 1 addition & 0 deletions blimp/client/test/compositor/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ source_set("compositor") {
deps = [
"//cc:test_support",
"//cc/proto",
"//gpu/ipc/common",
]

public_deps = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "cc/layers/layer.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "gpu/ipc/common/surface_handle.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/native_widget_types.h"

Expand All @@ -22,7 +23,7 @@ TestBlimpEmbedderCompositor::TestBlimpEmbedderCompositor(
CompositorDependencies* compositor_dependencies)
: BlimpEmbedderCompositor(compositor_dependencies) {
SetContextProvider(BlimpContextProvider::Create(
gfx::kNullAcceleratedWidget,
gpu::kNullSurfaceHandle,
compositor_dependencies->GetGpuMemoryBufferManager()));
}

Expand Down
5 changes: 5 additions & 0 deletions cc/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ component("cc") {
"output/gl_renderer.h",
"output/gl_renderer_draw_cache.cc",
"output/gl_renderer_draw_cache.h",
"output/in_process_context_provider.cc",
"output/in_process_context_provider.h",
"output/latency_info_swap_promise.cc",
"output/latency_info_swap_promise.h",
"output/layer_quad.cc",
Expand Down Expand Up @@ -584,7 +586,10 @@ component("cc") {
"//cc/proto",
"//cc/surfaces:surface_id",
"//gpu",
"//gpu/command_buffer/client:gles2_implementation",
"//gpu/command_buffer/client:gles2_interface",
"//gpu/ipc:gl_in_process_context",
"//gpu/skia_bindings:skia_bindings",
"//media",
"//third_party/libyuv",
"//ui/events:events_base",
Expand Down
14 changes: 14 additions & 0 deletions cc/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,17 @@ include_rules = [
"+ui/gl",
"-cc/blink",
]

specific_include_rules = {
"in_process_context_provider\.cc": [
"+gpu/command_buffer/client",
"+gpu/command_buffer/common",
"+gpu/command_buffer/service",
"+gpu/ipc",
"+gpu/skia_bindings",
],
"in_process_context_provider\.h": [
"+gpu/command_buffer/common",
"+gpu/ipc",
],
}
165 changes: 165 additions & 0 deletions cc/output/in_process_context_provider.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/output/in_process_context_provider.h"

#include <stdint.h>

#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/resources/platform_color.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/shader_translator_cache.h"
#include "gpu/command_buffer/service/sync_point_manager.h"
#include "gpu/ipc/common/surface_handle.h"
#include "gpu/ipc/gl_in_process_context.h"
#include "gpu/ipc/gpu_in_process_thread_service.h"
#include "gpu/ipc/in_process_command_buffer.h"
#include "gpu/skia_bindings/grcontext_for_gles2_interface.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gl/gl_share_group.h"

namespace cc {

namespace {

gpu::gles2::ContextCreationAttribHelper CreateAttributes() {
gpu::gles2::ContextCreationAttribHelper attributes;
attributes.alpha_size = -1;
attributes.depth_size = 0;
attributes.stencil_size = 0;
attributes.samples = 0;
attributes.sample_buffers = 0;
attributes.fail_if_major_perf_caveat = false;
attributes.bind_generates_resource = false;
return attributes;
}

std::unique_ptr<gpu::GLInProcessContext> CreateInProcessContext(
scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
const gpu::gles2::ContextCreationAttribHelper& attributes,
gpu::SurfaceHandle widget,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
gpu::ImageFactory* image_factory,
const gpu::SharedMemoryLimits& limits,
gpu::GLInProcessContext* shared_context) {
const bool is_offscreen = widget == gpu::kNullSurfaceHandle;
return base::WrapUnique(gpu::GLInProcessContext::Create(
service, nullptr, is_offscreen, widget, shared_context, attributes,
limits, gpu_memory_buffer_manager, image_factory,
base::ThreadTaskRunnerHandle::Get()));
}

} // namespace

InProcessContextProvider::InProcessContextProvider(
scoped_refptr<gpu::InProcessCommandBuffer::Service> service,
gpu::SurfaceHandle widget,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
gpu::ImageFactory* image_factory,
const gpu::SharedMemoryLimits& limits,
InProcessContextProvider* shared_context)
: attributes_(CreateAttributes()),
context_(CreateInProcessContext(
service,
attributes_,
widget,
gpu_memory_buffer_manager,
image_factory,
limits,
(shared_context ? shared_context->context_.get() : nullptr))) {
cache_controller_.reset(new ContextCacheController(
context_->GetImplementation(), base::ThreadTaskRunnerHandle::Get()));
}

InProcessContextProvider::~InProcessContextProvider() = default;

bool InProcessContextProvider::BindToCurrentThread() {
return !!context_;
}

gpu::gles2::GLES2Interface* InProcessContextProvider::ContextGL() {
return context_->GetImplementation();
}

gpu::ContextSupport* InProcessContextProvider::ContextSupport() {
return context_->GetImplementation();
}

class GrContext* InProcessContextProvider::GrContext() {
if (gr_context_)
return gr_context_->get();

gr_context_.reset(new skia_bindings::GrContextForGLES2Interface(ContextGL()));
return gr_context_->get();
}

ContextCacheController* InProcessContextProvider::CacheController() {
return cache_controller_.get();
}

void InProcessContextProvider::InvalidateGrContext(uint32_t state) {
if (gr_context_)
gr_context_->ResetContext(state);
}

base::Lock* InProcessContextProvider::GetLock() {
return &context_lock_;
}

gpu::Capabilities InProcessContextProvider::ContextCapabilities() {
gpu::Capabilities capabilities;
capabilities.texture_rectangle = true;
capabilities.sync_query = true;
switch (PlatformColor::Format()) {
case PlatformColor::SOURCE_FORMAT_RGBA8:
capabilities.texture_format_bgra8888 = false;
break;
case PlatformColor::SOURCE_FORMAT_BGRA8:
capabilities.texture_format_bgra8888 = true;
break;
}
return capabilities;
}

void InProcessContextProvider::SetLostContextCallback(
const LostContextCallback& lost_context_callback) {
// This code lives in the GPU process and so this would go away
// if the context is lost?
}

uint32_t InProcessContextProvider::GetCopyTextureInternalFormat() {
if (attributes_.alpha_size > 0)
return GL_RGBA;
DCHECK_NE(attributes_.red_size, 0);
DCHECK_NE(attributes_.green_size, 0);
DCHECK_NE(attributes_.blue_size, 0);
return GL_RGB;
}

void InProcessContextProvider::SetSwapBuffersCompletionCallback(
const gpu::InProcessCommandBuffer::SwapBuffersCompletionCallback&
callback) {
context_->SetSwapBuffersCompletionCallback(callback);
}

void InProcessContextProvider::SetUpdateVSyncParametersCallback(
const gpu::InProcessCommandBuffer::UpdateVSyncParametersCallback&
callback) {
context_->SetUpdateVSyncParametersCallback(callback);
}

} // namespace cc
Loading

0 comments on commit edc0c2c

Please sign in to comment.