| // 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 |