blob: 8d1bc223ac38fd2024f9a377e9034202771025b1 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "image_pipe_surface_async.h"
namespace image_pipe_swapchain {
void ImagePipeSurfaceAsync::AddImage(uint32_t image_id,
fuchsia::images::ImageInfo image_info,
zx::vmo buffer, uint64_t size_bytes) {
std::lock_guard<std::mutex> lock(mutex_);
image_pipe_->AddImage(image_id, std::move(image_info), std::move(buffer), 0,
size_bytes,
fuchsia::images::MemoryType::VK_DEVICE_MEMORY);
}
void ImagePipeSurfaceAsync::RemoveImage(uint32_t image_id) {
std::unique_lock<std::mutex> lock(mutex_);
for (auto iter = queue_.begin(); iter != queue_.end();) {
if (iter->image_id == image_id) {
iter = queue_.erase(iter);
} else {
iter++;
}
}
// TODO(SCN-1107) - remove this workaround
static constexpr bool kUseWorkaround = true;
while (kUseWorkaround && present_pending_) {
lock.unlock();
std::this_thread::sleep_for(std::chrono::milliseconds(5));
lock.lock();
}
image_pipe_->RemoveImage(image_id);
}
void ImagePipeSurfaceAsync::PresentImage(
uint32_t image_id, std::vector<zx::event> acquire_fences,
std::vector<zx::event> release_fences) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push_back(
{image_id, std::move(acquire_fences), std::move(release_fences)});
if (!present_pending_) {
PresentNextImageLocked();
}
}
void ImagePipeSurfaceAsync::PresentNextImageLocked() {
assert(!present_pending_);
if (queue_.empty())
return;
// To guarantee FIFO mode, we can't have Scenic drop any of our frames.
// We accomplish that sending the next one only when we receive the callback
// for the previous one. We don't use the presentation info timing
// parameters because we really just want to push out the next image asap.
uint64_t presentation_time = zx_clock_get_monotonic();
auto& present = queue_.front();
image_pipe_->PresentImage(present.image_id, presentation_time,
std::move(present.acquire_fences),
std::move(present.release_fences),
// This callback happening in a separate thread.
[this](fuchsia::images::PresentationInfo pinfo) {
std::lock_guard<std::mutex> lock(mutex_);
present_pending_ = false;
PresentNextImageLocked();
});
queue_.erase(queue_.begin());
present_pending_ = true;
}
} // namespace image_pipe_swapchain