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

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

Issue 1921533008: Add support for OutputSurface for Vulkan on Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix rebase error. Created 4 years, 7 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
« no previous file with comments | « content/browser/renderer_host/compositor_impl_android.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 3c58174ed68cf624b779d748e15c8c3006ad35cb..b0c00a36de9c6851c4844da14c394df8fd87290e 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -35,6 +35,7 @@
#include "cc/output/context_provider.h"
#include "cc/output/output_surface.h"
#include "cc/output/output_surface_client.h"
+#include "cc/output/vulkan_in_process_context_provider.h"
#include "cc/raster/single_thread_task_graph_runner.h"
#include "cc/scheduler/begin_frame_source.h"
#include "cc/surfaces/onscreen_display_client.h"
@@ -61,6 +62,7 @@
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/ipc/client/command_buffer_proxy_impl.h"
#include "gpu/ipc/client/gpu_channel_host.h"
+#include "gpu/vulkan/vulkan_surface.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkMallocPixelRef.h"
@@ -221,6 +223,60 @@ class OutputSurfaceWithoutParent : public cc::OutputSurface,
std::unique_ptr<ExternalBeginFrameSource> begin_frame_source_;
};
+#if defined(ENABLE_VULKAN)
+class VulkanOutputSurface : public cc::OutputSurface {
+ public:
+ VulkanOutputSurface(
+ scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider)
+ : OutputSurface(nullptr,
+ nullptr,
+ std::move(vulkan_context_provider),
+ nullptr) {}
+
+ ~VulkanOutputSurface() override { Destroy(); }
+
+ bool Initialize(gfx::AcceleratedWidget widget) {
+ DCHECK(!surface_);
+ std::unique_ptr<gpu::VulkanSurface> surface(
+ gpu::VulkanSurface::CreateViewSurface(widget));
+ if (!surface->Initialize(vulkan_context_provider()->GetDeviceQueue(),
+ gpu::VulkanSurface::DEFAULT_SURFACE_FORMAT)) {
+ return false;
+ }
+ surface_ = std::move(surface);
+
+ return true;
+ }
+
+ void SwapBuffers(cc::CompositorFrame* frame) override {
+ surface_->SwapBuffers();
+ PostSwapBuffersComplete();
+ client_->DidSwapBuffers();
+ }
+
+ void Destroy() {
+ if (surface_) {
+ surface_->Destroy();
+ surface_.reset();
+ }
+ }
+
+ void OnSwapBuffersCompleted(const std::vector<ui::LatencyInfo>& latency_info,
+ gfx::SwapResult result) {
+ RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
+ OutputSurface::OnSwapBuffersComplete();
+ }
+
+ private:
+ std::unique_ptr<gpu::VulkanSurface> surface_;
+
+ DISALLOW_COPY_AND_ASSIGN(VulkanOutputSurface);
+};
+#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 =
@@ -277,6 +333,20 @@ CompositorImpl::CreateSurfaceIdAllocator() {
return allocator;
}
+// 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 == NULL)
+ *context_provider = cc::VulkanInProcessContextProvider::Create();
+ return *context_provider;
+ }
+ return nullptr;
+}
+
CompositorImpl::CompositorImpl(CompositorClient* client,
gfx::NativeWindow root_window)
: root_layer_(cc::Layer::Create()),
@@ -507,82 +577,104 @@ void CompositorImpl::CreateOutputSurface() {
if (!output_surface_request_pending_ || !host_->visible())
return;
- // 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;
+ scoped_refptr<ContextProviderCommandBuffer> context_provider;
+ scoped_refptr<cc::VulkanInProcessContextProvider> vulkan_context_provider =
+ SharedVulkanContextProviderAndroid();
+ std::unique_ptr<cc::OutputSurface> real_output_surface;
+#if defined(ENABLE_VULKAN)
+ std::unique_ptr<VulkanOutputSurface> vulkan_surface;
+ if (vulkan_context_provider) {
+ vulkan_surface.reset(
+ new VulkanOutputSurface(std::move(vulkan_context_provider)));
+ if (!vulkan_surface->Initialize(window_)) {
+ vulkan_surface->Destroy();
+ vulkan_surface.reset();
+ } else {
+ real_output_surface = std::move(vulkan_surface);
+ }
}
+#endif
- pending_swapbuffers_ = 0;
+ if (!real_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;
+ }
- DCHECK(window_);
- DCHECK_NE(surface_handle_, gpu::kNullSurfaceHandle);
+ pending_swapbuffers_ = 0;
- BrowserGpuChannelHostFactory* factory =
- BrowserGpuChannelHostFactory::instance();
- // This channel might be lost (and even if it isn't right now, it might
- // still get marked as lost from the IO thread, at any point in time really).
- // But from here on just try and always lead to either
- // DidInitializeOutputSurface() or DidFailToInitializeOutputSurface().
- scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(factory->GetGpuChannel());
-
- GURL url("chrome://gpu/CompositorImpl::CreateOutputSurface");
- constexpr bool automatic_flushes = 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;
-
- scoped_refptr<ContextProviderCommandBuffer> context_provider(
- new ContextProviderCommandBuffer(
- std::move(gpu_channel_host), surface_handle_, url,
- gfx::PreferIntegratedGpu, automatic_flushes, limits, attributes,
- nullptr,
- command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT));
- DCHECK(context_provider.get());
-
- std::unique_ptr<cc::OutputSurface> real_output_surface(
- new OutputSurfaceWithoutParent(
- this, context_provider,
- base::Bind(&CompositorImpl::PopulateGpuCapabilities,
- base::Unretained(this)),
- base::WrapUnique(new ExternalBeginFrameSource(this))));
+ DCHECK(window_);
+ DCHECK_NE(surface_handle_, gpu::kNullSurfaceHandle);
+
+ BrowserGpuChannelHostFactory* factory =
+ BrowserGpuChannelHostFactory::instance();
+ // This channel might be lost (and even if it isn't right now, it might
+ // still get marked as lost from the IO thread, at any point in time
+ // really).
+ // But from here on just try and always lead to either
+ // DidInitializeOutputSurface() or DidFailToInitializeOutputSurface().
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host(
+ factory->GetGpuChannel());
+
+ GURL url("chrome://gpu/CompositorImpl::CreateOutputSurface");
+ constexpr bool automatic_flushes = 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), surface_handle_, url,
+ gfx::PreferIntegratedGpu, automatic_flushes, limits, attributes,
+ nullptr, command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
+ DCHECK(context_provider.get());
+
+ real_output_surface = base::WrapUnique(new OutputSurfaceWithoutParent(
+ this, context_provider,
+ base::Bind(&CompositorImpl::PopulateGpuCapabilities,
+ base::Unretained(this)),
+ base::WrapUnique(new ExternalBeginFrameSource(this))));
+ }
cc::SurfaceManager* manager = GetSurfaceManager();
display_client_.reset(new cc::OnscreenDisplayClient(
@@ -591,9 +683,16 @@ void CompositorImpl::CreateOutputSurface() {
BrowserGpuMemoryBufferManager::current(),
host_->settings().renderer_settings, base::ThreadTaskRunnerHandle::Get(),
surface_id_allocator_->id_namespace()));
+
std::unique_ptr<cc::SurfaceDisplayOutputSurface> surface_output_surface(
- new cc::SurfaceDisplayOutputSurface(manager, surface_id_allocator_.get(),
- context_provider, nullptr));
+ vulkan_context_provider
+ ? new cc::SurfaceDisplayOutputSurface(
+ manager, surface_id_allocator_.get(),
+ static_cast<scoped_refptr<cc::VulkanContextProvider>>(
+ vulkan_context_provider))
+ : new cc::SurfaceDisplayOutputSurface(manager,
+ surface_id_allocator_.get(),
+ context_provider, nullptr));
display_client_->set_surface_output_surface(surface_output_surface.get());
surface_output_surface->set_display_client(display_client_.get());
« no previous file with comments | « content/browser/renderer_host/compositor_impl_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698