Commit 0ea41733 authored by Saman Sami's avatar Saman Sami Committed by Commit Bot

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

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

Bug: 756454
Change-Id: Ic537d05253bc68c27a8fed961de8547ace359e82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2016327Reviewed-by: default avatarRobert Kroeger <rjkroege@chromium.org>
Commit-Queue: Saman Sami <samans@chromium.org>
Cr-Commit-Position: refs/heads/master@{#736065}
parent e007e95c
...@@ -354,7 +354,8 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, ...@@ -354,7 +354,8 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
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_;
......
...@@ -1855,7 +1855,7 @@ TEST_F(UnderlayTest, PrimaryPlaneOverlayIsTransparentWithUnderlay) { ...@@ -1855,7 +1855,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;
...@@ -2202,7 +2202,7 @@ TEST_F(UnderlayCastTest, PrimaryPlaneOverlayIsAlwaysTransparent) { ...@@ -2202,7 +2202,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(),
......
...@@ -37,10 +37,13 @@ void BufferQueue::SetSyncTokenProvider(SyncTokenProvider* sync_token_provider) { ...@@ -37,10 +37,13 @@ void BufferQueue::SetSyncTokenProvider(SyncTokenProvider* sync_token_provider) {
gpu::Mailbox BufferQueue::GetCurrentBuffer( gpu::Mailbox BufferQueue::GetCurrentBuffer(
gpu::SyncToken* creation_sync_token) { gpu::SyncToken* creation_sync_token) {
DCHECK(creation_sync_token);
if (!current_surface_) if (!current_surface_)
current_surface_ = GetNextSurface(creation_sync_token); current_surface_ = GetNextSurface();
return current_surface_ ? current_surface_->mailbox : gpu::Mailbox(); if (!current_surface_)
return gpu::Mailbox();
if (creation_sync_token)
*creation_sync_token = current_surface_->creation_sync_token;
return current_surface_->mailbox;
} }
void BufferQueue::UpdateBufferDamage(const gfx::Rect& damage) { void BufferQueue::UpdateBufferDamage(const gfx::Rect& damage) {
...@@ -124,9 +127,7 @@ void BufferQueue::FreeSurface(std::unique_ptr<AllocatedSurface> surface, ...@@ -124,9 +127,7 @@ void BufferQueue::FreeSurface(std::unique_ptr<AllocatedSurface> surface,
allocated_count_--; allocated_count_--;
} }
std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface( std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface() {
gpu::SyncToken* creation_sync_token) {
DCHECK(creation_sync_token);
if (!available_surfaces_.empty()) { if (!available_surfaces_.empty()) {
std::unique_ptr<AllocatedSurface> surface = std::unique_ptr<AllocatedSurface> surface =
std::move(available_surfaces_.back()); std::move(available_surfaces_.back());
...@@ -158,16 +159,20 @@ std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface( ...@@ -158,16 +159,20 @@ std::unique_ptr<BufferQueue::AllocatedSurface> BufferQueue::GetNextSurface(
} }
allocated_count_++; allocated_count_++;
*creation_sync_token = sii_->GenUnverifiedSyncToken(); gpu::SyncToken creation_sync_token = sii_->GenUnverifiedSyncToken();
return std::make_unique<AllocatedSurface>(std::move(buffer), mailbox, return std::make_unique<AllocatedSurface>(
gfx::Rect(size_)); std::move(buffer), mailbox, creation_sync_token, gfx::Rect(size_));
} }
BufferQueue::AllocatedSurface::AllocatedSurface( BufferQueue::AllocatedSurface::AllocatedSurface(
std::unique_ptr<gfx::GpuMemoryBuffer> buffer, std::unique_ptr<gfx::GpuMemoryBuffer> buffer,
const gpu::Mailbox& mailbox, const gpu::Mailbox& mailbox,
const gpu::SyncToken& creation_sync_token,
const gfx::Rect& rect) const gfx::Rect& rect)
: buffer(buffer.release()), mailbox(mailbox), damage(rect) {} : buffer(buffer.release()),
mailbox(mailbox),
creation_sync_token(creation_sync_token),
damage(rect) {}
BufferQueue::AllocatedSurface::~AllocatedSurface() { BufferQueue::AllocatedSurface::~AllocatedSurface() {
DCHECK(!buffer); DCHECK(!buffer);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.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/mailbox.h"
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/ipc/common/surface_handle.h" #include "gpu/ipc/common/surface_handle.h"
#include "ui/gfx/buffer_types.h" #include "ui/gfx/buffer_types.h"
#include "ui/gfx/color_space.h" #include "ui/gfx/color_space.h"
...@@ -122,6 +123,7 @@ class VIZ_SERVICE_EXPORT BufferQueue { ...@@ -122,6 +123,7 @@ class VIZ_SERVICE_EXPORT BufferQueue {
struct VIZ_SERVICE_EXPORT AllocatedSurface { struct VIZ_SERVICE_EXPORT AllocatedSurface {
AllocatedSurface(std::unique_ptr<gfx::GpuMemoryBuffer> buffer, AllocatedSurface(std::unique_ptr<gfx::GpuMemoryBuffer> buffer,
const gpu::Mailbox& mailbox, const gpu::Mailbox& mailbox,
const gpu::SyncToken& creation_sync_token,
const gfx::Rect& rect); const gfx::Rect& rect);
~AllocatedSurface(); ~AllocatedSurface();
...@@ -129,6 +131,9 @@ class VIZ_SERVICE_EXPORT BufferQueue { ...@@ -129,6 +131,9 @@ class VIZ_SERVICE_EXPORT BufferQueue {
// SurfaceHandle, we don't have to keep track of |buffer|. // SurfaceHandle, we don't have to keep track of |buffer|.
std::unique_ptr<gfx::GpuMemoryBuffer> buffer; std::unique_ptr<gfx::GpuMemoryBuffer> buffer;
gpu::Mailbox mailbox; gpu::Mailbox mailbox;
// SyncToken generated when |mailbox| was created. The client of BufferQueue
// should insert this token in its command stream before using |mailbox|.
gpu::SyncToken creation_sync_token;
gfx::Rect damage; // This is the damage for this frame from the previous. gfx::Rect damage; // This is the damage for this frame from the previous.
}; };
...@@ -138,11 +143,8 @@ class VIZ_SERVICE_EXPORT BufferQueue { ...@@ -138,11 +143,8 @@ class VIZ_SERVICE_EXPORT BufferQueue {
void UpdateBufferDamage(const gfx::Rect& damage); void UpdateBufferDamage(const gfx::Rect& damage);
// Return a buffer that is available to be drawn into or nullptr if there is // Return a buffer that is available to be drawn into or nullptr if there is
// no available buffer and one cannot be created. If a new buffer is created // no available buffer and one cannot be created.
// *|creation_sync_token| is set to a sync token that the client must wait on std::unique_ptr<AllocatedSurface> GetNextSurface();
// before using the buffer.
std::unique_ptr<AllocatedSurface> GetNextSurface(
gpu::SyncToken* creation_sync_token);
gpu::SharedImageInterface* const sii_; gpu::SharedImageInterface* const sii_;
gfx::Size size_; gfx::Size size_;
......
...@@ -191,6 +191,10 @@ unsigned GLOutputSurfaceBufferQueue::GetOverlayTextureId() const { ...@@ -191,6 +191,10 @@ unsigned GLOutputSurfaceBufferQueue::GetOverlayTextureId() const {
return current_texture_; return current_texture_;
} }
gpu::Mailbox GLOutputSurfaceBufferQueue::GetOverlayMailbox() const {
return buffer_queue_->GetCurrentBuffer(nullptr);
}
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:
......
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