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,
OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane =
nullptr;
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 =
overlay_processor_->ProcessOutputSurfaceAsOverlay(
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());
}
......
......@@ -82,4 +82,9 @@ void OutputSurface::SetGpuVSyncCallback(GpuVSyncCallback callback) {
void OutputSurface::SetGpuVSyncEnabled(bool enabled) {
NOTREACHED();
}
gpu::Mailbox OutputSurface::GetOverlayMailbox() const {
return gpu::Mailbox();
}
} // namespace viz
......@@ -19,6 +19,7 @@
#include "components/viz/common/resources/returned_resource.h"
#include "components/viz/service/display/software_output_device.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/ipc/common/surface_handle.h"
#include "gpu/ipc/gpu_task_scheduler_helper.h"
......@@ -145,6 +146,9 @@ class VIZ_SERVICE_EXPORT OutputSurface {
// Get the texture for the main image's overlay.
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.
virtual gfx::BufferFormat GetOverlayBufferFormat() const = 0;
......
......@@ -141,13 +141,15 @@ OverlayProcessorInterface::ProcessOutputSurfaceAsOverlay(
const gfx::Size& viewport_size,
const gfx::BufferFormat& buffer_format,
const gfx::ColorSpace& color_space,
bool has_alpha) {
bool has_alpha,
const gpu::Mailbox& mailbox) {
OutputSurfaceOverlayPlane overlay_plane;
overlay_plane.transform = gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE;
overlay_plane.resource_size = viewport_size;
overlay_plane.format = buffer_format;
overlay_plane.color_space = color_space;
overlay_plane.enable_blending = has_alpha;
overlay_plane.mailbox = mailbox;
// Adjust transformation and display_rect based on display rotation.
overlay_plane.display_rect =
......
......@@ -79,6 +79,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorInterface {
// TODO(weiliangc): Should be replaced by SharedImage mailbox.
// Gpu fence to wait for before overlay is ready for display.
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
......@@ -88,7 +90,8 @@ class VIZ_SERVICE_EXPORT OverlayProcessorInterface {
const gfx::Size& viewport_size,
const gfx::BufferFormat& buffer_format,
const gfx::ColorSpace& color_space,
bool has_alpha);
bool has_alpha,
const gpu::Mailbox& mailbox);
static std::unique_ptr<OverlayProcessorInterface> CreateOverlayProcessor(
gpu::SurfaceHandle surface_handle,
......
......@@ -131,6 +131,18 @@ void OverlayProcessorOzone::CheckOverlaySupport(
// For ozone-cast, there will not be a primary_plane.
if (primary_plane) {
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++;
}
......@@ -141,29 +153,11 @@ void OverlayProcessorOzone::CheckOverlaySupport(
ConvertToOzoneOverlaySurface(*surface_iterator,
&(*ozone_surface_iterator));
if (shared_image_interface_) {
UMA_HISTOGRAM_BOOLEAN(
"Compositing.Display.OverlayProcessorOzone."
"IsCandidateSharedImage",
surface_iterator->mailbox.IsSharedImage());
if (surface_iterator->mailbox.IsSharedImage()) {
(*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);
}
bool result = SetNativePixmapForCandidate(&(*ozone_surface_iterator),
surface_iterator->mailbox);
// Skip the candidate if the corresponding NativePixmap is not found.
if (!result) {
*ozone_surface_iterator = ui::OverlaySurfaceCandidate();
}
}
}
......@@ -195,4 +189,35 @@ gfx::Rect OverlayProcessorOzone::GetOverlayDamageRectForOutputSurface(
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
......@@ -36,6 +36,12 @@ class VIZ_SERVICE_EXPORT OverlayProcessorOzone
const OverlayCandidate& candidate) const override;
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_;
std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates_;
......
......@@ -1856,7 +1856,7 @@ TEST_F(UnderlayTest, PrimaryPlaneOverlayIsTransparentWithUnderlay) {
auto output_surface_plane = overlay_processor_->ProcessOutputSurfaceAsOverlay(
kDisplaySize, kDefaultBufferFormat, gfx::ColorSpace(),
false /* has_alpha */);
false /* has_alpha */, gpu::Mailbox());
OverlayProcessorInterface::OutputSurfaceOverlayPlane* primary_plane =
&output_surface_plane;
......@@ -2203,7 +2203,7 @@ TEST_F(UnderlayCastTest, PrimaryPlaneOverlayIsAlwaysTransparent) {
RenderPassList pass_list;
pass_list.push_back(std::move(pass));
auto output_surface_plane = overlay_processor_->ProcessOutputSurfaceAsOverlay(
kDisplaySize, kDefaultBufferFormat, gfx::ColorSpace());
kDisplaySize, kDefaultBufferFormat, gfx::ColorSpace(), gpu::Mailbox());
overlay_processor_->ProcessForOverlays(
resource_provider_.get(), &pass_list, GetIdentityColorMatrix(),
......
......@@ -148,7 +148,7 @@ class VIZ_SERVICE_EXPORT BufferQueue {
gfx::Size size_;
gfx::ColorSpace color_space_;
size_t allocated_count_;
gfx::BufferFormat format_;
const gfx::BufferFormat format_;
// This surface is currently bound. This may be nullptr if no surface has
// been bound, or if allocation failed at bind.
std::unique_ptr<AllocatedSurface> current_surface_;
......
......@@ -61,6 +61,7 @@ GLOutputSurfaceBufferQueue::~GLOutputSurfaceBufferQueue() {
buffer_queue_textures_.clear();
current_texture_ = 0u;
last_bound_texture_ = 0u;
last_bound_mailbox_.SetZero();
// Freeing the BufferQueue here ensures that *this is fully alive in case the
// BufferQueue needs the SyncTokenProvider functionality.
......@@ -96,6 +97,7 @@ void GLOutputSurfaceBufferQueue::BindFramebuffer() {
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
texture_target_, current_texture_, 0);
last_bound_texture_ = current_texture_;
last_bound_mailbox_ = current_buffer;
#if DCHECK_IS_ON() && defined(OS_CHROMEOS)
const GLenum result = gl->CheckFramebufferStatus(GL_FRAMEBUFFER);
......@@ -152,6 +154,7 @@ void GLOutputSurfaceBufferQueue::Reshape(const gfx::Size& size,
buffer_queue_textures_.clear();
current_texture_ = 0u;
last_bound_texture_ = 0u;
last_bound_mailbox_.SetZero();
}
}
}
......@@ -199,6 +202,10 @@ unsigned GLOutputSurfaceBufferQueue::GetOverlayTextureId() const {
return last_bound_texture_;
}
gpu::Mailbox GLOutputSurfaceBufferQueue::GetOverlayMailbox() const {
return last_bound_mailbox_;
}
gfx::BufferFormat GLOutputSurfaceBufferQueue::GetOverlayBufferFormat() const {
DCHECK(buffer_queue_);
return buffer_queue_->buffer_format();
......
......@@ -60,6 +60,7 @@ class VIZ_SERVICE_EXPORT GLOutputSurfaceBufferQueue
uint32_t GetFramebufferCopyTextureFormat() override;
bool IsDisplayedAsOverlayPlane() const override;
unsigned GetOverlayTextureId() const override;
gpu::Mailbox GetOverlayMailbox() const override;
gfx::BufferFormat GetOverlayBufferFormat() const override;
// GLOutputSurface:
......@@ -78,11 +79,14 @@ class VIZ_SERVICE_EXPORT GLOutputSurfaceBufferQueue
// |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
// |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_|
// because it requires Begin/EndSharedImageAccessDirectCHROMIUM().
unsigned current_texture_ = 0u;
unsigned last_bound_texture_ = 0u;
gpu::Mailbox last_bound_mailbox_;
const unsigned texture_target_;
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