Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
SkSL::WGSLCodeGenerator::SwizzleLValue Class Reference
Inheritance diagram for SkSL::WGSLCodeGenerator::SwizzleLValue:
SkSL::WGSLCodeGenerator::LValue

Public Member Functions

 SwizzleLValue (const Context &ctx, std::string name, const Type &t, const ComponentArray &c)
 
std::string load () override
 
std::string store (const std::string &value) override
 
- Public Member Functions inherited from SkSL::WGSLCodeGenerator::LValue
virtual ~LValue ()=default
 
virtual std::string load ()=0
 
virtual std::string store (const std::string &value)=0
 

Detailed Description

Definition at line 1160 of file SkSLWGSLCodeGenerator.cpp.

Constructor & Destructor Documentation

◆ SwizzleLValue()

SkSL::WGSLCodeGenerator::SwizzleLValue::SwizzleLValue ( const Context ctx,
std::string  name,
const Type t,
const ComponentArray c 
)
inline

Definition at line 1163 of file SkSLWGSLCodeGenerator.cpp.

1164 : fContext(ctx)
1165 , fName(std::move(name))
1166 , fType(t)
1167 , fComponents(c) {
1168 // If the component array doesn't cover the entire value, we need to create masks for
1169 // writing back into the lvalue. For example, if the type is vec4 and the component array
1170 // holds `zx`, a GLSL assignment would look like:
1171 // name.zx = new_value;
1172 //
1173 // The equivalent WGSL assignment statement would look like:
1174 // name = vec4<f32>(new_value, name.xw).yzxw;
1175 //
1176 // This replaces name.zy with new_value.xy, and leaves name.xw at their original values.
1177 // By convention, we always put the new value first and the original values second; it might
1178 // be possible to find better arrangements which simplify the assignment overall, but we
1179 // don't attempt this.
1180 int fullSlotCount = fType.slotCount();
1181 SkASSERT(fullSlotCount <= 4);
1182
1183 // First, see which components are used.
1184 // The assignment swizzle must not reuse components.
1185 bool used[4] = {};
1186 for (int8_t component : fComponents) {
1187 SkASSERT(!used[component]);
1188 used[component] = true;
1189 }
1190
1191 // Any untouched components will need to be fetched from the original value.
1192 for (int index = 0; index < fullSlotCount; ++index) {
1193 if (!used[index]) {
1194 fUntouchedComponents.push_back(index);
1195 }
1196 }
1197
1198 // The reintegration swizzle needs to move the components back into their proper slots.
1199 fReintegrationSwizzle.resize(fullSlotCount);
1200 int reintegrateIndex = 0;
1201
1202 // This refills the untouched slots with the original values.
1203 auto refillUntouchedSlots = [&] {
1204 for (int index = 0; index < fullSlotCount; ++index) {
1205 if (!used[index]) {
1206 fReintegrationSwizzle[index] = reintegrateIndex++;
1207 }
1208 }
1209 };
1210
1211 // This places the new-value components into the proper slots.
1212 auto insertNewValuesIntoSlots = [&] {
1213 for (int index = 0; index < fComponents.size(); ++index) {
1214 fReintegrationSwizzle[fComponents[index]] = reintegrateIndex++;
1215 }
1216 };
1217
1218 // When reintegrating the untouched and new values, if the `x` slot is overwritten, we
1219 // reintegrate the new value first. Otherwise, we reintegrate the original value first.
1220 // This increases our odds of getting an identity swizzle for the reintegration.
1221 if (used[0]) {
1222 fReintegrateNewValueFirst = true;
1223 insertNewValuesIntoSlots();
1224 refillUntouchedSlots();
1225 } else {
1226 fReintegrateNewValueFirst = false;
1227 refillUntouchedSlots();
1228 insertNewValuesIntoSlots();
1229 }
1230 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
virtual size_t slotCount() const
Definition: SkSLType.h:457
void resize(int newSize)
Definition: SkFixedArray.h:101
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32

Member Function Documentation

◆ load()

std::string SkSL::WGSLCodeGenerator::SwizzleLValue::load ( )
inlineoverridevirtual

Implements SkSL::WGSLCodeGenerator::LValue.

Definition at line 1232 of file SkSLWGSLCodeGenerator.cpp.

1232 {
1233 return fName + "." + Swizzle::MaskString(fComponents);
1234 }
static std::string MaskString(const ComponentArray &inComponents)

◆ store()

std::string SkSL::WGSLCodeGenerator::SwizzleLValue::store ( const std::string &  value)
inlineoverridevirtual

Implements SkSL::WGSLCodeGenerator::LValue.

Definition at line 1236 of file SkSLWGSLCodeGenerator.cpp.

1236 {
1237 // `variable = `
1238 std::string result = fName;
1239 result += " = ";
1240
1241 if (fUntouchedComponents.empty()) {
1242 // `(new_value);`
1243 result += '(';
1244 result += value;
1245 result += ")";
1246 } else if (fReintegrateNewValueFirst) {
1247 // `vec4<f32>((new_value), `
1248 result += to_wgsl_type(fContext, fType);
1249 result += "((";
1250 result += value;
1251 result += "), ";
1252
1253 // `variable.yz)`
1254 result += fName;
1255 result += '.';
1256 result += Swizzle::MaskString(fUntouchedComponents);
1257 result += ')';
1258 } else {
1259 // `vec4<f32>(variable.yz`
1260 result += to_wgsl_type(fContext, fType);
1261 result += '(';
1262 result += fName;
1263 result += '.';
1264 result += Swizzle::MaskString(fUntouchedComponents);
1265
1266 // `, (new_value))`
1267 result += ", (";
1268 result += value;
1269 result += "))";
1270 }
1271
1272 if (!Swizzle::IsIdentity(fReintegrationSwizzle)) {
1273 // `.wzyx`
1274 result += '.';
1275 result += Swizzle::MaskString(fReintegrationSwizzle);
1276 }
1277
1278 return result + ';';
1279 }
static bool IsIdentity(const ComponentArray &components)
uint8_t value
GAsyncResult * result

The documentation for this class was generated from the following file: