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
public:
BuiltInFunctionEmulator();
void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
void MarkBuiltInFunctionsForEmulation(TIntermNode *root);
void Cleanup();
// "name(" becomes "webgl_name_emu(".
static TString GetEmulatedFunctionName(const TString& name);
static TString GetEmulatedFunctionName(const TString &name);
bool IsOutputEmpty() const;
// Output function emulation definition. This should be before any other
// shader source.
void OutputEmulatedFunctions(TInfoSinkBase& out) const;
void OutputEmulatedFunctions(TInfoSinkBase &out) const;
// Add functions that need to be emulated.
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, const TType& param3, 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, const TType *param3,
const char *emulatedFunctionDefinition);
private:
class BuiltInFunctionEmulationMarker;
......@@ -46,28 +48,32 @@ class BuiltInFunctionEmulator
// 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
// emulated one.
bool SetFunctionCalled(TOperator op, const TType& param);
bool SetFunctionCalled(
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 &param);
bool SetFunctionCalled(TOperator op, const TType &param1, const TType &param2);
bool SetFunctionCalled(TOperator op, const TType &param1, const TType &param2, const TType &param3);
class FunctionId {
public:
FunctionId(TOperator op, const TType& param);
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 *param);
FunctionId(TOperator op, const TType *param1, const TType *param2);
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:
TOperator mOp;
TType mParam1;
TType mParam2;
TType mParam3;
// The memory that these TType objects use is freed by PoolAllocator. The BuiltInFunctionEmulator's lifetime
// 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
std::map<FunctionId, std::string> mEmulatedFunctions;
......
......@@ -17,10 +17,10 @@ void InitBuiltInFunctionEmulatorForGLSL(BuiltInFunctionEmulator *emu, sh::GLenum
// evaluated. This is unlikely to show up in real shaders, but is something to
// consider.
TType float1(EbtFloat);
TType float2(EbtFloat, 2);
TType float3(EbtFloat, 3);
TType float4(EbtFloat, 4);
TType *float1 = new TType(EbtFloat);
TType *float2 = new TType(EbtFloat, 2);
TType *float3 = new TType(EbtFloat, 3);
TType *float4 = new TType(EbtFloat, 4);
if (shaderType == GL_FRAGMENT_SHADER)
{
......
......@@ -11,10 +11,10 @@
void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
{
TType float1(EbtFloat);
TType float2(EbtFloat, 2);
TType float3(EbtFloat, 3);
TType float4(EbtFloat, 4);
TType *float1 = new TType(EbtFloat);
TType *float2 = new TType(EbtFloat, 2);
TType *float3 = new TType(EbtFloat, 3);
TType *float4 = new TType(EbtFloat, 4);
emu->addEmulatedFunction(EOpMod, float1, float1,
"float webgl_mod_emu(float x, float y)\n"
......@@ -250,7 +250,7 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" return (y << 16) | x;\n"
"}\n");
TType uint1(EbtUInt);
TType *uint1 = new TType(EbtUInt);
emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
"float webgl_fromSnorm(in uint x) {\n"
......@@ -327,9 +327,9 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" return mul(float4x1(r), float1x3(c));\n"
"}\n");
TType mat2(EbtFloat, 2, 2);
TType mat3(EbtFloat, 3, 3);
TType mat4(EbtFloat, 4, 4);
TType *mat2 = new TType(EbtFloat, 2, 2);
TType *mat3 = new TType(EbtFloat, 3, 3);
TType *mat4 = new TType(EbtFloat, 4, 4);
// Remember here that the parameter matrix is actually the transpose
// of the matrix that we're trying to invert, and the resulting matrix
......@@ -408,10 +408,10 @@ void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu)
" return cof / determinant(transpose(m));\n"
"}\n");
TType bool1(EbtBool);
TType bool2(EbtBool, 2);
TType bool3(EbtBool, 3);
TType bool4(EbtBool, 4);
TType *bool1 = new TType(EbtBool);
TType *bool2 = new TType(EbtBool, 2);
TType *bool3 = new TType(EbtBool, 3);
TType *bool4 = new TType(EbtBool, 4);
// 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.
......
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