Commit 2d6a0abd authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Reusing shared image backing for render pass overlays on macOS

Bug: 1100728
Change-Id: Idfdd5c7f2e94c0c37665184e21c98ad01c344002
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2410843
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807988}
parent 80c67edf
......@@ -854,7 +854,7 @@ void SkiaRenderer::DidReceiveReleasedOverlays(
for (const auto& mailbox : released_overlays) {
auto it = awaiting_release_overlay_locks_.find(mailbox);
if (it == awaiting_release_overlay_locks_.end()) {
DLOG(ERROR) << "Got an unexpected mailbox";
DLOG(FATAL) << "Got an unexpected mailbox";
continue;
}
awaiting_release_overlay_locks_.erase(it);
......
......@@ -362,7 +362,7 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
const DisplayResourceProvider::ScopedReadLockSharedImage& rhs) const;
};
// a set for locks of overlays which are waiting for releasing.
// The set is using lock->mailbox() as the unique key.
// The set is using lock.mailbox() as the unique key.
base::flat_set<DisplayResourceProvider::ScopedReadLockSharedImage,
ScopedReadLockComparator>
awaiting_release_overlay_locks_;
......
......@@ -117,7 +117,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputDeviceBufferQueue : public SkiaOutputDevice {
bool operator()(const OverlayData& lhs, const gpu::Mailbox& rhs) const;
bool operator()(const gpu::Mailbox& lhs, const OverlayData& rhs) const;
};
// A set for all overlays. The set uses overlay_data->mailbox() as the unique
// A set for all overlays. The set uses overlay_data.mailbox() as the unique
// key.
base::flat_set<OverlayData, OverlayDataComparator> overlays_;
......
......@@ -995,51 +995,21 @@ void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays(
// GL is used on MacOS and GL doesn't need semaphores.
DCHECK(begin_semaphores.empty());
DCHECK(end_semaphores.empty());
std::vector<gpu::Mailbox> render_pass_overlay_mailboxes;
for (auto& overlay : overlays) {
if (!overlay.ddl)
continue;
base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
if (dependency_->GetGrShaderCache()) {
cache_use.emplace(dependency_->GetGrShaderCache(),
gpu::kDisplayCompositorClientId);
}
constexpr auto kOverlayUsage =
gpu::SHARED_IMAGE_USAGE_SCANOUT | gpu::SHARED_IMAGE_USAGE_DISPLAY |
gpu::SHARED_IMAGE_USAGE_GLES2_FRAMEBUFFER_HINT;
const auto& characterization = overlay.ddl->characterization();
ResourceFormat resource_format;
switch (characterization.colorType()) {
case kRGBA_8888_SkColorType:
resource_format = ResourceFormat::RGBA_8888;
break;
case kBGRA_8888_SkColorType:
resource_format = ResourceFormat::BGRA_8888;
break;
case kRGBA_F16_SkColorType:
resource_format = ResourceFormat::RGBA_F16;
break;
default:
resource_format = ResourceFormat::RGBA_8888;
NOTREACHED();
}
// TODO(https://crbug.com/1100728): reuse shared images.
auto backing = GetOrCreateRenderPassOverlayBacking(characterization);
DCHECK(overlay.mailbox.IsZero());
overlay.mailbox = gpu::Mailbox::GenerateForSharedImage();
shared_image_factory_->CreateSharedImage(
overlay.mailbox, resource_format,
gfx::Size(characterization.width(), characterization.height()),
gfx::ColorSpace(*characterization.colorSpace()),
characterization.origin(), characterization.imageInfo().alphaType(),
gpu::kNullSurfaceHandle, kOverlayUsage);
auto representation = shared_image_representation_factory_->ProduceSkia(
overlay.mailbox, context_state_.get());
DCHECK(representation);
auto scoped_access = representation->BeginScopedWriteAccess(
overlay.mailbox = backing->mailbox();
auto scoped_access = backing->BeginScopedWriteAccess(
/*final_msaa_count=*/0, characterization.surfaceProps(),
/*begin_semaphores=*/nullptr,
/*end_semaphores=*/nullptr,
......@@ -1048,17 +1018,16 @@ void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays(
DCHECK(result);
context_state_->gr_context()->flushAndSubmit();
scoped_access.reset();
representation->SetCleared();
render_pass_overlay_mailboxes.push_back(overlay.mailbox);
backing->SetCleared();
in_flight_render_pass_overlay_backings_.insert(std::move(backing));
}
promise_image_access_helper_.EndAccess();
output_device_->ScheduleOverlays(std::move(overlays));
for (const auto& mailbox : render_pass_overlay_mailboxes) {
shared_image_factory_->DestroySharedImage(mailbox);
}
// Release any backings which are not reused by the current frame, probably
// because the properties of render passes are changed or render passes are
// removed.
available_render_pass_overlay_backings_.clear();
#else
DCHECK(image_contexts.empty());
output_device_->ScheduleOverlays(std::move(overlays));
......@@ -1466,6 +1435,26 @@ void SkiaOutputSurfaceImplOnGpu::DidSwapBuffersCompleteInternal(
}
}
#if defined(OS_APPLE)
// |available_render_pass_overlay_backings_| are used or released in
// ScheduleOverlays() for every frames.
DCHECK(available_render_pass_overlay_backings_.empty());
// Erase mailboxes of render pass overlays from |params.released_overlays| and
// move released backings for those render pass overlays from
// |in_flight_render_pass_overlay_backings_| to
// |available_render_pass_overlay_backings_| for reusing.
base::EraseIf(params.released_overlays, [this](const gpu::Mailbox& mailbox) {
auto it = in_flight_render_pass_overlay_backings_.find(mailbox);
if (it == in_flight_render_pass_overlay_backings_.end())
return false;
available_render_pass_overlay_backings_.push_back(std::move(*it));
in_flight_render_pass_overlay_backings_.erase(it);
return true;
});
#endif
PostTaskToClientThread(
base::BindOnce(did_swap_buffer_complete_callback_, params, pixel_size));
}
......@@ -1516,4 +1505,72 @@ void SkiaOutputSurfaceImplOnGpu::CheckReadbackCompletion() {
ScheduleCheckReadbackCompletion();
}
#if defined(OS_APPLE)
std::unique_ptr<gpu::SharedImageRepresentationSkia>
SkiaOutputSurfaceImplOnGpu::GetOrCreateRenderPassOverlayBacking(
const SkSurfaceCharacterization& characterization) {
ResourceFormat resource_format;
switch (characterization.colorType()) {
case kRGBA_8888_SkColorType:
resource_format = ResourceFormat::RGBA_8888;
break;
case kBGRA_8888_SkColorType:
resource_format = ResourceFormat::BGRA_8888;
break;
case kRGBA_F16_SkColorType:
resource_format = ResourceFormat::RGBA_F16;
break;
default:
resource_format = ResourceFormat::RGBA_8888;
NOTREACHED();
}
gfx::Size size(characterization.width(), characterization.height());
gfx::ColorSpace color_space(*characterization.colorSpace());
auto it = std::find_if(
available_render_pass_overlay_backings_.begin(),
available_render_pass_overlay_backings_.end(),
[&characterization, &resource_format, &size, &color_space](
const std::unique_ptr<gpu::SharedImageRepresentationSkia>& backing) {
return backing->format() == resource_format &&
backing->size() == size &&
backing->color_space() == color_space &&
backing->surface_origin() == characterization.origin() &&
backing->alpha_type() ==
characterization.imageInfo().alphaType();
});
if (it != available_render_pass_overlay_backings_.end()) {
auto backing = std::move(*it);
available_render_pass_overlay_backings_.erase(it);
return backing;
}
auto mailbox = gpu::Mailbox::GenerateForSharedImage();
constexpr auto kOverlayUsage = gpu::SHARED_IMAGE_USAGE_SCANOUT |
gpu::SHARED_IMAGE_USAGE_DISPLAY |
gpu::SHARED_IMAGE_USAGE_RASTER;
bool result = shared_image_factory_->CreateSharedImage(
mailbox, resource_format, size, color_space, characterization.origin(),
characterization.imageInfo().alphaType(), gpu::kNullSurfaceHandle,
kOverlayUsage);
if (!result) {
LOG(ERROR) << "CreateSharedImage() failed.";
return nullptr;
}
auto backing = shared_image_representation_factory_->ProduceSkia(
mailbox, context_state_.get());
DCHECK(backing);
// The |backing| will keep a ref on the shared image, so the image will not be
// released until |backing| is released.
shared_image_factory_->DestroySharedImage(mailbox);
return backing;
}
#endif
} // namespace viz
......@@ -268,6 +268,12 @@ class SkiaOutputSurfaceImplOnGpu
// after a short delay.
void CheckReadbackCompletion();
#if defined(OS_APPLE)
std::unique_ptr<gpu::SharedImageRepresentationSkia>
GetOrCreateRenderPassOverlayBacking(
const SkSurfaceCharacterization& characterization);
#endif
class ReleaseCurrent {
public:
ReleaseCurrent(scoped_refptr<gl::GLSurface> gl_surface,
......@@ -348,6 +354,34 @@ class SkiaOutputSurfaceImplOnGpu
int num_readbacks_pending_ = 0;
bool readback_poll_pending_ = false;
#if defined(OS_APPLE)
using UniqueBackingPtr = std::unique_ptr<gpu::SharedImageRepresentationSkia>;
class BackingComparator {
public:
using is_transparent = void;
bool operator()(const UniqueBackingPtr& lhs,
const UniqueBackingPtr& rhs) const {
return lhs->mailbox() < rhs->mailbox();
}
bool operator()(const UniqueBackingPtr& lhs,
const gpu::Mailbox& rhs) const {
return lhs->mailbox() < rhs;
}
bool operator()(const gpu::Mailbox& lhs,
const UniqueBackingPtr& rhs) const {
return lhs < rhs->mailbox();
}
};
// Render pass overlay backings are in flight.
// The base::flat_set uses backing->mailbox() as the unique key.
base::flat_set<UniqueBackingPtr, BackingComparator>
in_flight_render_pass_overlay_backings_;
// Render pass overlay backings are available for reusing.
std::vector<std::unique_ptr<gpu::SharedImageRepresentationSkia>>
available_render_pass_overlay_backings_;
#endif
THREAD_CHECKER(thread_checker_);
base::WeakPtr<SkiaOutputSurfaceImplOnGpu> weak_ptr_;
......
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