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( ...@@ -854,7 +854,7 @@ void SkiaRenderer::DidReceiveReleasedOverlays(
for (const auto& mailbox : released_overlays) { for (const auto& mailbox : released_overlays) {
auto it = awaiting_release_overlay_locks_.find(mailbox); auto it = awaiting_release_overlay_locks_.find(mailbox);
if (it == awaiting_release_overlay_locks_.end()) { if (it == awaiting_release_overlay_locks_.end()) {
DLOG(ERROR) << "Got an unexpected mailbox"; DLOG(FATAL) << "Got an unexpected mailbox";
continue; continue;
} }
awaiting_release_overlay_locks_.erase(it); awaiting_release_overlay_locks_.erase(it);
......
...@@ -362,7 +362,7 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer { ...@@ -362,7 +362,7 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
const DisplayResourceProvider::ScopedReadLockSharedImage& rhs) const; const DisplayResourceProvider::ScopedReadLockSharedImage& rhs) const;
}; };
// a set for locks of overlays which are waiting for releasing. // 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, base::flat_set<DisplayResourceProvider::ScopedReadLockSharedImage,
ScopedReadLockComparator> ScopedReadLockComparator>
awaiting_release_overlay_locks_; awaiting_release_overlay_locks_;
......
...@@ -117,7 +117,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputDeviceBufferQueue : public SkiaOutputDevice { ...@@ -117,7 +117,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputDeviceBufferQueue : public SkiaOutputDevice {
bool operator()(const OverlayData& lhs, const gpu::Mailbox& rhs) const; bool operator()(const OverlayData& lhs, const gpu::Mailbox& rhs) const;
bool operator()(const gpu::Mailbox& lhs, const OverlayData& 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. // key.
base::flat_set<OverlayData, OverlayDataComparator> overlays_; base::flat_set<OverlayData, OverlayDataComparator> overlays_;
......
...@@ -995,51 +995,21 @@ void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays( ...@@ -995,51 +995,21 @@ void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays(
// GL is used on MacOS and GL doesn't need semaphores. // GL is used on MacOS and GL doesn't need semaphores.
DCHECK(begin_semaphores.empty()); DCHECK(begin_semaphores.empty());
DCHECK(end_semaphores.empty()); DCHECK(end_semaphores.empty());
std::vector<gpu::Mailbox> render_pass_overlay_mailboxes;
for (auto& overlay : overlays) { for (auto& overlay : overlays) {
if (!overlay.ddl) if (!overlay.ddl)
continue; continue;
base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use; base::Optional<gpu::raster::GrShaderCache::ScopedCacheUse> cache_use;
if (dependency_->GetGrShaderCache()) { if (dependency_->GetGrShaderCache()) {
cache_use.emplace(dependency_->GetGrShaderCache(), cache_use.emplace(dependency_->GetGrShaderCache(),
gpu::kDisplayCompositorClientId); 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(); const auto& characterization = overlay.ddl->characterization();
auto backing = GetOrCreateRenderPassOverlayBacking(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.
DCHECK(overlay.mailbox.IsZero()); DCHECK(overlay.mailbox.IsZero());
overlay.mailbox = gpu::Mailbox::GenerateForSharedImage(); overlay.mailbox = backing->mailbox();
shared_image_factory_->CreateSharedImage( auto scoped_access = backing->BeginScopedWriteAccess(
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(
/*final_msaa_count=*/0, characterization.surfaceProps(), /*final_msaa_count=*/0, characterization.surfaceProps(),
/*begin_semaphores=*/nullptr, /*begin_semaphores=*/nullptr,
/*end_semaphores=*/nullptr, /*end_semaphores=*/nullptr,
...@@ -1048,17 +1018,16 @@ void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays( ...@@ -1048,17 +1018,16 @@ void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays(
DCHECK(result); DCHECK(result);
context_state_->gr_context()->flushAndSubmit(); context_state_->gr_context()->flushAndSubmit();
scoped_access.reset(); scoped_access.reset();
representation->SetCleared(); backing->SetCleared();
in_flight_render_pass_overlay_backings_.insert(std::move(backing));
render_pass_overlay_mailboxes.push_back(overlay.mailbox);
} }
promise_image_access_helper_.EndAccess(); promise_image_access_helper_.EndAccess();
output_device_->ScheduleOverlays(std::move(overlays)); output_device_->ScheduleOverlays(std::move(overlays));
for (const auto& mailbox : render_pass_overlay_mailboxes) { // Release any backings which are not reused by the current frame, probably
shared_image_factory_->DestroySharedImage(mailbox); // because the properties of render passes are changed or render passes are
} // removed.
available_render_pass_overlay_backings_.clear();
#else #else
DCHECK(image_contexts.empty()); DCHECK(image_contexts.empty());
output_device_->ScheduleOverlays(std::move(overlays)); output_device_->ScheduleOverlays(std::move(overlays));
...@@ -1466,6 +1435,26 @@ void SkiaOutputSurfaceImplOnGpu::DidSwapBuffersCompleteInternal( ...@@ -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( PostTaskToClientThread(
base::BindOnce(did_swap_buffer_complete_callback_, params, pixel_size)); base::BindOnce(did_swap_buffer_complete_callback_, params, pixel_size));
} }
...@@ -1516,4 +1505,72 @@ void SkiaOutputSurfaceImplOnGpu::CheckReadbackCompletion() { ...@@ -1516,4 +1505,72 @@ void SkiaOutputSurfaceImplOnGpu::CheckReadbackCompletion() {
ScheduleCheckReadbackCompletion(); 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 } // namespace viz
...@@ -268,6 +268,12 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -268,6 +268,12 @@ class SkiaOutputSurfaceImplOnGpu
// after a short delay. // after a short delay.
void CheckReadbackCompletion(); void CheckReadbackCompletion();
#if defined(OS_APPLE)
std::unique_ptr<gpu::SharedImageRepresentationSkia>
GetOrCreateRenderPassOverlayBacking(
const SkSurfaceCharacterization& characterization);
#endif
class ReleaseCurrent { class ReleaseCurrent {
public: public:
ReleaseCurrent(scoped_refptr<gl::GLSurface> gl_surface, ReleaseCurrent(scoped_refptr<gl::GLSurface> gl_surface,
...@@ -348,6 +354,34 @@ class SkiaOutputSurfaceImplOnGpu ...@@ -348,6 +354,34 @@ class SkiaOutputSurfaceImplOnGpu
int num_readbacks_pending_ = 0; int num_readbacks_pending_ = 0;
bool readback_poll_pending_ = false; 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_); THREAD_CHECKER(thread_checker_);
base::WeakPtr<SkiaOutputSurfaceImplOnGpu> weak_ptr_; 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