blob: 8c8f005389c20a778c649217f12aab3e36b4cbfa [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 "lib/escher/vk/impl/framebuffer_allocator.h"
#include "lib/escher/third_party/granite/vk/render_pass.h"
#include "lib/escher/util/hasher.h"
#include "lib/escher/util/trace_macros.h"
#include "lib/escher/vk/impl/framebuffer.h"
#include "lib/escher/vk/impl/render_pass_cache.h"
#include "lib/escher/vk/render_pass_info.h"
namespace escher {
namespace impl {
FramebufferAllocator::FramebufferAllocator(
ResourceRecycler* recycler, impl::RenderPassCache* render_pass_cache)
: recycler_(recycler), render_pass_cache_(render_pass_cache) {}
const impl::FramebufferPtr& FramebufferAllocator::ObtainFramebuffer(
const RenderPassInfo& info) {
TRACE_DURATION("gfx",
"escher::impl::FramebufferAllocator::ObtainFramebuffer");
// TODO(ES-75): consider making RenderPassInfo a subclass of Hashable
// so that we can directly look up the Framebuffer without first looking up
// the RenderPass (for the presumably-common case where the Framebuffer
// already exists).
auto& render_pass = render_pass_cache_->ObtainRenderPass(info);
FXL_DCHECK(render_pass);
Hasher h;
h.u64(render_pass->uid());
for (uint32_t i = 0; i < info.num_color_attachments; i++) {
FXL_DCHECK(info.color_attachments[i]);
h.u64(info.color_attachments[i]->uid());
}
if (info.depth_stencil_attachment) {
h.u64(info.depth_stencil_attachment->uid());
}
// TODO(ES-74): track cache hit/miss rates.
Hash hash = h.value();
auto pair = framebuffer_cache_.Obtain(hash);
if (!pair.second) {
// The cache didn't already have a Framebuffer so it returns an empty
// FramebufferPtr that we will point at a newly-created Framebuffer.
//
// TODO(ES-76): it smells weird to use an ObjectPool to hold possibly-null
// RefPtrs and then fill them in here. Maybe ObjectPool can be rejiggered
// to make this more elegant?
TRACE_DURATION(
"gfx", "escher::FramebufferAllocator::ObtainFramebuffer (creation)");
FXL_DCHECK(!pair.first->framebuffer);
pair.first->framebuffer =
fxl::MakeRefCounted<impl::Framebuffer>(recycler_, render_pass, info);
}
FXL_DCHECK(pair.first->framebuffer);
return pair.first->framebuffer;
}
} // namespace impl
} // namespace escher