| // 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 "lib/escher/shape/rounded_rect_factory.h" |
| |
| #include "lib/escher/escher.h" |
| #include "lib/escher/impl/gpu_uploader.h" |
| #include "lib/escher/shape/mesh.h" |
| #include "lib/escher/shape/mesh_spec.h" |
| #include "lib/escher/vk/buffer_factory.h" |
| |
| namespace escher { |
| |
| RoundedRectFactory::RoundedRectFactory(EscherWeakPtr weak_escher) |
| : ResourceRecycler(std::move(weak_escher)), |
| buffer_factory_(std::make_unique<BufferFactory>(GetEscherWeakPtr())), |
| uploader_(escher()->gpu_uploader()) {} |
| |
| RoundedRectFactory::~RoundedRectFactory() {} |
| |
| MeshPtr RoundedRectFactory::NewRoundedRect(const RoundedRectSpec& spec, |
| const MeshSpec& mesh_spec) { |
| auto index_buffer = GetIndexBuffer(spec, mesh_spec); |
| |
| auto counts = GetRoundedRectMeshVertexAndIndexCounts(spec); |
| uint32_t vertex_count = counts.first; |
| uint32_t index_count = counts.second; |
| size_t vertex_buffer_size = vertex_count * mesh_spec.GetStride(); |
| |
| auto vertex_buffer = |
| buffer_factory_->NewBuffer(vertex_buffer_size, |
| vk::BufferUsageFlagBits::eVertexBuffer | |
| vk::BufferUsageFlagBits::eTransferDst, |
| vk::MemoryPropertyFlagBits::eDeviceLocal); |
| |
| impl::GpuUploader::Writer writer = uploader_->GetWriter(vertex_buffer_size); |
| GenerateRoundedRectVertices(spec, mesh_spec, writer.ptr(), writer.size()); |
| writer.WriteBuffer(vertex_buffer, {0, 0, vertex_buffer->size()}, |
| Semaphore::New(vk_device())); |
| writer.Submit(); |
| |
| BoundingBox bounding_box = |
| spec.width > 0.f && spec.height > 0.f |
| ? BoundingBox(-0.5f * vec3(spec.width, spec.height, 0), |
| 0.5f * vec3(spec.width, spec.height, 0)) |
| : BoundingBox(); |
| |
| return fxl::MakeRefCounted<Mesh>( |
| static_cast<ResourceRecycler*>(this), mesh_spec, bounding_box, |
| vertex_count, index_count, vertex_buffer, std::move(index_buffer)); |
| } |
| |
| BufferPtr RoundedRectFactory::GetIndexBuffer(const RoundedRectSpec& spec, |
| const MeshSpec& mesh_spec) { |
| // Lazily create index buffer. Since the rounded-rect tessellation functions |
| // don't currently take |RoundedRectSpec.zoom| into account, we can always |
| // return the same index buffer. |
| if (!index_buffer_) { |
| uint32_t index_count = GetRoundedRectMeshVertexAndIndexCounts(spec).second; |
| size_t index_buffer_size = index_count * MeshSpec::kIndexSize; |
| |
| index_buffer_ = |
| buffer_factory_->NewBuffer(index_buffer_size, |
| vk::BufferUsageFlagBits::eIndexBuffer | |
| vk::BufferUsageFlagBits::eTransferDst, |
| vk::MemoryPropertyFlagBits::eDeviceLocal); |
| |
| impl::GpuUploader::Writer writer = uploader_->GetWriter(index_buffer_size); |
| GenerateRoundedRectIndices(spec, mesh_spec, writer.ptr(), writer.size()); |
| writer.WriteBuffer(index_buffer_, {0, 0, index_buffer_->size()}, |
| SemaphorePtr()); |
| writer.Submit(); |
| } |
| return index_buffer_; |
| } |
| |
| } // namespace escher |