Commit 950457b3 by Olli Etuaho

Fix destructing TStrings through BuiltInFunctionEmulator after free

BuiltInFunctionEmulator gets destructed after the PoolAllocator has already freed memory. That's why BuiltInFunctionEmulator can't hold any objects that contain parts stored in the memory pool that would be accessed in its destructor. Use only pointers to TType objects inside BuiltInFunctionEmulator, so that the BuiltInFunctionEmulator destructor doesn't access TStrings which have data in the memory pool. Also fix style issues in BuiltInFunctionEmulator. BUG=angleproject:1010 TEST=dEQP-GLES3.functional.shaders.builtin_functions.* Change-Id: Ic35caf80bf125d0427c2ed2024e98657756103b6 Reviewed-on: https://chromium-review.googlesource.com/272738Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent c378cd8a
...@@ -21,23 +21,25 @@ class BuiltInFunctionEmulator ...@@ -21,23 +21,25 @@ class BuiltInFunctionEmulator
public: public:
BuiltInFunctionEmulator(); BuiltInFunctionEmulator();
void MarkBuiltInFunctionsForEmulation(TIntermNode* root); void MarkBuiltInFunctionsForEmulation(TIntermNode *root);
void Cleanup(); void Cleanup();
// "name(" becomes "webgl_name_emu(". // "name(" becomes "webgl_name_emu(".
static TString GetEmulatedFunctionName(const TString& name); static TString GetEmulatedFunctionName(const TString &name);
bool IsOutputEmpty() const; bool IsOutputEmpty() const;
// Output function emulation definition. This should be before any other // Output function emulation definition. This should be before any other
// shader source. // shader source.
void OutputEmulatedFunctions(TInfoSinkBase& out) const; void OutputEmulatedFunctions(TInfoSinkBase &out) const;
// Add functions that need to be emulated. // Add functions that need to be emulated.
void addEmulatedFunction(TOperator op, const TType& param, const char* emulatedFunctionDefinition); void addEmulatedFunction(TOperator op, const TType *param, const char *emulatedFunctionDefinition);
void addEmulatedFunction(TOperator op, const TType& param1, const TType& param2, const char* emulatedFunctionDefinition); void addEmulatedFunction(TOperator op, const TType *param1, const TType *param2,
void addEmulatedFunction(TOperator op, const TType& param1, const TType& param2, const TType& param3, const char* emulatedFunctionDefinition); const char *emulatedFunctionDefinition);
void addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, const TType *param3,
const char *emulatedFunctionDefinition);
private: private:
class BuiltInFunctionEmulationMarker; class BuiltInFunctionEmulationMarker;
...@@ -46,28 +48,32 @@ class BuiltInFunctionEmulator ...@@ -46,28 +48,32 @@ class BuiltInFunctionEmulator
// emulated. If the function is not in mEmulatedFunctions, this becomes a // emulated. If the function is not in mEmulatedFunctions, this becomes a
// no-op. Returns true if the function call needs to be replaced with an // no-op. Returns true if the function call needs to be replaced with an
// emulated one. // emulated one.
bool SetFunctionCalled(TOperator op, const TType& param); bool SetFunctionCalled(TOperator op, const TType &param);
bool SetFunctionCalled( bool SetFunctionCalled(TOperator op, const TType &param1, const TType &param2);
TOperator op, const TType& param1, const TType& param2); bool SetFunctionCalled(TOperator op, const TType &param1, const TType &param2, const TType &param3);
bool SetFunctionCalled(
TOperator op, const TType& param1, const TType& param2, const TType& param3);
class FunctionId { class FunctionId {
public: public:
FunctionId(TOperator op, const TType& param); FunctionId(TOperator op, const TType *param);
FunctionId(TOperator op, const TType& param1, const TType& param2); FunctionId(TOperator op, const TType *param1, const TType *param2);
FunctionId(TOperator op, const TType& param1, const TType& param2, const TType& param3); FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3);
bool operator==(const FunctionId& other) const; bool operator==(const FunctionId &other) const;
bool operator<(const FunctionId& other) const; bool operator<(const FunctionId &other) const;
FunctionId getCopy() const;
private: private:
TOperator mOp; TOperator mOp;
TType mParam1;
TType mParam2; // The memory that these TType objects use is freed by PoolAllocator. The BuiltInFunctionEmulator's lifetime
TType mParam3; // can extend until after the memory pool is freed, but that's not an issue since this class never destructs
// these objects.
const TType *mParam1;
const TType *mParam2;
const TType *mParam3;
}; };
bool SetFunctionCalled(const FunctionId& functionId); bool SetFunctionCalled(const FunctionId &functionId);
// Map from function id to emulated function definition // Map from function id to emulated function definition
std::map<FunctionId, std::string> mEmulatedFunctions; std::map<FunctionId, std::string> mEmulatedFunctions;
......
...@@ -17,10 +17,10 @@ void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum ...@@ -17,10 +17,10 @@ void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum
// evaluated. This is unlikely to show up in real shaders, but is something to // evaluated. This is unlikely to show up in real shaders, but is something to
// consider. // consider.
TType float1(EbtFloat); TType *float1 = new TType(EbtFloat);
TType float2(EbtFloat, 2); TType *float2 = new TType(EbtFloat, 2);
TType float3(EbtFloat, 3); TType *float3 = new TType(EbtFloat, 3);
TType float4(EbtFloat, 4); TType *float4 = new TType(EbtFloat, 4);
if (shaderType == GL_FRAGMENT_SHADER) if (shaderType == GL_FRAGMENT_SHADER)
{ {
......
...@@ -11,10 +11,10 @@ ...@@ -11,10 +11,10 @@
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
{ {
TType float1(EbtFloat); TType *float1 = new TType(EbtFloat);
TType float2(EbtFloat, 2); TType *float2 = new TType(EbtFloat, 2);
TType float3(EbtFloat, 3); TType *float3 = new TType(EbtFloat, 3);
TType float4(EbtFloat, 4); TType *float4 = new TType(EbtFloat, 4);
emu->addEmulatedFunction(EOpMod, float1, float1, emu->addEmulatedFunction(EOpMod, float1, float1,
"float webgl_mod_emu(float x, float y)\n" "float webgl_mod_emu(float x, float y)\n"
...@@ -250,7 +250,7 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) ...@@ -250,7 +250,7 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" return (y << 16) | x;\n" " return (y << 16) | x;\n"
"}\n"); "}\n");
TType uint1(EbtUInt); TType *uint1 = new TType(EbtUInt);
emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1, emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
"float webgl_fromSnorm(in uint x) {\n" "float webgl_fromSnorm(in uint x) {\n"
...@@ -327,9 +327,9 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) ...@@ -327,9 +327,9 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" return mul(float4x1(r), float1x3(c));\n" " return mul(float4x1(r), float1x3(c));\n"
"}\n"); "}\n");
TType mat2(EbtFloat, 2, 2); TType *mat2 = new TType(EbtFloat, 2, 2);
TType mat3(EbtFloat, 3, 3); TType *mat3 = new TType(EbtFloat, 3, 3);
TType mat4(EbtFloat, 4, 4); TType *mat4 = new TType(EbtFloat, 4, 4);
// Remember here that the parameter matrix is actually the transpose // Remember here that the parameter matrix is actually the transpose
// of the matrix that we're trying to invert, and the resulting matrix // of the matrix that we're trying to invert, and the resulting matrix
...@@ -408,10 +408,10 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) ...@@ -408,10 +408,10 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" return cof / determinant(transpose(m));\n" " return cof / determinant(transpose(m));\n"
"}\n"); "}\n");
TType bool1(EbtBool); TType *bool1 = new TType(EbtBool);
TType bool2(EbtBool, 2); TType *bool2 = new TType(EbtBool, 2);
TType bool3(EbtBool, 3); TType *bool3 = new TType(EbtBool, 3);
TType bool4(EbtBool, 4); TType *bool4 = new TType(EbtBool, 4);
// Emulate ESSL3 variant of mix that takes last argument as boolean vector. // Emulate ESSL3 variant of mix that takes last argument as boolean vector.
// genType mix (genType x, genType y, genBType a): Selects which vector each returned component comes from. // genType mix (genType x, genType y, genBType a): Selects which vector each returned component comes from.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment