| 415 | } |
| 416 | |
| 417 | bool LoadTexture(Rml::TextureHandle& texture_handle, Rml::Vector2i& texture_dimensions, const Rml::String& source) override { |
| 418 | flush_image_from_bytes_queue(); |
| 419 | |
| 420 | auto it = image_from_bytes_map.find(source); |
| 421 | if (it == image_from_bytes_map.end()) { |
| 422 | // Return a transparent texture if the image can't be found. |
| 423 | texture_handle = 1; |
| 424 | texture_dimensions.x = 1; |
| 425 | texture_dimensions.y = 1; |
| 426 | return true; |
| 427 | } |
| 428 | |
| 429 | RT64::Texture* texture = nullptr; |
| 430 | std::unique_ptr<plume::RenderBuffer> texture_buffer; |
| 431 | ImageFromBytes& img = it->second; |
| 432 | copy_command_list_->begin(); |
| 433 | |
| 434 | switch (img.type) { |
| 435 | case ImageType::RGBA32: |
| 436 | { |
| 437 | // Read the image header (two 32-bit values for width and height respectively). |
| 438 | uint32_t rowPitch = img.width * 4; |
| 439 | size_t byteCount = img.height * rowPitch; |
| 440 | texture = new RT64::Texture(); |
| 441 | RT64::TextureCache::setRGBA32(texture, device_, copy_command_list_.get(), reinterpret_cast<const uint8_t*>(img.bytes.data()), byteCount, img.width, img.height, rowPitch, texture_buffer, nullptr); |
| 442 | } |
| 443 | break; |
| 444 | case ImageType::File: |
| 445 | { |
| 446 | // TODO: This data copy can be avoided when RT64::TextureCache::loadTextureFromBytes's function is updated to only take a pointer and size as the input. |
| 447 | std::vector<uint8_t> data_copy(img.bytes.data(), img.bytes.data() + img.bytes.size()); |
| 448 | texture = RT64::TextureCache::loadTextureFromBytes(device_, copy_command_list_.get(), data_copy, texture_buffer); |
| 449 | } |
| 450 | break; |
| 451 | } |
| 452 | |
| 453 | copy_command_list_->end(); |
| 454 | copy_command_queue_->executeCommandLists(copy_command_list_.get(), copy_command_fence_.get()); |
| 455 | copy_command_queue_->waitForCommandFence(copy_command_fence_.get()); |
| 456 | |
| 457 | if (texture == nullptr) { |
| 458 | return false; |
| 459 | } |
| 460 | |
| 461 | texture_handle = texture_count_++; |
| 462 | texture_dimensions.x = texture->width; |
| 463 | texture_dimensions.y = texture->height; |
| 464 | |
| 465 | std::unique_ptr<plume::RenderDescriptorSet> set = texture_set_builder_->create(device_); |
| 466 | set->setTexture(gTexture_descriptor_index, texture->texture.get(), plume::RenderTextureLayout::SHADER_READ); |
| 467 | textures_.emplace(texture_handle, TextureHandle{ std::move(texture->texture), std::move(set), false }); |
| 468 | delete texture; |
| 469 | |
| 470 | return true; |
| 471 | } |
| 472 | |
| 473 | bool GenerateTexture(Rml::TextureHandle& texture_handle, const Rml::byte* source, const Rml::Vector2i& source_dimensions) override { |
| 474 | if (source_dimensions.x == 0 || source_dimensions.y == 0) { |