Commit 4ecdf213 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Support Android SurfaceControl with SkiaRenderer + Vulkan

This CL makes SkiaOutputDeviceBufferQueue work with Vulkan.
It creates GLSurfaceEGLSurfaceControl for
SkiaOutputDeviceBufferQueue. So SkiaOutputDeviceBufferQueue
and SkiaOutputSurfaceImplOnGPU can use this GLSurface to
present the SharedImage (AHardwareBuffer) as an overlay.

TODO:
* Refactor GL unrelated code out of GLSurfaceEGLSurfaceControl,
so we can used them for both GL and vulkan.
* Remove GL dependencies from SkiaOutputDeviceBufferQueue

Bug: 1012401
Change-Id: Ic58e82d9f3cde86ac1601dc4f330a4309bff6178
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1931376Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719394}
parent c8ca44dc
......@@ -117,6 +117,12 @@ SkiaOutputSurfaceDependencyWebView::CreateGLSurface(
return gl_surface_;
}
base::ScopedClosureRunner SkiaOutputSurfaceDependencyWebView::CacheGLSurface(
gl::GLSurface* surface) {
NOTREACHED();
return base::ScopedClosureRunner();
}
void SkiaOutputSurfaceDependencyWebView::RegisterDisplayContext(
gpu::DisplayContext* display_context) {
// No GpuChannelManagerDelegate here, so leave it no-op for now.
......
......@@ -45,6 +45,7 @@ class SkiaOutputSurfaceDependencyWebView
gpu::SurfaceHandle GetSurfaceHandle() override;
scoped_refptr<gl::GLSurface> CreateGLSurface(
base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub) override;
base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) override;
void RegisterDisplayContext(gpu::DisplayContext* display_context) override;
void UnregisterDisplayContext(gpu::DisplayContext* display_context) override;
void DidLoseContext(bool offscreen,
......
......@@ -4,6 +4,8 @@
#include "components/viz/service/display_embedder/skia_output_device_buffer_queue.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "components/viz/service/display_embedder/skia_output_surface_dependency.h"
#include "gpu/command_buffer/common/capabilities.h"
......@@ -11,6 +13,8 @@
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/command_buffer/service/shared_image_representation.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/ipc/common/gpu_surface_lookup.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkSurfaceProps.h"
#include "ui/display/types/display_snapshot.h"
......@@ -18,6 +22,10 @@
#include "ui/gl/gl_fence.h"
#include "ui/gl/gl_surface.h"
#if defined(OS_ANDROID)
#include "ui/gl/gl_surface_egl_surface_control.h"
#endif
namespace viz {
static constexpr uint32_t kSharedImageUsage =
......@@ -125,7 +133,7 @@ void SkiaOutputDeviceBufferQueue::Image::EndWriteSkia() {
.fSignalSemaphores = end_semaphores_.data(),
};
scoped_write_access_->surface()->flush(
SkSurface::BackendSurfaceAccess::kPresent, flush_info);
SkSurface::BackendSurfaceAccess::kNoAccess, flush_info);
scoped_write_access_.reset();
end_semaphores_.clear();
}
......@@ -204,6 +212,41 @@ SkiaOutputDeviceBufferQueue::~SkiaOutputDeviceBufferQueue() {
FreeAllSurfaces();
}
// static
std::unique_ptr<SkiaOutputDeviceBufferQueue>
SkiaOutputDeviceBufferQueue::Create(
SkiaOutputSurfaceDependency* deps,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback) {
#if defined(OS_ANDROID)
if (!features::IsAndroidSurfaceControlEnabled())
return nullptr;
bool can_be_used_with_surface_control = false;
ANativeWindow* window =
gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
deps->GetSurfaceHandle(), &can_be_used_with_surface_control);
if (!window || !can_be_used_with_surface_control)
return nullptr;
// TODO(https://crbug.com/1012401): don't depend on GL.
auto gl_surface = base::MakeRefCounted<gl::GLSurfaceEGLSurfaceControl>(
window, base::ThreadTaskRunnerHandle::Get());
if (!gl_surface->Initialize(gl::GLSurfaceFormat())) {
LOG(ERROR) << "Failed to initialize GLSurfaceEGLSurfaceControl.";
return nullptr;
}
if (!deps->GetSharedContextState()->MakeCurrent(gl_surface.get(),
true /* needs_gl*/)) {
LOG(ERROR) << "MakeCurrent failed.";
return nullptr;
}
return std::make_unique<SkiaOutputDeviceBufferQueue>(
std::move(gl_surface), deps, did_swap_buffer_complete_callback);
#else
return nullptr;
#endif
}
SkiaOutputDeviceBufferQueue::Image*
SkiaOutputDeviceBufferQueue::GetCurrentImage() {
if (!current_image_)
......
......@@ -33,6 +33,10 @@ class VIZ_SERVICE_EXPORT SkiaOutputDeviceBufferQueue final
uint32_t shared_image_usage);
~SkiaOutputDeviceBufferQueue() override;
static std::unique_ptr<SkiaOutputDeviceBufferQueue> Create(
SkiaOutputSurfaceDependency* deps,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback);
void SwapBuffers(BufferPresentedCallback feedback,
std::vector<ui::LatencyInfo> latency_info) override;
void PostSubBuffer(const gfx::Rect& rect,
......@@ -51,6 +55,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputDeviceBufferQueue final
// Creates and submits gpu fence
std::unique_ptr<gfx::GpuFence> SubmitOverlayGpuFence() override;
gl::GLSurface* gl_surface() { return gl_surface_.get(); }
private:
friend class SkiaOutputDeviceBufferQueueTest;
class Image;
......
......@@ -8,6 +8,7 @@
#include <vector>
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
......@@ -86,6 +87,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceDependency {
virtual gpu::SurfaceHandle GetSurfaceHandle() = 0;
virtual scoped_refptr<gl::GLSurface> CreateGLSurface(
base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub) = 0;
// Hold a ref of the given surface until the returned closure is fired.
virtual base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) = 0;
virtual void PostTaskToClientThread(base::OnceClosure closure) = 0;
virtual void ScheduleGrContextCleanup() = 0;
......
......@@ -106,6 +106,22 @@ scoped_refptr<gl::GLSurface> SkiaOutputSurfaceDependencyImpl::CreateGLSurface(
}
}
base::ScopedClosureRunner SkiaOutputSurfaceDependencyImpl::CacheGLSurface(
gl::GLSurface* surface) {
gpu_service_impl_->main_runner()->PostTask(
FROM_HERE,
base::BindOnce(&gl::GLSurface::AddRef, base::Unretained(surface)));
auto release_callback = base::BindOnce(
[](const scoped_refptr<base::TaskRunner>& runner,
gl::GLSurface* surface) {
runner->PostTask(FROM_HERE, base::BindOnce(&gl::GLSurface::Release,
base::Unretained(surface)));
},
base::WrapRefCounted(gpu_service_impl_->main_runner()),
base::Unretained(surface));
return base::ScopedClosureRunner(std::move(release_callback));
}
void SkiaOutputSurfaceDependencyImpl::PostTaskToClientThread(
base::OnceClosure closure) {
client_thread_task_runner_->PostTask(FROM_HERE, std::move(closure));
......
......@@ -42,6 +42,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceDependencyImpl
gpu::SurfaceHandle GetSurfaceHandle() override;
scoped_refptr<gl::GLSurface> CreateGLSurface(
base::WeakPtr<gpu::ImageTransportSurfaceDelegate> stub) override;
base::ScopedClosureRunner CacheGLSurface(gl::GLSurface* surface) override;
void PostTaskToClientThread(base::OnceClosure closure) override;
void ScheduleGrContextCleanup() override;
......
......@@ -893,10 +893,8 @@ void SkiaOutputSurfaceImpl::SetNeedsSwapSizeNotifications(
}
base::ScopedClosureRunner SkiaOutputSurfaceImpl::GetCacheBackBufferCb() {
// TODO(weiliangc) : Add support for this once SkiaRenderer works with
// SurfaceControl.
CHECK(false);
return base::ScopedClosureRunner();
DCHECK(impl_on_gpu_->gl_surface());
return dependency_->CacheGLSurface(impl_on_gpu_->gl_surface());
}
void SkiaOutputSurfaceImpl::AddContextLostObserver(
......
......@@ -847,7 +847,6 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffers(
scoped_output_device_paint_.reset();
if (output_surface_plane_) {
DCHECK(!is_using_vulkan());
if (gl::GLImage* image = output_device_->GetOverlayImage()) {
std::unique_ptr<gfx::GpuFence> gpu_fence =
output_device_->SubmitOverlayGpuFence();
......@@ -1400,9 +1399,17 @@ bool SkiaOutputSurfaceImplOnGpu::InitializeForVulkan() {
did_swap_buffer_complete_callback_);
}
#else
auto output_device = SkiaOutputDeviceBufferQueue::Create(
dependency_, did_swap_buffer_complete_callback_);
if (output_device) {
// TODO(https://crbug.com/1012401): don't depend on GL.
gl_surface_ = output_device->gl_surface();
output_device_ = std::move(output_device);
} else {
output_device_ = std::make_unique<SkiaOutputDeviceVulkan>(
vulkan_context_provider_, dependency_->GetSurfaceHandle(),
did_swap_buffer_complete_callback_);
}
#endif
}
#endif
......
......@@ -114,6 +114,7 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate,
const base::WeakPtr<SkiaOutputSurfaceImplOnGpu>& weak_ptr() const {
return weak_ptr_;
}
gl::GLSurface* gl_surface() const { return gl_surface_.get(); }
void Reshape(const gfx::Size& size,
float device_scale_factor,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment