Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1032)

Unified Diff: content/browser/renderer_host/compositor_impl_android.cc

Issue 2190033002: content: Add ContextProviderFactory to create a render ContextProvider. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove display_ DCHECK. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/compositor_impl_android.cc
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 53bc1404a7c37f313f981727b278adc320c85a5e..db423ccb31f8d85f5078207c3ba47dfc6b296197 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -44,16 +44,15 @@
#include "cc/surfaces/display_scheduler.h"
#include "cc/surfaces/surface_display_output_surface.h"
#include "cc/surfaces/surface_id_allocator.h"
-#include "cc/surfaces/surface_manager.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_settings.h"
#include "components/display_compositor/compositor_overlay_candidate_validator_android.h"
#include "components/display_compositor/gl_helper.h"
#include "content/browser/android/child_process_launcher_android.h"
-#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
+#include "content/browser/renderer_host/context_provider_factory_impl_android.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/common/host_shared_bitmap_manager.h"
@@ -82,6 +81,64 @@ namespace {
const unsigned int kMaxDisplaySwapBuffers = 1U;
+gpu::SharedMemoryLimits GetCompositorContextSharedMemoryLimits() {
+ constexpr size_t kBytesPerPixel = 4;
+ const size_t full_screen_texture_size_in_bytes =
+ gfx::DeviceDisplayInfo().GetDisplayHeight() *
+ gfx::DeviceDisplayInfo().GetDisplayWidth() * kBytesPerPixel;
+
+ gpu::SharedMemoryLimits limits;
+ // This limit is meant to hold the contents of the display compositor
+ // drawing the scene. See discussion here:
+ // https://codereview.chromium.org/1900993002/diff/90001/content/browser/renderer_host/compositor_impl_android.cc?context=3&column_width=80&tab_spaces=8
+ limits.command_buffer_size = 64 * 1024;
+ // These limits are meant to hold the uploads for the browser UI without
+ // any excess space.
+ limits.start_transfer_buffer_size = 64 * 1024;
+ limits.min_transfer_buffer_size = 64 * 1024;
+ limits.max_transfer_buffer_size = full_screen_texture_size_in_bytes;
+ // Texture uploads may use mapped memory so give a reasonable limit for
+ // them.
+ limits.mapped_memory_reclaim_limit = full_screen_texture_size_in_bytes;
+
+ return limits;
+}
+
+gpu::gles2::ContextCreationAttribHelper GetCompositorContextAttributes(
+ bool has_transparent_background) {
+ // This is used for the browser compositor (offscreen) and for the display
+ // compositor (onscreen), so ask for capabilities needed by either one.
+ // The default framebuffer for an offscreen context is not used, so it does
+ // not need alpha, stencil, depth, antialiasing. The display compositor does
+ // not use these things either, except for alpha when it has a transparent
+ // background.
+ gpu::gles2::ContextCreationAttribHelper attributes;
+ attributes.alpha_size = -1;
+ attributes.stencil_size = 0;
+ attributes.depth_size = 0;
+ attributes.samples = 0;
+ attributes.sample_buffers = 0;
+ attributes.bind_generates_resource = false;
+
+ if (has_transparent_background) {
+ attributes.alpha_size = 8;
+ } else if (base::SysInfo::IsLowEndDevice()) {
+ // In this case we prefer to use RGB565 format instead of RGBA8888 if
+ // possible.
+ // TODO(danakj): GpuCommandBufferStub constructor checks for alpha == 0 in
+ // order to enable 565, but it should avoid using 565 when -1s are
+ // specified
+ // (IOW check that a <= 0 && rgb > 0 && rgb <= 565) then alpha should be
+ // -1.
+ attributes.alpha_size = 0;
+ attributes.red_size = 5;
+ attributes.green_size = 6;
+ attributes.blue_size = 5;
+ }
+
+ return attributes;
+}
+
class ExternalBeginFrameSource : public cc::BeginFrameSource,
public CompositorImpl::VSyncObserver {
public:
@@ -287,16 +344,8 @@ class VulkanOutputSurface : public cc::OutputSurface {
};
#endif
-base::LazyInstance<scoped_refptr<cc::VulkanInProcessContextProvider>>
- g_shared_vulkan_context_provider_android_ = LAZY_INSTANCE_INITIALIZER;
-
static bool g_initialized = false;
-base::LazyInstance<cc::SurfaceManager> g_surface_manager =
- LAZY_INSTANCE_INITIALIZER;
-
-int g_surface_client_id = 0;
-
class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner {
public:
SingleThreadTaskGraphRunner() {
@@ -330,34 +379,11 @@ bool CompositorImpl::IsInitialized() {
return g_initialized;
}
-// static
-cc::SurfaceManager* CompositorImpl::GetSurfaceManager() {
- return g_surface_manager.Pointer();
-}
-
-// static
-uint32_t CompositorImpl::AllocateSurfaceClientId() {
- return ++g_surface_client_id;
-}
-
-// static
-scoped_refptr<cc::VulkanInProcessContextProvider>
-CompositorImpl::SharedVulkanContextProviderAndroid() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableVulkan)) {
- scoped_refptr<cc::VulkanInProcessContextProvider>* context_provider =
- g_shared_vulkan_context_provider_android_.Pointer();
- if (!*context_provider)
- *context_provider = cc::VulkanInProcessContextProvider::Create();
- return *context_provider;
- }
- return nullptr;
-}
-
CompositorImpl::CompositorImpl(CompositorClient* client,
gfx::NativeWindow root_window)
: surface_id_allocator_(
- new cc::SurfaceIdAllocator(AllocateSurfaceClientId())),
+ new cc::SurfaceIdAllocator(ui::ContextProviderFactory::GetInstance()
+ ->AllocateSurfaceClientId())),
resource_manager_(root_window),
has_transparent_background_(false),
device_scale_factor_(1),
@@ -371,8 +397,9 @@ CompositorImpl::CompositorImpl(CompositorClient* client,
output_surface_request_pending_(false),
needs_begin_frames_(false),
weak_factory_(this) {
- GetSurfaceManager()->RegisterSurfaceClientId(
- surface_id_allocator_->client_id());
+ ui::ContextProviderFactory::GetInstance()
+ ->GetSurfaceManager()
+ ->RegisterSurfaceClientId(surface_id_allocator_->client_id());
DCHECK(client);
DCHECK(root_window);
DCHECK(root_window->GetLayer() == nullptr);
@@ -387,8 +414,9 @@ CompositorImpl::~CompositorImpl() {
root_window_->SetLayer(nullptr);
// Clean-up any surface references.
SetSurface(NULL);
- GetSurfaceManager()->InvalidateSurfaceClientId(
- surface_id_allocator_->client_id());
+ ui::ContextProviderFactory::GetInstance()
+ ->GetSurfaceManager()
+ ->InvalidateSurfaceClientId(surface_id_allocator_->client_id());
}
ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() {
@@ -490,12 +518,11 @@ void CompositorImpl::SetVisible(bool visible) {
if (!host_->output_surface_lost())
host_->ReleaseOutputSurface();
pending_swapbuffers_ = 0;
- establish_gpu_channel_timeout_.Stop();
display_.reset();
} else {
host_->SetVisible(true);
if (output_surface_request_pending_)
- RequestNewOutputSurface();
+ HandlePendingOutputSurfaceRequest();
}
}
@@ -538,38 +565,12 @@ void CompositorImpl::UpdateLayerTreeHost() {
}
}
-void CompositorImpl::OnGpuChannelEstablished() {
- establish_gpu_channel_timeout_.Stop();
- CreateOutputSurface();
-}
-
-void CompositorImpl::OnGpuChannelTimeout() {
- LOG(FATAL) << "Timed out waiting for GPU channel.";
-}
-
void CompositorImpl::RequestNewOutputSurface() {
- output_surface_request_pending_ = true;
-
-#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
- defined(SYZYASAN) || defined(CYGPROFILE_INSTRUMENTATION)
- const int64_t kGpuChannelTimeoutInSeconds = 40;
-#else
- const int64_t kGpuChannelTimeoutInSeconds = 10;
-#endif
+ DCHECK(!output_surface_request_pending_)
+ << "Output Surface Request is already pending?";
- BrowserGpuChannelHostFactory* factory =
- BrowserGpuChannelHostFactory::instance();
- if (!factory->GetGpuChannel()) {
- factory->EstablishGpuChannel(
- base::Bind(&CompositorImpl::OnGpuChannelEstablished,
- weak_factory_.GetWeakPtr()));
- establish_gpu_channel_timeout_.Start(
- FROM_HERE, base::TimeDelta::FromSeconds(kGpuChannelTimeoutInSeconds),
- this, &CompositorImpl::OnGpuChannelTimeout);
- return;
- }
-
- CreateOutputSurface();
+ output_surface_request_pending_ = true;
+ HandlePendingOutputSurfaceRequest();
}
void CompositorImpl::DidInitializeOutputSurface() {
@@ -581,24 +582,44 @@ void CompositorImpl::DidFailToInitializeOutputSurface() {
LOG(ERROR) << "Failed to init OutputSurface for compositor.";
LOG_IF(FATAL, ++num_successive_context_creation_failures_ >= 2)
<< "Too many context creation failures. Giving up... ";
- RequestNewOutputSurface();
+ HandlePendingOutputSurfaceRequest();
}
-void CompositorImpl::CreateOutputSurface() {
- // We might have had a request from a LayerTreeHost that was then
- // hidden (and hidden means we don't have a native surface).
- // Also make sure we only handle this once.
- if (!output_surface_request_pending_ || !host_->visible())
+void CompositorImpl::HandlePendingOutputSurfaceRequest() {
+ DCHECK(output_surface_request_pending_);
+
+ // We might have been made invisible now.
+ if (!host_->visible())
return;
- scoped_refptr<ContextProviderCommandBuffer> context_provider;
- scoped_refptr<cc::VulkanInProcessContextProvider> vulkan_context_provider =
- SharedVulkanContextProviderAndroid();
- std::unique_ptr<cc::OutputSurface> display_output_surface;
#if defined(ENABLE_VULKAN)
- std::unique_ptr<VulkanOutputSurface> vulkan_surface;
+ CreateVulkanOutputSurface()
+ if (display_)
+ return;
+#endif
+
+ DCHECK(surface_handle_ != gpu::kNullSurfaceHandle);
+
+ ContextProviderFactoryImpl::GetInstance()->CreateDisplayContextProvider(
+ surface_handle_, GetCompositorContextSharedMemoryLimits(),
+ GetCompositorContextAttributes(has_transparent_background_),
+ false /*support_locking*/, false /*automatic_flushes*/,
+ base::Bind(&CompositorImpl::CreateCompositorOutputSurface,
+ weak_factory_.GetWeakPtr()));
+}
+
+#if defined(ENABLE_VULKAN)
+void CompositorImpl::CreateVulkanOutputSurface() {
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableVulkan))
+ return;
+
+ std::unique_ptr<cc::OutputSurface> display_output_surface;
+ scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider =
+ ui::ContextProviderFactory::GetInstance()
+ ->GetSharedVulkanContextProvider();
if (vulkan_context_provider) {
- vulkan_surface.reset(
+ std::unique_ptr<VulkanOutputSurface> vulkan_surface(
new VulkanOutputSurface(std::move(vulkan_context_provider)));
if (!vulkan_surface->Initialize(window_)) {
vulkan_surface->Destroy();
@@ -607,91 +628,48 @@ void CompositorImpl::CreateOutputSurface() {
display_output_surface = std::move(vulkan_surface);
}
}
-#endif
- if (!display_output_surface) {
- // This is used for the browser compositor (offscreen) and for the display
- // compositor (onscreen), so ask for capabilities needed by either one.
- // The default framebuffer for an offscreen context is not used, so it does
- // not need alpha, stencil, depth, antialiasing. The display compositor does
- // not use these things either, except for alpha when it has a transparent
- // background.
- gpu::gles2::ContextCreationAttribHelper attributes;
- attributes.alpha_size = -1;
- attributes.stencil_size = 0;
- attributes.depth_size = 0;
- attributes.samples = 0;
- attributes.sample_buffers = 0;
- attributes.bind_generates_resource = false;
-
- if (has_transparent_background_) {
- attributes.alpha_size = 8;
- } else if (base::SysInfo::IsLowEndDevice()) {
- // In this case we prefer to use RGB565 format instead of RGBA8888 if
- // possible.
- // TODO(danakj): GpuCommandBufferStub constructor checks for alpha == 0 in
- // order to enable 565, but it should avoid using 565 when -1s are
- // specified
- // (IOW check that a <= 0 && rgb > 0 && rgb <= 565) then alpha should be
- // -1.
- attributes.alpha_size = 0;
- attributes.red_size = 5;
- attributes.green_size = 6;
- attributes.blue_size = 5;
- }
-
- pending_swapbuffers_ = 0;
-
- DCHECK(window_);
- DCHECK_NE(surface_handle_, gpu::kNullSurfaceHandle);
-
- BrowserGpuChannelHostFactory* factory =
- BrowserGpuChannelHostFactory::instance();
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(
- factory->GetGpuChannel());
- // If the channel was already lost, we'll get null back here and need to
- // try again.
- if (!gpu_channel_host) {
- RequestNewOutputSurface();
- return;
- }
+ if (!display_output_surface)
+ return;
- GURL url("chrome://gpu/CompositorImpl::CreateOutputSurface");
- constexpr bool automatic_flushes = false;
- constexpr bool support_locking = false;
-
- constexpr size_t kBytesPerPixel = 4;
- const size_t full_screen_texture_size_in_bytes =
- gfx::DeviceDisplayInfo().GetDisplayHeight() *
- gfx::DeviceDisplayInfo().GetDisplayWidth() * kBytesPerPixel;
-
- gpu::SharedMemoryLimits limits;
- // This limit is meant to hold the contents of the display compositor
- // drawing the scene. See discussion here:
- // https://codereview.chromium.org/1900993002/diff/90001/content/browser/renderer_host/compositor_impl_android.cc?context=3&column_width=80&tab_spaces=8
- limits.command_buffer_size = 64 * 1024;
- // These limits are meant to hold the uploads for the browser UI without
- // any excess space.
- limits.start_transfer_buffer_size = 64 * 1024;
- limits.min_transfer_buffer_size = 64 * 1024;
- limits.max_transfer_buffer_size = full_screen_texture_size_in_bytes;
- // Texture uploads may use mapped memory so give a reasonable limit for
- // them.
- limits.mapped_memory_reclaim_limit = full_screen_texture_size_in_bytes;
-
- context_provider = new ContextProviderCommandBuffer(
- std::move(gpu_channel_host), gpu::GPU_STREAM_DEFAULT,
- gpu::GpuStreamPriority::NORMAL, surface_handle_, url, automatic_flushes,
- support_locking, limits, attributes, nullptr,
- command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
- DCHECK(context_provider.get());
-
- display_output_surface = base::WrapUnique(new OutputSurfaceWithoutParent(
- context_provider, base::Bind(&CompositorImpl::PopulateGpuCapabilities,
- base::Unretained(this))));
- }
+ InitializeDisplay(std::move(display_output_surface),
+ std::move(vulkan_context_provider), nullptr);
+}
+#endif
- cc::SurfaceManager* manager = GetSurfaceManager();
+void CompositorImpl::CreateCompositorOutputSurface(
+ const scoped_refptr<cc::ContextProvider>& context_provider) {
+ // This callback should run only if we have a pending output surface request,
+ // since that is when we should have queued a context request.
+ // In case the surface was invalidated after the context request was queued,
+ // the request should have been dropped by the ContextProviderFactory.
+ DCHECK(output_surface_request_pending_);
+ DCHECK(host_->visible());
+ DCHECK(window_);
+ DCHECK_NE(surface_handle_, gpu::kNullSurfaceHandle);
+ DCHECK(context_provider);
+
+ scoped_refptr<ContextProviderCommandBuffer> context_provider_command_buffer =
+ static_cast<ContextProviderCommandBuffer*>(context_provider.get());
+ std::unique_ptr<cc::OutputSurface> display_output_surface(
+ new OutputSurfaceWithoutParent(
+ context_provider_command_buffer,
+ base::Bind(&CompositorImpl::PopulateGpuCapabilities,
+ base::Unretained(this))));
+ InitializeDisplay(std::move(display_output_surface), nullptr,
+ std::move(context_provider));
+}
+
+void CompositorImpl::InitializeDisplay(
+ std::unique_ptr<cc::OutputSurface> display_output_surface,
+ scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider,
+ scoped_refptr<cc::ContextProvider> context_provider) {
+ DCHECK(output_surface_request_pending_);
+
+ pending_swapbuffers_ = 0;
+
+ cc::SurfaceManager* manager =
+ ui::ContextProviderFactory::GetInstance()->GetSurfaceManager();
auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
std::unique_ptr<ExternalBeginFrameSource> begin_frame_source(
new ExternalBeginFrameSource(this));
@@ -707,14 +685,12 @@ void CompositorImpl::CreateOutputSurface() {
base::MakeUnique<cc::TextureMailboxDeleter>(task_runner)));
std::unique_ptr<cc::SurfaceDisplayOutputSurface> delegated_output_surface(
- vulkan_context_provider
- ? new cc::SurfaceDisplayOutputSurface(
- manager, surface_id_allocator_.get(), display_.get(),
- static_cast<scoped_refptr<cc::VulkanContextProvider>>(
- vulkan_context_provider))
- : new cc::SurfaceDisplayOutputSurface(
- manager, surface_id_allocator_.get(), display_.get(),
- context_provider, nullptr));
+ vulkan_context_provider ? new cc::SurfaceDisplayOutputSurface(
+ manager, surface_id_allocator_.get(),
+ display_.get(), vulkan_context_provider)
+ : new cc::SurfaceDisplayOutputSurface(
+ manager, surface_id_allocator_.get(),
+ display_.get(), context_provider, nullptr));
display_->Resize(size_);
host_->SetOutputSurface(std::move(delegated_output_surface));

Powered by Google App Engine
This is Rietveld 408576698