255 {
257
258 using namespace SkSL;
259 static constexpr int kFailed = -2;
260
262 public:
264
266
267 int passthroughFieldIndex() const { return fPassthroughFieldIndex; }
268
269 uint32_t fieldUseMask() const { return fFieldUseMask; }
270
271 protected:
275 if (def.type().name() == "Varyings") {
276 fVaryingsType = &def.
type();
277 }
278
279 return false;
280 }
284
285 SkASSERT(fVaryingsType && fVaryingsType->matches(fVaryings->type()));
286
287 fInMain = true;
289 fInMain = false;
291 }
293 }
294
296 if (!fInMain) {
298 }
299
302
303 if (fPassthroughFieldIndex == kFailed) {
304
305
307 }
310 }
311
312
316 this->passthroughFailed();
318 }
319 const auto& fa = rs.expression()->as<
FieldAccess>();
321 this->passthroughFailed();
323 }
325 if (baseRef.variable() != fVaryings) {
326 this->passthroughFailed();
328 }
329 if (fPassthroughFieldIndex >= 0) {
330
331
332 if (fa.fieldIndex() != fPassthroughFieldIndex) {
333 this->passthroughFailed();
335 }
336
337
338 return false;
339 }
340 const Field& field = fVaryings->type().fields()[fa.fieldIndex()];
342 this->passthroughFailed();
344 }
345 fPassthroughFieldIndex = fa.fieldIndex();
346
347
348 return false;
349 }
350
352
353 if (!fVaryingsType) {
354 return false;
355 }
358 }
360 if (!fa.base()->type().matches(*fVaryingsType)) {
362 }
363 fFieldUseMask |= 1 << fa.fieldIndex();
364 return false;
365 }
366
367 private:
368 void passthroughFailed() {
369 if (fPassthroughFieldIndex >= 0) {
370 fFieldUseMask |= 1 << fPassthroughFieldIndex;
371 }
372 fPassthroughFieldIndex =
kFailed;
373 }
374
376 const Type* fVaryingsType =
nullptr;
377 const Variable* fVaryings =
nullptr;
378 int fPassthroughFieldIndex = -1;
379 bool fInMain = false;
380 uint32_t fFieldUseMask = 0;
381 };
382
384 v.visit(fsProgram);
385 *deadVaryingMask = ~v.fieldUseMask();
386 return v.passthroughFieldIndex();
387}
bool visit(const Program &program)
const Type & type() const
virtual bool visitStatement(typename T::Statement &statement)
virtual bool visitExpression(typename T::Expression &expression)
virtual bool visitProgramElement(typename T::ProgramElement &programElement)
bool matches(const Type &other) const
Visitor(Ts...) -> Visitor< Ts... >
std::shared_ptr< Context > fContext