1e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo//
2e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
3e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo// Use of this source code is governed by a BSD-style license that can be
4e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo// found in the LICENSE file.
5e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo//
6e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo
7e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo#include "compiler/translator/RegenerateStructNames.h"
8e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo#include "compiler/translator/compilerdebug.h"
9e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo
10e740addbc2ab1a7928775814115771c96848ac18Zhenyao Movoid RegenerateStructNames::visitSymbol(TIntermSymbol *symbol)
11e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo{
12e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    ASSERT(symbol);
13e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    TType *type = symbol->getTypePointer();
14e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    ASSERT(type);
15e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    TStructure *userType = type->getStruct();
16e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    if (!userType)
17e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        return;
18e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo
19e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    if (mSymbolTable.findBuiltIn(userType->name(), mShaderVersion))
20e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    {
21e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // Built-in struct, do not touch it.
22e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        return;
23e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    }
24e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo
25e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    int uniqueId = userType->uniqueId();
26e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo
27e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    ASSERT(mScopeDepth > 0);
28e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    if (mScopeDepth == 1)
29e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    {
30e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // If a struct is defined at global scope, we don't map its name.
31e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // This is because at global level, the struct might be used to
32e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // declare a uniform, so the same name needs to stay the same for
33e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // vertex/fragment shaders. However, our mapping uses internal ID,
34e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // which will be different for the same struct in vertex/fragment
35e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // shaders.
36e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // This is OK because names for any structs defined in other scopes
37e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // will begin with "_webgl", which is reserved. So there will be
38e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // no conflicts among unmapped struct names from global scope and
39e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // mapped struct names from other scopes.
40e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // However, we need to keep track of these global structs, so if a
41e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // variable is used in a local scope, we don't try to modify the
42e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // struct name through that variable.
43e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        mDeclaredGlobalStructs.insert(uniqueId);
44e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        return;
45e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    }
46e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    if (mDeclaredGlobalStructs.count(uniqueId) > 0)
47e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        return;
48e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    // Map {name} to _webgl_struct_{uniqueId}_{name}.
49e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    const char kPrefix[] = "_webgl_struct_";
50e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    if (userType->name().find(kPrefix) == 0)
51e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    {
52e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        // The name has already been regenerated.
53e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        return;
54e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    }
55e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    std::string id = Str(uniqueId);
56e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    TString tmp = kPrefix + TString(id.c_str());
57e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    tmp += "_" + userType->name();
58e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    userType->setName(tmp);
59e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo}
60e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo
61e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mobool RegenerateStructNames::visitAggregate(Visit, TIntermAggregate *aggregate)
62e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo{
63e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    ASSERT(aggregate);
64e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    switch (aggregate->getOp())
65e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    {
66e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo      case EOpSequence:
67e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        ++mScopeDepth;
68e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        {
69e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo            TIntermSequence &sequence = *(aggregate->getSequence());
70e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo            for (size_t ii = 0; ii < sequence.size(); ++ii)
71e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo            {
72e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo                TIntermNode *node = sequence[ii];
73e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo                ASSERT(node != NULL);
74e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo                node->traverse(this);
75e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo            }
76e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        }
77e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        --mScopeDepth;
78e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        return false;
79e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo      default:
80e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo        return true;
81e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo    }
82e740addbc2ab1a7928775814115771c96848ac18Zhenyao Mo}
83