mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Wire up samplers.
This commit is contained in:
parent
135433a0d1
commit
f86c10efca
@ -44,6 +44,8 @@ impeller_component("compositor") {
|
||||
"renderer.mm",
|
||||
"sampler.h",
|
||||
"sampler.mm",
|
||||
"sampler_descriptor.h",
|
||||
"sampler_descriptor.mm",
|
||||
"shader_function.h",
|
||||
"shader_function.mm",
|
||||
"shader_library.h",
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
namespace impeller {
|
||||
|
||||
class ShaderLibrary;
|
||||
class SamplerLibrary;
|
||||
class CommandBuffer;
|
||||
class Allocator;
|
||||
|
||||
@ -39,6 +40,8 @@ class Context {
|
||||
|
||||
std::shared_ptr<ShaderLibrary> GetShaderLibrary() const;
|
||||
|
||||
std::shared_ptr<SamplerLibrary> GetSamplerLibrary() const;
|
||||
|
||||
std::shared_ptr<PipelineLibrary> GetPipelineLibrary() const;
|
||||
|
||||
std::shared_ptr<CommandBuffer> CreateRenderCommandBuffer() const;
|
||||
@ -49,6 +52,7 @@ class Context {
|
||||
id<MTLCommandQueue> transfer_queue_ = nullptr;
|
||||
std::shared_ptr<ShaderLibrary> shader_library_;
|
||||
std::shared_ptr<PipelineLibrary> pipeline_library_;
|
||||
std::shared_ptr<SamplerLibrary> sampler_library_;
|
||||
std::shared_ptr<Allocator> permanents_allocator_;
|
||||
std::shared_ptr<Allocator> transients_allocator_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "flutter/fml/paths.h"
|
||||
#include "impeller/compositor/allocator.h"
|
||||
#include "impeller/compositor/command_buffer.h"
|
||||
#include "impeller/compositor/sampler_descriptor.h"
|
||||
#include "impeller/compositor/shader_library.h"
|
||||
|
||||
namespace impeller {
|
||||
@ -55,6 +56,12 @@ Context::Context(std::string shaders_directory)
|
||||
std::shared_ptr<PipelineLibrary>(new PipelineLibrary(device_));
|
||||
}
|
||||
|
||||
// Setup the sampler library.
|
||||
{ //
|
||||
sampler_library_ =
|
||||
std::shared_ptr<SamplerLibrary>(new SamplerLibrary(device_));
|
||||
}
|
||||
|
||||
{
|
||||
transients_allocator_ = std::shared_ptr<Allocator>(
|
||||
new Allocator(device_, "Impeller Transients Allocator"));
|
||||
@ -86,6 +93,10 @@ std::shared_ptr<PipelineLibrary> Context::GetPipelineLibrary() const {
|
||||
return pipeline_library_;
|
||||
}
|
||||
|
||||
std::shared_ptr<SamplerLibrary> Context::GetSamplerLibrary() const {
|
||||
return sampler_library_;
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandBuffer> Context::CreateRenderCommandBuffer() const {
|
||||
if (!IsValid()) {
|
||||
return nullptr;
|
||||
|
||||
@ -66,6 +66,23 @@ enum class PrimitiveType {
|
||||
// checks. Hence, they are not supported here.
|
||||
};
|
||||
|
||||
enum class MinMagFilter {
|
||||
/// Select nearest to the sample point. Most widely supported.
|
||||
kNearest,
|
||||
/// Select two points and linearly interpolate between them. Some formats may
|
||||
/// not support this.
|
||||
kLinear,
|
||||
};
|
||||
|
||||
enum class SamplerAddressMode {
|
||||
kClampToEdge,
|
||||
kRepeat,
|
||||
kMirror,
|
||||
// More modes are almost always supported but they are usually behind
|
||||
// extensions checks. The ones current in these structs are safe (always
|
||||
// supported) defaults.
|
||||
};
|
||||
|
||||
enum class ColorWriteMask : uint64_t {
|
||||
kNone = 0,
|
||||
kRed = 1 << 0,
|
||||
|
||||
@ -215,6 +215,29 @@ constexpr StoreAction FromMTLStoreAction(MTLStoreAction action) {
|
||||
return StoreAction::kDontCare;
|
||||
}
|
||||
|
||||
constexpr MTLSamplerMinMagFilter ToMTLSamplerMinMagFilter(MinMagFilter filter) {
|
||||
switch (filter) {
|
||||
case MinMagFilter::kNearest:
|
||||
return MTLSamplerMinMagFilterNearest;
|
||||
case MinMagFilter::kLinear:
|
||||
return MTLSamplerMinMagFilterLinear;
|
||||
}
|
||||
return MTLSamplerMinMagFilterNearest;
|
||||
}
|
||||
|
||||
constexpr MTLSamplerAddressMode ToMTLSamplerAddressMode(
|
||||
SamplerAddressMode mode) {
|
||||
switch (mode) {
|
||||
case SamplerAddressMode::kClampToEdge:
|
||||
return MTLSamplerAddressModeClampToEdge;
|
||||
case SamplerAddressMode::kRepeat:
|
||||
return MTLSamplerAddressModeRepeat;
|
||||
case SamplerAddressMode::kMirror:
|
||||
return MTLSamplerAddressModeMirrorRepeat;
|
||||
}
|
||||
return MTLSamplerAddressModeClampToEdge;
|
||||
}
|
||||
|
||||
constexpr MTLClearColor ToMTLClearColor(const Color& color) {
|
||||
return MTLClearColorMake(color.red, color.green, color.blue, color.alpha);
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ class PipelineLibrary : public std::enable_shared_from_this<PipelineLibrary> {
|
||||
std::shared_ptr<const Pipeline>,
|
||||
ComparableHash<PipelineDescriptor>,
|
||||
ComparableEqual<PipelineDescriptor>>;
|
||||
id<MTLDevice> device_;
|
||||
id<MTLDevice> device_ = nullptr;
|
||||
Pipelines pipelines_;
|
||||
|
||||
PipelineLibrary(id<MTLDevice> device);
|
||||
|
||||
@ -4,17 +4,27 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class SamplerLibrary;
|
||||
|
||||
class Sampler {
|
||||
public:
|
||||
Sampler();
|
||||
bool IsValid() const;
|
||||
|
||||
~Sampler();
|
||||
|
||||
private:
|
||||
friend SamplerLibrary;
|
||||
|
||||
id<MTLSamplerState> state_ = nullptr;
|
||||
|
||||
Sampler(id<MTLSamplerState> state);
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(Sampler);
|
||||
};
|
||||
|
||||
|
||||
@ -6,8 +6,12 @@
|
||||
|
||||
namespace impeller {
|
||||
|
||||
Sampler::Sampler() = default;
|
||||
Sampler::Sampler(id<MTLSamplerState> state) : state_(state) {}
|
||||
|
||||
Sampler::~Sampler() = default;
|
||||
|
||||
bool Sampler::IsValid() const {
|
||||
return state_;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
64
engine/src/flutter/impeller/compositor/sampler_descriptor.h
Normal file
64
engine/src/flutter/impeller/compositor/sampler_descriptor.h
Normal file
@ -0,0 +1,64 @@
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/compositor/comparable.h"
|
||||
#include "impeller/compositor/formats.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class Sampler;
|
||||
class Context;
|
||||
|
||||
struct SamplerDescriptor final : public Comparable<SamplerDescriptor> {
|
||||
MinMagFilter min_filter = MinMagFilter::kNearest;
|
||||
MinMagFilter mag_filter = MinMagFilter::kNearest;
|
||||
|
||||
SamplerAddressMode width_address_mode = SamplerAddressMode::kClampToEdge;
|
||||
SamplerAddressMode height_address_mode = SamplerAddressMode::kClampToEdge;
|
||||
SamplerAddressMode depth_address_mode = SamplerAddressMode::kClampToEdge;
|
||||
|
||||
// Comparable<SamplerDescriptor>
|
||||
std::size_t GetHash() const override {
|
||||
return fml::HashCombine(min_filter, mag_filter, width_address_mode,
|
||||
height_address_mode, depth_address_mode);
|
||||
}
|
||||
|
||||
// Comparable<SamplerDescriptor>
|
||||
bool IsEqual(const SamplerDescriptor& o) const override {
|
||||
return min_filter == o.min_filter && mag_filter == o.mag_filter &&
|
||||
width_address_mode == o.width_address_mode &&
|
||||
height_address_mode == o.height_address_mode &&
|
||||
depth_address_mode == o.depth_address_mode;
|
||||
}
|
||||
};
|
||||
|
||||
class SamplerLibrary {
|
||||
public:
|
||||
~SamplerLibrary();
|
||||
|
||||
std::shared_ptr<const Sampler> GetSampler(SamplerDescriptor descriptor);
|
||||
|
||||
private:
|
||||
friend Context;
|
||||
|
||||
using Samplers = std::unordered_map<SamplerDescriptor,
|
||||
std::shared_ptr<const Sampler>,
|
||||
ComparableHash<SamplerDescriptor>,
|
||||
ComparableEqual<SamplerDescriptor>>;
|
||||
id<MTLDevice> device_ = nullptr;
|
||||
Samplers samplers_;
|
||||
|
||||
SamplerLibrary(id<MTLDevice> device);
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(SamplerLibrary);
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
43
engine/src/flutter/impeller/compositor/sampler_descriptor.mm
Normal file
43
engine/src/flutter/impeller/compositor/sampler_descriptor.mm
Normal file
@ -0,0 +1,43 @@
|
||||
// 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/compositor/sampler_descriptor.h"
|
||||
|
||||
#include "impeller/compositor/formats_metal.h"
|
||||
#include "impeller/compositor/sampler.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
SamplerLibrary::SamplerLibrary(id<MTLDevice> device) : device_(device) {}
|
||||
|
||||
SamplerLibrary::~SamplerLibrary() = default;
|
||||
|
||||
std::shared_ptr<const Sampler> SamplerLibrary::GetSampler(
|
||||
SamplerDescriptor descriptor) {
|
||||
auto found = samplers_.find(descriptor);
|
||||
if (found != samplers_.end()) {
|
||||
return found->second;
|
||||
}
|
||||
if (!device_) {
|
||||
return nullptr;
|
||||
}
|
||||
auto desc = [[MTLSamplerDescriptor alloc] init];
|
||||
desc.minFilter = ToMTLSamplerMinMagFilter(descriptor.min_filter);
|
||||
desc.magFilter = ToMTLSamplerMinMagFilter(descriptor.mag_filter);
|
||||
desc.sAddressMode = MTLSamplerAddressMode(descriptor.width_address_mode);
|
||||
desc.rAddressMode = MTLSamplerAddressMode(descriptor.depth_address_mode);
|
||||
desc.tAddressMode = MTLSamplerAddressMode(descriptor.height_address_mode);
|
||||
auto mtl_sampler = [device_ newSamplerStateWithDescriptor:desc];
|
||||
if (!mtl_sampler) {
|
||||
return nullptr;
|
||||
}
|
||||
auto sampler = std::shared_ptr<Sampler>(new Sampler(mtl_sampler));
|
||||
if (!sampler->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
samplers_[descriptor] = sampler;
|
||||
return sampler;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
@ -32,9 +32,13 @@ EntityRenderer::EntityRenderer(std::string shaders_directory)
|
||||
VertexBufferBuilder<shader::BoxVertexInfo::PerVertexData> vertex_builder;
|
||||
vertex_builder.SetLabel("Box");
|
||||
vertex_builder.AddVertices({
|
||||
{{0, 0, 0.0}, {Color::Red()}}, //
|
||||
{{800, 0.0, 0.0}, {Color::Green()}}, //
|
||||
{{0.0, 600, 0.0}, {Color::Blue()}}, //
|
||||
{{100, 100, 0.0}, {Color::Red()}}, // 1
|
||||
{{800, 100, 0.0}, {Color::Green()}}, // 2
|
||||
{{800, 800, 0.0}, {Color::Blue()}}, // 3
|
||||
|
||||
{{100, 100, 0.0}, {Color::Cyan()}}, // 1
|
||||
{{800, 800, 0.0}, {Color::White()}}, // 3
|
||||
{{100, 800, 0.0}, {Color::Purple()}}, // 4
|
||||
});
|
||||
|
||||
vertex_buffer_ =
|
||||
|
||||
@ -3,9 +3,17 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
in vec4 color;
|
||||
in vec2 interpolated_texture_coordinates;
|
||||
|
||||
uniform sampler2D contents;
|
||||
// uniform sampler2D texture_sampler2;
|
||||
// uniform sampler2D texture_sampler3;
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
frag_color = color;
|
||||
vec4 color1 = texture(contents, interpolated_texture_coordinates);
|
||||
// vec4 color2 = texture(texture_sampler2, interpolated_texture_coordinates);
|
||||
// vec4 color3 = texture(texture_sampler3, interpolated_texture_coordinates);
|
||||
frag_color = color1;
|
||||
}
|
||||
|
||||
@ -8,10 +8,13 @@ uniform UniformBuffer {
|
||||
|
||||
in vec3 vertex_position;
|
||||
in vec4 vertex_color;
|
||||
in vec2 texture_coordinates;
|
||||
|
||||
out vec4 color;
|
||||
out vec2 interpolated_texture_coordinates;
|
||||
|
||||
void main() {
|
||||
gl_Position = uniforms.mvp * vec4(vertex_position, 1.0);
|
||||
color = vertex_color;
|
||||
interpolated_texture_coordinates = texture_coordinates;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user