1bdf2d80f459d43f5a6df074431bacf41584f81b7shannon.woods@transgaming.com#include "precompiled.h" 2ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com// 34526236b5542c17a7bfb2ca0ac41945b5c9c5a8ashannon.woods@transgaming.com// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved. 4ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be 5ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com// found in the LICENSE file. 6ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com// 7ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com 8ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances. 9ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com 1086cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org#include <EGL/eglext.h> 1125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com#include "libGLESv2/main.h" 1225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com#include "libGLESv2/Program.h" 13ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com#include "libGLESv2/renderer/Renderer.h" 14ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com#include "libGLESv2/renderer/Renderer9.h" 15c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com#include "libGLESv2/renderer/Renderer11.h" 16d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com#include "libGLESv2/utilities.h" 173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#include "third_party/trace_event/trace_event.h" 18c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 19c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com#if !defined(ANGLE_ENABLE_D3D11) 2086cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org// Enables use of the Direct3D 11 API for a default display, when available 21c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com#define ANGLE_ENABLE_D3D11 0 22c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com#endif 23ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com 2425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.comnamespace rx 2525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com{ 2625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 2725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.comRenderer::Renderer(egl::Display *display) : mDisplay(display) 2825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com{ 2925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com mD3dCompilerModule = NULL; 3025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com mD3DCompileFunc = NULL; 3125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com} 3225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 3325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.comRenderer::~Renderer() 3425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com{ 3525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (mD3dCompilerModule) 3625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 3725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com FreeLibrary(mD3dCompilerModule); 3825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com mD3dCompilerModule = NULL; 3925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 4025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com} 4125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 4225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.combool Renderer::initializeCompiler() 4325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com{ 443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT0("gpu", "initializeCompiler"); 4525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) 4625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. 4725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; 4825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 4925b5f1d197dc1dea005e59ddc4787bdd5dac2942apatrick@chromium.org for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i) 5025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 5125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3dCompilerModule)) 5225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 5325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com break; 5425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 5525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 5625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES 5725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 5825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (!mD3dCompilerModule) 5925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 600677631ac394a87922e40c07d8d4fc3afe304f4bGeoff Lang // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. 610677631ac394a87922e40c07d8d4fc3afe304f4bGeoff Lang mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL); 620677631ac394a87922e40c07d8d4fc3afe304f4bGeoff Lang } 630677631ac394a87922e40c07d8d4fc3afe304f4bGeoff Lang 640677631ac394a87922e40c07d8d4fc3afe304f4bGeoff Lang if (!mD3dCompilerModule) 650677631ac394a87922e40c07d8d4fc3afe304f4bGeoff Lang { 6625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com ERR("No D3D compiler module found - aborting!\n"); 6725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com return false; 6825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 6925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 704e91d566b61855082158bb105d91683ba84c6ef0shannon.woods@transgaming.com mD3DCompileFunc = reinterpret_cast<pCompileFunc>(GetProcAddress(mD3dCompilerModule, "D3DCompile")); 7125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com ASSERT(mD3DCompileFunc); 7225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 7325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com return mD3DCompileFunc != NULL; 7425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com} 7525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 7625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com// Compiles HLSL code into executable binaries 77d3d4208e0d4f34708db30d2adb953c2446588245shannon.woods@transgaming.comShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags) 7825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com{ 7925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (!hlsl) 8025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 8125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com return NULL; 8225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 8325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 8425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com HRESULT result = S_OK; 854526236b5542c17a7bfb2ca0ac41945b5c9c5a8ashannon.woods@transgaming.com UINT flags = 0; 8625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com std::string sourceText; 8725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (gl::perfActive()) 8825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 8925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com flags |= D3DCOMPILE_DEBUG; 90d3d4208e0d4f34708db30d2adb953c2446588245shannon.woods@transgaming.com 9125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com#ifdef NDEBUG 92d3d4208e0d4f34708db30d2adb953c2446588245shannon.woods@transgaming.com flags |= optimizationFlags; 9325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com#else 9425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com flags |= D3DCOMPILE_SKIP_OPTIMIZATION; 9525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com#endif 9625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 9725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com std::string sourcePath = getTempPath(); 9825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl); 9925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); 10025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 10125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com else 10225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 103d3d4208e0d4f34708db30d2adb953c2446588245shannon.woods@transgaming.com flags |= optimizationFlags; 10425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com sourceText = hlsl; 10525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 10625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 10725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. 10825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com // Try the default flags first and if compilation fails, try some alternatives. 10925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com const static UINT extraFlags[] = 11025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 11125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 0, 11225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com D3DCOMPILE_AVOID_FLOW_CONTROL, 11325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com D3DCOMPILE_PREFER_FLOW_CONTROL 11425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com }; 11525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 11625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com const static char * const extraFlagNames[] = 11725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 11825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com "default", 11925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com "avoid flow control", 12025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com "prefer flow control" 12125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com }; 12225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 123d438fd497baeddedec135e7c8bfa4148e116b9a8shannon.woods@transgaming.com int attempts = alternateFlags ? ArraySize(extraFlags) : 1; 1244e91d566b61855082158bb105d91683ba84c6ef0shannon.woods@transgaming.com pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc); 12525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com for (int i = 0; i < attempts; ++i) 12625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 12725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com ID3DBlob *errorMessage = NULL; 12825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com ID3DBlob *binary = NULL; 1294e91d566b61855082158bb105d91683ba84c6ef0shannon.woods@transgaming.com 1304e91d566b61855082158bb105d91683ba84c6ef0shannon.woods@transgaming.com result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL, 1314e91d566b61855082158bb105d91683ba84c6ef0shannon.woods@transgaming.com "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage); 13225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (errorMessage) 13325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 13425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com const char *message = (const char*)errorMessage->GetBufferPointer(); 13525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 13625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com infoLog.appendSanitized(message); 13725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com TRACE("\n%s", hlsl); 13825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com TRACE("\n%s", message); 13925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 14025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com errorMessage->Release(); 14125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com errorMessage = NULL; 14225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 14325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 14425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (SUCCEEDED(result)) 14525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 1464e91d566b61855082158bb105d91683ba84c6ef0shannon.woods@transgaming.com return (ShaderBlob*)binary; 14725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 14825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com else 14925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 15025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) 15125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 1524e91d566b61855082158bb105d91683ba84c6ef0shannon.woods@transgaming.com return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*) NULL); 15325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 15425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 15525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com infoLog.append("Warning: D3D shader compilation failed with "); 15625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com infoLog.append(extraFlagNames[i]); 15725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com infoLog.append(" flags."); 15825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com if (i + 1 < attempts) 15925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com { 16025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com infoLog.append(" Retrying with "); 16125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com infoLog.append(extraFlagNames[i + 1]); 16225e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com infoLog.append(".\n"); 16325e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 16425e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 16525e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com } 16625e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 16725e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com return NULL; 16825e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com} 16925e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 17025e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com} 17125e16afcef3dc214789acb141c959d45a1f000b9daniel@transgaming.com 172ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.comextern "C" 173ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com{ 174ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com 17586cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.orgrx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId) 176ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com{ 177c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com rx::Renderer *renderer = NULL; 178c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com EGLint status = EGL_BAD_ALLOC; 179c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 18086cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org if (ANGLE_ENABLE_D3D11 || 18186cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org displayId == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || 18286cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE) 183def9f0f35beb8606b73bab418c69f1047252e50edaniel@transgaming.com { 184c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com renderer = new rx::Renderer11(display, hDc); 185c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 186c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com if (renderer) 187c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com { 188c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com status = renderer->initialize(); 189c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com } 190c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 191c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com if (status == EGL_SUCCESS) 192c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com { 193c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com return renderer; 194c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com } 19586cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org else if (displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE) 19686cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org { 19786cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org return NULL; 19886cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org } 199c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 200c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com // Failed to create a D3D11 renderer, try creating a D3D9 renderer 201c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com delete renderer; 202def9f0f35beb8606b73bab418c69f1047252e50edaniel@transgaming.com } 203c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 20486cfba18f4da4398e0b6adea35c757eac76a3edfshannonwoods@chromium.org bool softwareDevice = (displayId == EGL_SOFTWARE_DISPLAY_ANGLE); 205c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com renderer = new rx::Renderer9(display, hDc, softwareDevice); 206c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 207c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com if (renderer) 208c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com { 209c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com status = renderer->initialize(); 210c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com } 211c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 212c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com if (status == EGL_SUCCESS) 213c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com { 214c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com return renderer; 215c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com } 216c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com 217c1e263411a97e7fac60ecb0c6681d7141742da88daniel@transgaming.com return NULL; 218ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com} 219ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com 220ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.comvoid glDestroyRenderer(rx::Renderer *renderer) 221ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com{ 222ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com delete renderer; 223ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com} 224ae4f4d4b930280d58634365d1a9206984ef30723daniel@transgaming.com 225feaaae28270686b789d4e80898b02eff108c3786Shannon Woods}