Commit 3ff3d8d3 authored by Saman Sami's avatar Saman Sami Committed by Commit Bot

Reland "Viz/Ozone/DRM: Provide NativePixmap for the primary plane"

Relands https://crrev.com/c/2016327 but avoids calling
BufferQueue::GetCurrentBuffer() in GLOutputSurfaceBufferQueue due to
issues with empty swaps.

Plumb mailbox for the primary plane to OverlayProcessorOzone and use
SharedImageInterface to obtain the corresponding NativePixmap.

Bug: 756454,1047030
Change-Id: I78466b2225b2d4402b853f9f7cbade485144b18f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2036430
Commit-Queue: Saman Sami <samans@chromium.org>
Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738325}
parent 29b4c657
...@@ -352,10 +352,16 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, ...@@ -352,10 +352,16 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane = OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane =
nullptr; nullptr;
if (output_surface_->IsDisplayedAsOverlayPlane()) { if (output_surface_->IsDisplayedAsOverlayPlane()) {
// OutputSurface::GetOverlayMailbox() returns the mailbox for the last
// used buffer, which is most likely different from the one being used
// this frame. However, for the purpose of testing the overlay
// configuration, the mailbox for ANY buffer from BufferQueue is good
// enough because they're all created with identical properties.
current_frame()->output_surface_plane = current_frame()->output_surface_plane =
overlay_processor_->ProcessOutputSurfaceAsOverlay( overlay_processor_->ProcessOutputSurfaceAsOverlay(
device_viewport_size, output_surface_->GetOverlayBufferFormat(), device_viewport_size, output_surface_->GetOverlayBufferFormat(),
reshape_device_color_space_, reshape_has_alpha_); reshape_device_color_space_, reshape_has_alpha_,
output_surface_->GetOverlayMailbox());
primary_plane = &(current_frame()->output_surface_plane.value()); primary_plane = &(current_frame()->output_surface_plane.value());
} }
......
...@@ -82,4 +82,9 @@ void OutputSurface::SetGpuVSyncCallback(GpuVSyncCallback callback) { ...@@ -82,4 +82,9 @@ void OutputSurface::SetGpuVSyncCallback(GpuVSyncCallback callback) {
void OutputSurface::SetGpuVSyncEnabled(bool enabled) { void OutputSurface::SetGpuVSyncEnabled(bool enabled) {
NOTREACHED(); NOTREACHED();
} }
gpu::Mailbox OutputSurface::GetOverlayMailbox() const {
return gpu::Mailbox();
}
} // namespace viz } // namespace viz
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "components/viz/common/resources/returned_resource.h" #include "components/viz/common/resources/returned_resource.h"
#include "components/viz/service/display/software_output_device.h" #include "components/viz/service/display/software_output_device.h"
#include "components/viz/service/viz_service_export.h" #include "components/viz/service/viz_service_export.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/texture_in_use_response.h" #include "gpu/command_buffer/common/texture_in_use_response.h"
#include "gpu/ipc/common/surface_handle.h" #include "gpu/ipc/common/surface_handle.h"
#include "gpu/ipc/gpu_task_scheduler_helper.h" #include "gpu/ipc/gpu_task_scheduler_helper.h"
...@@ -145,6 +146,9 @@ class VIZ_SERVICE_EXPORT OutputSurface { ...@@ -145,6 +146,9 @@ class VIZ_SERVICE_EXPORT OutputSurface {
// Get the texture for the main image's overlay. // Get the texture for the main image's overlay.
virtual unsigned GetOverlayTextureId() const = 0; virtual unsigned GetOverlayTextureId() const = 0;
// Returns the |mailbox| corresponding to the main image's overlay.
virtual gpu::Mailbox GetOverlayMailbox() const;
// Get the format for the main image's overlay. // Get the format for the main image's overlay.
virtual gfx::BufferFormat GetOverlayBufferFormat() const = 0; virtual gfx::BufferFormat GetOverlayBufferFormat() const = 0;
......
...@@ -141,13 +141,15 @@ OverlayProcessorInterface::ProcessOutputSurfaceAsOverlay( ...@@ -141,13 +141,15 @@ OverlayProcessorInterface::ProcessOutputSurfaceAsOverlay(
const gfx::Size& viewport_size, const gfx::Size& viewport_size,
const gfx::BufferFormat& buffer_format, const gfx::BufferFormat& buffer_format,
const gfx::ColorSpace& color_space, const gfx::ColorSpace& color_space,
bool has_alpha) { bool has_alpha,
const gpu::Mailbox& mailbox) {
OutputSurfaceOverlayPlane overlay_plane; OutputSurfaceOverlayPlane overlay_plane;
overlay_plane.transform = gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE; overlay_plane.transform = gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE;
overlay_plane.resource_size = viewport_size; overlay_plane.resource_size = viewport_size;
overlay_plane.format = buffer_format; overlay_plane.format = buffer_format;
overlay_plane.color_space = color_space; overlay_plane.color_space = color_space;
overlay_plane.enable_blending = has_alpha; overlay_plane.enable_blending = has_alpha;
overlay_plane.mailbox = mailbox;
// Adjust transformation and display_rect based on display rotation. // Adjust transformation and display_rect based on display rotation.
overlay_plane.display_rect = overlay_plane.display_rect =
......
...@@ -79,6 +79,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorInterface { ...@@ -79,6 +79,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorInterface {
// TODO(weiliangc): Should be replaced by SharedImage mailbox. // TODO(weiliangc): Should be replaced by SharedImage mailbox.
// Gpu fence to wait for before overlay is ready for display. // Gpu fence to wait for before overlay is ready for display.
unsigned gpu_fence_id; unsigned gpu_fence_id;
// Mailbox corresponding to the buffer backing the primary plane.
gpu::Mailbox mailbox;
}; };
// TODO(weiliangc): Eventually the asymmetry between primary plane and // TODO(weiliangc): Eventually the asymmetry between primary plane and
...@@ -88,7 +90,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorInterface { ...@@ -88,7 +90,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorInterface {
const gfx::Size& viewport_size, const gfx::Size& viewport_size,
const gfx::BufferFormat& buffer_format, const gfx::BufferFormat& buffer_format,
const gfx::ColorSpace& color_space, const gfx::ColorSpace& color_space,
bool has_alpha); bool has_alpha,
const gpu::Mailbox& mailbox);
static std::unique_ptr<OverlayProcessorInterface> CreateOverlayProcessor( static std::unique_ptr<OverlayProcessorInterface> CreateOverlayProcessor(
gpu::SurfaceHandle surface_handle, gpu::SurfaceHandle surface_handle,
......
...@@ -131,6 +131,18 @@ void OverlayProcessorOzone::CheckOverlaySupport( ...@@ -131,6 +131,18 @@ void OverlayProcessorOzone::CheckOverlaySupport(
// For ozone-cast, there will not be a primary_plane. // For ozone-cast, there will not be a primary_plane.
if (primary_plane) { if (primary_plane) {
ConvertToOzoneOverlaySurface(*primary_plane, &(*ozone_surface_iterator)); ConvertToOzoneOverlaySurface(*primary_plane, &(*ozone_surface_iterator));
if (shared_image_interface_) {
bool result = SetNativePixmapForCandidate(&(*ozone_surface_iterator),
primary_plane->mailbox);
// We cannot validate an overlay configuration without the buffer for
// primary plane present.
if (!result) {
for (auto& candidate : *surfaces) {
candidate.overlay_handled = false;
}
return;
}
}
ozone_surface_iterator++; ozone_surface_iterator++;
} }
...@@ -141,29 +153,11 @@ void OverlayProcessorOzone::CheckOverlaySupport( ...@@ -141,29 +153,11 @@ void OverlayProcessorOzone::CheckOverlaySupport(
ConvertToOzoneOverlaySurface(*surface_iterator, ConvertToOzoneOverlaySurface(*surface_iterator,
&(*ozone_surface_iterator)); &(*ozone_surface_iterator));
if (shared_image_interface_) { if (shared_image_interface_) {
UMA_HISTOGRAM_BOOLEAN( bool result = SetNativePixmapForCandidate(&(*ozone_surface_iterator),
"Compositing.Display.OverlayProcessorOzone." surface_iterator->mailbox);
"IsCandidateSharedImage", // Skip the candidate if the corresponding NativePixmap is not found.
surface_iterator->mailbox.IsSharedImage()); if (!result) {
if (surface_iterator->mailbox.IsSharedImage()) { *ozone_surface_iterator = ui::OverlaySurfaceCandidate();
(*ozone_surface_iterator).native_pixmap =
shared_image_interface_->GetNativePixmap(
surface_iterator->mailbox);
if (!ozone_surface_iterator->native_pixmap) {
// SharedImage creation and destruction happens on a different
// thread so there is no guarantee that we can always look them up
// successfully. If a SharedImage doesn't exist, ignore the
// candidate. We will try again next frame.
DLOG(ERROR)
<< "Unable to find the NativePixmap corresponding to the "
"overlay candidate";
*ozone_surface_iterator = ui::OverlaySurfaceCandidate();
ReportSharedImageExists(false);
} else {
(*ozone_surface_iterator).native_pixmap_unique_id =
MailboxToUInt32(surface_iterator->mailbox);
ReportSharedImageExists(true);
}
} }
} }
} }
...@@ -195,4 +189,35 @@ gfx::Rect OverlayProcessorOzone::GetOverlayDamageRectForOutputSurface( ...@@ -195,4 +189,35 @@ gfx::Rect OverlayProcessorOzone::GetOverlayDamageRectForOutputSurface(
return ToEnclosedRect(overlay.display_rect); return ToEnclosedRect(overlay.display_rect);
} }
bool OverlayProcessorOzone::SetNativePixmapForCandidate(
ui::OverlaySurfaceCandidate* candidate,
const gpu::Mailbox& mailbox) {
DCHECK(shared_image_interface_);
UMA_HISTOGRAM_BOOLEAN(
"Compositing.Display.OverlayProcessorOzone."
"IsCandidateSharedImage",
mailbox.IsSharedImage());
if (!mailbox.IsSharedImage())
return false;
candidate->native_pixmap = shared_image_interface_->GetNativePixmap(mailbox);
if (!candidate->native_pixmap) {
// SharedImage creation and destruction happens on a different
// thread so there is no guarantee that we can always look them up
// successfully. If a SharedImage doesn't exist, ignore the
// candidate. We will try again next frame.
DLOG(ERROR) << "Unable to find the NativePixmap corresponding to the "
"overlay candidate";
ReportSharedImageExists(false);
return false;
}
candidate->native_pixmap_unique_id = MailboxToUInt32(mailbox);
ReportSharedImageExists(true);
return true;
}
} // namespace viz } // namespace viz
...@@ -36,6 +36,12 @@ class VIZ_SERVICE_EXPORT OverlayProcessorOzone ...@@ -36,6 +36,12 @@ class VIZ_SERVICE_EXPORT OverlayProcessorOzone
const OverlayCandidate& candidate) const override; const OverlayCandidate& candidate) const override;
private: private:
// Populates |native_pixmap| and |native_pixmap_unique_id| in |candidate|
// based on |mailbox|. Return false if the corresponding NativePixmap cannot
// be found.
bool SetNativePixmapForCandidate(ui::OverlaySurfaceCandidate* candidate,
const gpu::Mailbox& mailbox);
const bool overlay_enabled_; const bool overlay_enabled_;
std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates_; std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates_;
......
...@@ -1856,7 +1856,7 @@ TEST_F(UnderlayTest, PrimaryPlaneOverlayIsTransparentWithUnderlay) { ...@@ -1856,7 +1856,7 @@ TEST_F(UnderlayTest, PrimaryPlaneOverlayIsTransparentWithUnderlay) {
auto output_surface_plane = overlay_processor_->ProcessOutputSurfaceAsOverlay( auto output_surface_plane = overlay_processor_->ProcessOutputSurfaceAsOverlay(
kDisplaySize, kDefaultBufferFormat, gfx::ColorSpace(), kDisplaySize, kDefaultBufferFormat, gfx::ColorSpace(),
false /* has_alpha */); false /* has_alpha */, gpu::Mailbox());
OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane = OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane =
&output_surface_plane; &output_surface_plane;
...@@ -2203,7 +2203,7 @@ TEST_F(UnderlayCastTest, PrimaryPlaneOverlayIsAlwaysTransparent) { ...@@ -2203,7 +2203,7 @@ TEST_F(UnderlayCastTest, PrimaryPlaneOverlayIsAlwaysTransparent) {
RenderPassList pass_list; RenderPassList pass_list;
pass_list.push_back(std::move(pass)); pass_list.push_back(std::move(pass));
auto output_surface_plane = overlay_processor_->ProcessOutputSurfaceAsOverlay( auto output_surface_plane = overlay_processor_->ProcessOutputSurfaceAsOverlay(
kDisplaySize, kDefaultBufferFormat, gfx::ColorSpace()); kDisplaySize, kDefaultBufferFormat, gfx::ColorSpace(), gpu::Mailbox());
overlay_processor_->ProcessForOverlays( overlay_processor_->ProcessForOverlays(
resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
......
...@@ -148,7 +148,7 @@ class VIZ_SERVICE_EXPORT BufferQueue { ...@@ -148,7 +148,7 @@ class VIZ_SERVICE_EXPORT BufferQueue {
gfx::Size size_; gfx::Size size_;
gfx::ColorSpace color_space_; gfx::ColorSpace color_space_;
size_t allocated_count_; size_t allocated_count_;
gfx::BufferFormat format_; const gfx::BufferFormat format_;
// This surface is currently bound. This may be nullptr if no surface has // This surface is currently bound. This may be nullptr if no surface has
// been bound, or if allocation failed at bind. // been bound, or if allocation failed at bind.
std::unique_ptr<AllocatedSurface> current_surface_; std::unique_ptr<AllocatedSurface> current_surface_;
......
...@@ -61,6 +61,7 @@ GLOutputSurfaceBufferQueue::~GLOutputSurfaceBufferQueue() { ...@@ -61,6 +61,7 @@ GLOutputSurfaceBufferQueue::~GLOutputSurfaceBufferQueue() {
buffer_queue_textures_.clear(); buffer_queue_textures_.clear();
current_texture_ = 0u; current_texture_ = 0u;
last_bound_texture_ = 0u; last_bound_texture_ = 0u;
last_bound_mailbox_.SetZero();
// Freeing the BufferQueue here ensures that *this is fully alive in case the // Freeing the BufferQueue here ensures that *this is fully alive in case the
// BufferQueue needs the SyncTokenProvider functionality. // BufferQueue needs the SyncTokenProvider functionality.
...@@ -96,6 +97,7 @@ void GLOutputSurfaceBufferQueue::BindFramebuffer() { ...@@ -96,6 +97,7 @@ void GLOutputSurfaceBufferQueue::BindFramebuffer() {
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
texture_target_, current_texture_, 0); texture_target_, current_texture_, 0);
last_bound_texture_ = current_texture_; last_bound_texture_ = current_texture_;
last_bound_mailbox_ = current_buffer;
#if DCHECK_IS_ON() && defined(OS_CHROMEOS) #if DCHECK_IS_ON() && defined(OS_CHROMEOS)
const GLenum result = gl->CheckFramebufferStatus(GL_FRAMEBUFFER); const GLenum result = gl->CheckFramebufferStatus(GL_FRAMEBUFFER);
...@@ -152,6 +154,7 @@ void GLOutputSurfaceBufferQueue::Reshape(const gfx::Size& size, ...@@ -152,6 +154,7 @@ void GLOutputSurfaceBufferQueue::Reshape(const gfx::Size& size,
buffer_queue_textures_.clear(); buffer_queue_textures_.clear();
current_texture_ = 0u; current_texture_ = 0u;
last_bound_texture_ = 0u; last_bound_texture_ = 0u;
last_bound_mailbox_.SetZero();
} }
} }
} }
...@@ -199,6 +202,10 @@ unsigned GLOutputSurfaceBufferQueue::GetOverlayTextureId() const { ...@@ -199,6 +202,10 @@ unsigned GLOutputSurfaceBufferQueue::GetOverlayTextureId() const {
return last_bound_texture_; return last_bound_texture_;
} }
gpu::Mailbox GLOutputSurfaceBufferQueue::GetOverlayMailbox() const {
return last_bound_mailbox_;
}
gfx::BufferFormat GLOutputSurfaceBufferQueue::GetOverlayBufferFormat() const { gfx::BufferFormat GLOutputSurfaceBufferQueue::GetOverlayBufferFormat() const {
DCHECK(buffer_queue_); DCHECK(buffer_queue_);
return buffer_queue_->buffer_format(); return buffer_queue_->buffer_format();
......
...@@ -60,6 +60,7 @@ class VIZ_SERVICE_EXPORT GLOutputSurfaceBufferQueue ...@@ -60,6 +60,7 @@ class VIZ_SERVICE_EXPORT GLOutputSurfaceBufferQueue
uint32_t GetFramebufferCopyTextureFormat() override; uint32_t GetFramebufferCopyTextureFormat() override;
bool IsDisplayedAsOverlayPlane() const override; bool IsDisplayedAsOverlayPlane() const override;
unsigned GetOverlayTextureId() const override; unsigned GetOverlayTextureId() const override;
gpu::Mailbox GetOverlayMailbox() const override;
gfx::BufferFormat GetOverlayBufferFormat() const override; gfx::BufferFormat GetOverlayBufferFormat() const override;
// GLOutputSurface: // GLOutputSurface:
...@@ -78,11 +79,14 @@ class VIZ_SERVICE_EXPORT GLOutputSurfaceBufferQueue ...@@ -78,11 +79,14 @@ class VIZ_SERVICE_EXPORT GLOutputSurfaceBufferQueue
// |last_bound_texture_| is the texture that was last bound to |fbo_|. It's // |last_bound_texture_| is the texture that was last bound to |fbo_|. It's
// also one of |buffer_queue_textures_| or 0 if no texture has been bound to // also one of |buffer_queue_textures_| or 0 if no texture has been bound to
// |fbo_| or all the buffers in the buffer queue have been freed. // |fbo_| or all the buffers in the buffer queue have been freed.
// |last_bound_mailbox_| is the mailbox corresponding to
// |last_bound_texture_|.
// //
// TODO(andrescj): use an RAII pattern to scope access to |current_texture_| // TODO(andrescj): use an RAII pattern to scope access to |current_texture_|
// because it requires Begin/EndSharedImageAccessDirectCHROMIUM(). // because it requires Begin/EndSharedImageAccessDirectCHROMIUM().
unsigned current_texture_ = 0u; unsigned current_texture_ = 0u;
unsigned last_bound_texture_ = 0u; unsigned last_bound_texture_ = 0u;
gpu::Mailbox last_bound_mailbox_;
const unsigned texture_target_; const unsigned texture_target_;
unsigned fbo_ = 0u; unsigned fbo_ = 0u;
......
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