// Copyright 2013 The Flutter 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 "impeller/scene/scene_context.h" #include "impeller/core/formats.h" #include "impeller/core/host_buffer.h" #include "impeller/scene/material.h" #include "impeller/scene/shaders/skinned.vert.h" #include "impeller/scene/shaders/unlit.frag.h" #include "impeller/scene/shaders/unskinned.vert.h" namespace impeller { namespace scene { void SceneContextOptions::ApplyToPipelineDescriptor( const Capabilities& capabilities, PipelineDescriptor& desc) const { DepthAttachmentDescriptor depth; depth.depth_compare = CompareFunction::kLess; depth.depth_write_enabled = true; desc.SetDepthStencilAttachmentDescriptor(depth); desc.SetDepthPixelFormat(capabilities.GetDefaultDepthStencilFormat()); StencilAttachmentDescriptor stencil; stencil.stencil_compare = CompareFunction::kAlways; stencil.depth_stencil_pass = StencilOperation::kKeep; desc.SetStencilAttachmentDescriptors(stencil); desc.SetStencilPixelFormat(capabilities.GetDefaultDepthStencilFormat()); desc.SetSampleCount(sample_count); desc.SetPrimitiveType(primitive_type); desc.SetWindingOrder(WindingOrder::kCounterClockwise); desc.SetCullMode(CullMode::kBackFace); } SceneContext::SceneContext(std::shared_ptr context) : context_(std::move(context)) { if (!context_ || !context_->IsValid()) { return; } auto unskinned_variant = MakePipelineVariants( *context_); if (!unskinned_variant) { FML_LOG(ERROR) << "Could not create unskinned pipeline variant."; return; } pipelines_[{PipelineKey{GeometryType::kUnskinned, MaterialType::kUnlit}}] = std::move(unskinned_variant); auto skinned_variant = MakePipelineVariants(*context_); if (!skinned_variant) { FML_LOG(ERROR) << "Could not create skinned pipeline variant."; return; } pipelines_[{PipelineKey{GeometryType::kSkinned, MaterialType::kUnlit}}] = std::move(skinned_variant); { impeller::TextureDescriptor texture_descriptor; texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible; texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt; texture_descriptor.size = {1, 1}; texture_descriptor.mip_count = 1u; placeholder_texture_ = context_->GetResourceAllocator()->CreateTexture(texture_descriptor); placeholder_texture_->SetLabel("Placeholder Texture"); if (!placeholder_texture_) { FML_LOG(ERROR) << "Could not create placeholder texture."; return; } uint8_t pixel[] = {0xFF, 0xFF, 0xFF, 0xFF}; if (!placeholder_texture_->SetContents(pixel, 4)) { FML_LOG(ERROR) << "Could not set contents of placeholder texture."; return; } } host_buffer_ = HostBuffer::Create(GetContext()->GetResourceAllocator()); is_valid_ = true; } SceneContext::~SceneContext() = default; std::shared_ptr> SceneContext::GetPipeline( PipelineKey key, SceneContextOptions opts) const { if (!IsValid()) { return nullptr; } if (auto found = pipelines_.find(key); found != pipelines_.end()) { return found->second->GetPipeline(*context_, opts); } return nullptr; } bool SceneContext::IsValid() const { return is_valid_; } std::shared_ptr SceneContext::GetContext() const { return context_; } std::shared_ptr SceneContext::GetPlaceholderTexture() const { return placeholder_texture_; } } // namespace scene } // namespace impeller