blob: 1041a81bf9da11e465668fc8e7044f12b2fd145d [file] [log] [blame]
// Copyright 2017 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 "garnet/lib/ui/gfx/resources/material.h"
#include "garnet/lib/ui/gfx/engine/session.h"
#include "garnet/lib/ui/gfx/resources/image.h"
#include "garnet/lib/ui/gfx/resources/image_base.h"
#include "garnet/lib/ui/gfx/resources/image_pipe.h"
namespace {
// TODO(SCN-1380): This is a hack that temporarily avoids memory and performance
// issues involving immutable samplers. It relies on the fact that Scenic is
// currently a singleton service with a single vk::Device, with no user-provided
// parameters that affect sampler construction other than image format. SCN-1380
// covers the real task to solve this problem, which involves design work both
// at the Scenic and Escher levels.
escher::SamplerPtr CreateNV12Sampler(escher::ResourceRecycler* recycler) {
static vk::Device last_device;
static escher::SamplerPtr last_sampler;
if (recycler->vulkan_context().device == last_device && last_sampler)
return last_sampler;
if (last_sampler) {
FXL_LOG(WARNING) << "YUV Sampler was not successfully cached, memory "
"footprint will increase.";
}
last_device = recycler->vulkan_context().device;
last_sampler = fxl::MakeRefCounted<escher::Sampler>(
recycler, vk::Format::eG8B8R82Plane420Unorm, vk::Filter::eLinear);
return last_sampler;
}
} // namespace
namespace scenic_impl {
namespace gfx {
const ResourceTypeInfo Material::kTypeInfo = {ResourceType::kMaterial,
"Material"};
Material::Material(Session* session, ResourceId id)
: Resource(session, id, Material::kTypeInfo),
escher_material_(fxl::MakeRefCounted<escher::Material>()) {}
void Material::SetColor(float red, float green, float blue, float alpha) {
escher_material_->set_color(escher::vec4(red, green, blue, alpha));
// TODO(rosswang): This and related affordances are not enough to allow
// transparent textures to work on opaque materials. It may be worthwhile to
// surface the |opaque| flag on the Scenic client API to support this.
escher_material_->set_opaque(alpha == 1);
}
void Material::SetTexture(ImageBasePtr texture_image) {
texture_ = std::move(texture_image);
}
void Material::UpdateEscherMaterial(escher::BatchGpuUploader* gpu_uploader) {
// Update our escher::Material if our texture's presented image changed.
escher::ImagePtr escher_image;
if (texture_) {
texture_->UpdateEscherImage(gpu_uploader);
escher_image = texture_->GetEscherImage();
}
const escher::TexturePtr& escher_texture = escher_material_->texture();
if (!escher_texture || escher_image != escher_texture->image()) {
escher::TexturePtr texture;
if (escher_image) {
auto recycler = session()->resource_context().escher_resource_recycler;
// TODO(SCN-1403): Technically, eG8B8R82Plane420Unorm is not enough to
// assume NV12, but it's currently the only format we support at the
// sampler level.
if (escher_image->format() == vk::Format::eG8B8R82Plane420Unorm) {
texture = fxl::MakeRefCounted<escher::Texture>(
recycler, CreateNV12Sampler(recycler), escher_image);
} else {
texture =
escher::Texture::New(recycler, escher_image, vk::Filter::eLinear);
// TODO(ES-199, ES-200): Reusing samplers is just good policy, but it is
// required for immutable samplers because, until these bugs are fixed,
// Escher will keep these samplers around forever.
FXL_DCHECK(!texture->sampler()->is_immutable())
<< "Immutable samplers need to be cached to avoid unbounded memory "
"consumption";
}
}
escher_material_->SetTexture(std::move(texture));
}
}
} // namespace gfx
} // namespace scenic_impl