Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
sampler_gles.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <algorithm>
8
14
15namespace impeller {
16
17SamplerGLES::SamplerGLES(const SamplerDescriptor& desc) : Sampler(desc) {}
18
19SamplerGLES::~SamplerGLES() = default;
20
21static GLint ToParam(MinMagFilter minmag_filter) {
22 switch (minmag_filter) {
23 case MinMagFilter::kNearest:
24 return GL_NEAREST;
25 case MinMagFilter::kLinear:
26 return GL_LINEAR;
27 }
29}
30
31static GLint ToParam(MinMagFilter minmag_filter, MipFilter mip_filter) {
32 switch (mip_filter) {
33 case MipFilter::kBase:
34 return ToParam(minmag_filter);
35 case MipFilter::kNearest:
36 switch (minmag_filter) {
37 case MinMagFilter::kNearest:
38 return GL_NEAREST_MIPMAP_NEAREST;
39 case MinMagFilter::kLinear:
40 return GL_LINEAR_MIPMAP_NEAREST;
41 }
42 case MipFilter::kLinear:
43 switch (minmag_filter) {
44 case MinMagFilter::kNearest:
45 return GL_NEAREST_MIPMAP_LINEAR;
46 case MinMagFilter::kLinear:
47 return GL_LINEAR_MIPMAP_LINEAR;
48 }
49 }
51}
52
54 bool supports_decal_sampler_address_mode) {
55 switch (mode) {
56 case SamplerAddressMode::kClampToEdge:
57 return GL_CLAMP_TO_EDGE;
58 case SamplerAddressMode::kRepeat:
59 return GL_REPEAT;
60 case SamplerAddressMode::kMirror:
61 return GL_MIRRORED_REPEAT;
62 case SamplerAddressMode::kDecal:
63 if (supports_decal_sampler_address_mode) {
65 } else {
66 return GL_CLAMP_TO_EDGE;
67 }
68 }
70}
71
72bool SamplerGLES::ConfigureBoundTexture(const TextureGLES& texture,
73 const ProcTableGLES& gl) const {
74 auto target = ToTextureTarget(texture.GetTextureDescriptor().type);
75
76 if (!target.has_value()) {
77 return false;
78 }
79 const SamplerDescriptor& desc = GetDescriptor();
80
81 GLint mag_filter = ToParam(desc.mag_filter);
82
83 // If the texture doesn't have mipmaps, we can't use mip filtering.
84 GLint min_filter;
85 if (texture.GetTextureDescriptor().mip_count > 1) {
86 min_filter = ToParam(desc.min_filter, desc.mip_filter);
87 } else {
88 min_filter = ToParam(desc.min_filter);
89 }
90
91 gl.TexParameteri(*target, GL_TEXTURE_MIN_FILTER, min_filter);
92 gl.TexParameteri(*target, GL_TEXTURE_MAG_FILTER, mag_filter);
93
94 // Bound the sampled mip range to the levels the texture declares. GLES leaves
95 // GL_TEXTURE_MAX_LEVEL at its default of 1000, so a texture sampled with a
96 // mipmap filter reads as black unless every level down to 1x1 is defined.
97 // Metal and Vulkan allocate exactly mip_count levels, and clamping here gives
98 // the same behavior for a partial, manually uploaded mip chain. The parameter
99 // is unavailable on ES 2.0 without GL_APPLE_texture_max_level, and external
100 // textures have no mip levels, so it is skipped in those cases.
101 if (*target != GL_TEXTURE_EXTERNAL_OES &&
102 gl.GetCapabilities()->SupportsTextureMaxLevel()) {
103 const GLint max_level =
104 static_cast<GLint>(texture.GetTextureDescriptor().mip_count) - 1;
105 gl.TexParameteri(*target, GL_TEXTURE_MAX_LEVEL, max_level);
106 }
107
108 const auto supports_decal_mode =
109 gl.GetCapabilities()->SupportsDecalSamplerAddressMode();
110
111 const auto wrap_s =
112 ToAddressMode(desc.width_address_mode, supports_decal_mode);
113 const auto wrap_t =
114 ToAddressMode(desc.height_address_mode, supports_decal_mode);
115
116 gl.TexParameteri(*target, GL_TEXTURE_WRAP_S, wrap_s);
117 gl.TexParameteri(*target, GL_TEXTURE_WRAP_T, wrap_t);
118
119 if (wrap_s == IMPELLER_GL_CLAMP_TO_BORDER ||
120 wrap_t == IMPELLER_GL_CLAMP_TO_BORDER) {
121 // Transparent black.
122 const GLfloat border_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
123 gl.TexParameterfv(*target, IMPELLER_GL_TEXTURE_BORDER_COLOR, border_color);
124 }
125
126 // Anisotropy is a per-texture parameter in GLES, so it must be written on
127 // every configuration (including resetting it back to 1) to prevent a
128 // previously configured value from leaking into this sampler's state. The
129 // parameter only exists when GL_EXT_texture_filter_anisotropic is present;
130 // it is applied with TexParameterfv, which is core ES 2.0.
131 const uint32_t max_anisotropy =
132 gl.GetCapabilities()->GetMaxSamplerAnisotropy();
133 if (max_anisotropy > 1) {
134 const GLfloat anisotropy[1] = {static_cast<GLfloat>(
135 std::clamp<uint32_t>(desc.max_anisotropy, 1u, max_anisotropy))};
136 gl.TexParameterfv(*target, IMPELLER_GL_TEXTURE_MAX_ANISOTROPY, anisotropy);
137 }
138
139 return true;
140}
141
142} // namespace impeller
const std::shared_ptr< const CapabilitiesGLES > & GetCapabilities() const
uint32_t * target
#define FML_UNREACHABLE()
Definition logging.h:128
FlTexture * texture
std::function< ProfileSample(void)> Sampler
Sampler is run during SamplingProfiler::SampleRepeatedly. Each platform should implement its version ...
constexpr std::optional< GLenum > ToTextureTarget(TextureType type)
static GLint ToAddressMode(SamplerAddressMode mode, bool supports_decal_sampler_address_mode)
SamplerAddressMode
Definition formats.h:618
static GLint ToParam(MinMagFilter minmag_filter)
MipFilter
Options for selecting and filtering between mipmap levels.
Definition formats.h:602
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition formats.h:592
#define IMPELLER_GL_TEXTURE_BORDER_COLOR
Definition gles.h:13
#define IMPELLER_GL_CLAMP_TO_BORDER
Definition gles.h:12
#define IMPELLER_GL_TEXTURE_MAX_ANISOTROPY
Definition gles.h:16
SamplerAddressMode width_address_mode
SamplerAddressMode height_address_mode