WebKit Roll 56306:56312.
[chromium-blink-merge.git] / o3d / import / win / collada_conditioner_win.cc
blob0d9931938e6446d57529c8332e61957b3b5ff01b
1 /*
2 * Copyright 2009, Google Inc.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // This file defines platform-specific implementations of certain
34 // methods of ColladaConditioner.
36 #include "import/cross/precompile.h"
38 #include <d3dx9effect.h>
40 #include "base/base_paths.h"
41 #include "base/file_path.h"
42 #include "base/path_service.h"
43 #include "core/cross/error.h"
44 #include "core/cross/service_locator.h"
45 #include "import/cross/collada.h"
46 #include "import/cross/collada_conditioner.h"
48 namespace o3d {
50 const int kTimeoutInSeconds = 30;
52 bool ColladaConditioner::CompileHLSL(const String& shader_source,
53 const String& vs_entry,
54 const String& ps_entry) {
55 bool retval = false;
56 String shader_source_hlsl = shader_source;
57 shader_source_hlsl +=
58 "technique t {\n"
59 " pass p {\n"
60 " VertexShader = compile vs_2_0 " + vs_entry + "();\n"
61 " PixelShader = compile ps_2_0 " + ps_entry + "();\n"
62 " }\n"
63 "};\n";
65 // Create an effect compiler from the FX file.
66 ID3DXEffectCompiler* compiler = NULL;
67 ID3DXBuffer* parse_errors = NULL;
68 HRESULT hr = ::D3DXCreateEffectCompiler(shader_source_hlsl.c_str(),
69 static_cast<UINT>(
70 shader_source_hlsl.size()),
71 NULL,
72 NULL,
74 &compiler,
75 &parse_errors);
77 if (hr != D3D_OK) {
78 const char* error_str = reinterpret_cast<const char*>(
79 parse_errors->GetBufferPointer());
80 O3D_ERROR(service_locator_) << error_str;
81 } else {
82 ID3DXBuffer* effect_buffer;
83 ID3DXBuffer* error_buffer;
84 hr = compiler->CompileEffect(0, &effect_buffer, &error_buffer);
85 if (hr != S_OK) {
86 const char* compile_errors = reinterpret_cast<const char*>(
87 error_buffer->GetBufferPointer());
88 O3D_ERROR(service_locator_) << compile_errors;
89 } else {
90 retval = true;
91 if (effect_buffer) effect_buffer->Release();
92 if (error_buffer) error_buffer->Release();
94 if (compiler) compiler->Release();
95 if (parse_errors) parse_errors->Release();
97 return retval;
100 // Find cgc executable, and run it on the input so that we can get a
101 // preprocessed version out.
102 bool ColladaConditioner::PreprocessShaderFile(const FilePath& in_filename,
103 const FilePath& out_filename) {
104 FilePath executable_path;
105 if (!PathService::Get(base::DIR_EXE, &executable_path)) {
106 O3D_ERROR(service_locator_) << "Couldn't get executable path.";
107 return false;
109 executable_path = executable_path.Append(FILE_PATH_LITERAL("cgc.exe"));
110 std::wstring cmd;
111 cmd = L"\"" + executable_path.value() + L"\" ";
112 cmd += L"-E \"" + in_filename.value() + L"\" ";
113 cmd += L"-o \"" + out_filename.value() + L"\"";
115 // Have to dup the string because CreateProcessW might modify the
116 // contents.
117 wchar_t* buf = ::_wcsdup(cmd.c_str());
119 // Initialize structure to zero with default array initializer.
120 PROCESS_INFORMATION process_info = {0};
121 // Initialize structure to it's size, followed by zeros.
122 STARTUPINFO startup_info = {sizeof(STARTUPINFO)};
124 BOOL success = ::CreateProcessW(NULL,
125 buf,
126 NULL,
127 NULL,
128 TRUE,
130 NULL,
131 NULL,
132 &startup_info,
133 &process_info);
135 if (success) {
136 success = FALSE;
137 int exit_code = ::WaitForSingleObject(process_info.hProcess,
138 kTimeoutInSeconds * 1000);
139 if (exit_code == WAIT_OBJECT_0) {
140 success = TRUE;
141 } else if (exit_code == WAIT_TIMEOUT) {
142 O3D_ERROR(service_locator_) << "Timed out waiting for cg compiler!";
143 } else {
144 O3D_ERROR(service_locator_) << "Couldn't start cg compiler (cgc.exe).";
146 } else {
147 O3D_ERROR(service_locator_) << "Couldn't start cg compiler (cgc.exe).";
149 ::CloseHandle(process_info.hProcess);
150 ::CloseHandle(process_info.hThread);
151 ::free(buf);
152 return success == TRUE;
154 } // end namespace o3d