| // 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) | 
 |     : context_(std::move(context)) { | 
 |   if (!context_ || !context_->IsValid()) { | 
 |     return; | 
 |   } | 
 |  | 
 |   auto unskinned_variant = | 
 |       MakePipelineVariants<UnskinnedVertexShader, UnlitFragmentShader>( | 
 |           *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<SkinnedVertexShader, UnlitFragmentShader>(*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<Pipeline<PipelineDescriptor>> 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<Context> SceneContext::GetContext() const { | 
 |   return context_; | 
 | } | 
 |  | 
 | std::shared_ptr<Texture> SceneContext::GetPlaceholderTexture() const { | 
 |   return placeholder_texture_; | 
 | } | 
 |  | 
 | }  // namespace scene | 
 | }  // namespace impeller |