Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 #include "precompiled.h"
2 //
3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
8 // Shader.cpp: Implements the gl::Shader class and its derived classes
9 // VertexShader and FragmentShader. Implements GL shader objects and related
10 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
12 #include "libGLESv2/Shader.h"
14 #include <algorithm>
16 #include "GLSLANG/ShaderLang.h"
17 #include "libGLESv2/utilities.h"
18 #include "libGLESv2/renderer/Renderer.h"
19 #include "libGLESv2/Constants.h"
20 #include "libGLESv2/ResourceManager.h"
22 namespace gl
23 {
24 void *Shader::mFragmentCompiler = NULL;
25 void *Shader::mVertexCompiler = NULL;
27 Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
28 : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
29 {
30 mSource = NULL;
31 mHlsl = NULL;
32 mInfoLog = NULL;
34 uncompile();
35 initializeCompiler();
37 mRefCount = 0;
38 mDeleteStatus = false;
39 }
41 Shader::~Shader()
42 {
43 delete[] mSource;
44 delete[] mHlsl;
45 delete[] mInfoLog;
46 }
48 GLuint Shader::getHandle() const
49 {
50 return mHandle;
51 }
53 void Shader::setSource(GLsizei count, const char **string, const GLint *length)
54 {
55 delete[] mSource;
56 int totalLength = 0;
58 for (int i = 0; i < count; i++)
59 {
60 if (length && length[i] >= 0)
61 {
62 totalLength += length[i];
63 }
64 else
65 {
66 totalLength += (int)strlen(string[i]);
67 }
68 }
70 mSource = new char[totalLength + 1];
71 char *code = mSource;
73 for (int i = 0; i < count; i++)
74 {
75 int stringLength;
77 if (length && length[i] >= 0)
78 {
79 stringLength = length[i];
80 }
81 else
82 {
83 stringLength = (int)strlen(string[i]);
84 }
86 strncpy(code, string[i], stringLength);
87 code += stringLength;
88 }
90 mSource[totalLength] = '\0';
91 }
93 int Shader::getInfoLogLength() const
94 {
95 if (!mInfoLog)
96 {
97 return 0;
98 }
99 else
100 {
101 return strlen(mInfoLog) + 1;
102 }
103 }
105 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
106 {
107 int index = 0;
109 if (bufSize > 0)
110 {
111 if (mInfoLog)
112 {
113 index = std::min(bufSize - 1, (int)strlen(mInfoLog));
114 memcpy(infoLog, mInfoLog, index);
115 }
117 infoLog[index] = '\0';
118 }
120 if (length)
121 {
122 *length = index;
123 }
124 }
126 int Shader::getSourceLength() const
127 {
128 if (!mSource)
129 {
130 return 0;
131 }
132 else
133 {
134 return strlen(mSource) + 1;
135 }
136 }
138 int Shader::getTranslatedSourceLength() const
139 {
140 if (!mHlsl)
141 {
142 return 0;
143 }
144 else
145 {
146 return strlen(mHlsl) + 1;
147 }
148 }
150 void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
151 {
152 int index = 0;
154 if (bufSize > 0)
155 {
156 if (source)
157 {
158 index = std::min(bufSize - 1, (int)strlen(source));
159 memcpy(buffer, source, index);
160 }
162 buffer[index] = '\0';
163 }
165 if (length)
166 {
167 *length = index;
168 }
169 }
171 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
172 {
173 getSourceImpl(mSource, bufSize, length, buffer);
174 }
176 void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
177 {
178 getSourceImpl(mHlsl, bufSize, length, buffer);
179 }
181 const sh::ActiveUniforms &Shader::getUniforms()
182 {
183 return mActiveUniforms;
184 }
186 bool Shader::isCompiled()
187 {
188 return mHlsl != NULL;
189 }
191 const char *Shader::getHLSL()
192 {
193 return mHlsl;
194 }
196 void Shader::addRef()
197 {
198 mRefCount++;
199 }
201 void Shader::release()
202 {
203 mRefCount--;
205 if (mRefCount == 0 && mDeleteStatus)
206 {
207 mResourceManager->deleteShader(mHandle);
208 }
209 }
211 unsigned int Shader::getRefCount() const
212 {
213 return mRefCount;
214 }
216 bool Shader::isFlaggedForDeletion() const
217 {
218 return mDeleteStatus;
219 }
221 void Shader::flagForDeletion()
222 {
223 mDeleteStatus = true;
224 }
226 // Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
227 void Shader::initializeCompiler()
228 {
229 if (!mFragmentCompiler)
230 {
231 int result = ShInitialize();
233 if (result)
234 {
235 ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
237 ShBuiltInResources resources;
238 ShInitBuiltInResources(&resources);
240 resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
241 resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
242 resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
243 resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
244 resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
245 resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
246 resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
247 resources.MaxDrawBuffers = mRenderer->getMaxRenderTargets();
248 resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport();
249 resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1;
250 // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
251 resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
252 resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
254 mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
255 mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
256 }
257 }
258 }
260 void Shader::releaseCompiler()
261 {
262 ShDestruct(mFragmentCompiler);
263 ShDestruct(mVertexCompiler);
265 mFragmentCompiler = NULL;
266 mVertexCompiler = NULL;
268 ShFinalize();
269 }
271 void Shader::parseVaryings()
272 {
273 if (mHlsl)
274 {
275 const char *input = strstr(mHlsl, "// Varyings") + 12;
277 while(true)
278 {
279 char varyingType[256];
280 char varyingName[256];
282 int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
284 if (matches != 2)
285 {
286 break;
287 }
289 char *array = strstr(varyingName, "[");
290 int size = 1;
292 if (array)
293 {
294 size = atoi(array + 1);
295 *array = '\0';
296 }
298 mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
300 input = strstr(input, ";") + 2;
301 }
303 mUsesMultipleRenderTargets = strstr(mHlsl, "GL_USES_MRT") != NULL;
304 mUsesFragColor = strstr(mHlsl, "GL_USES_FRAG_COLOR") != NULL;
305 mUsesFragData = strstr(mHlsl, "GL_USES_FRAG_DATA") != NULL;
306 mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
307 mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
308 mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
309 mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
310 mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL;
311 mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL;
312 }
313 }
315 void Shader::resetVaryingsRegisterAssignment()
316 {
317 for (VaryingList::iterator var = mVaryings.begin(); var != mVaryings.end(); var++)
318 {
319 var->reg = -1;
320 var->col = -1;
321 }
322 }
324 // initialize/clean up previous state
325 void Shader::uncompile()
326 {
327 // set by compileToHLSL
328 delete[] mHlsl;
329 mHlsl = NULL;
330 delete[] mInfoLog;
331 mInfoLog = NULL;
333 // set by parseVaryings
334 mVaryings.clear();
336 mUsesMultipleRenderTargets = false;
337 mUsesFragColor = false;
338 mUsesFragData = false;
339 mUsesFragCoord = false;
340 mUsesFrontFacing = false;
341 mUsesPointSize = false;
342 mUsesPointCoord = false;
343 mUsesDepthRange = false;
344 mUsesFragDepth = false;
346 mActiveUniforms.clear();
347 }
349 void Shader::compileToHLSL(void *compiler)
350 {
351 // ensure we don't pass a NULL source to the compiler
352 const char *source = "\0";
353 if (mSource)
354 {
355 source = mSource;
356 }
358 // ensure the compiler is loaded
359 initializeCompiler();
361 int compileOptions = SH_OBJECT_CODE;
362 std::string sourcePath;
363 if (perfActive())
364 {
365 sourcePath = getTempPath();
366 writeFile(sourcePath.c_str(), source, strlen(source));
367 compileOptions |= SH_LINE_DIRECTIVES;
368 }
370 int result;
371 if (sourcePath.empty())
372 {
373 result = ShCompile(compiler, &source, 1, compileOptions);
374 }
375 else
376 {
377 const char* sourceStrings[2] =
378 {
379 sourcePath.c_str(),
380 source
381 };
383 result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
384 }
386 if (result)
387 {
388 size_t objCodeLen = 0;
389 ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
390 mHlsl = new char[objCodeLen];
391 ShGetObjectCode(compiler, mHlsl);
393 void *activeUniforms;
394 ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
395 mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms;
396 }
397 else
398 {
399 size_t infoLogLen = 0;
400 ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
401 mInfoLog = new char[infoLogLen];
402 ShGetInfoLog(compiler, mInfoLog);
404 TRACE("\n%s", mInfoLog);
405 }
406 }
408 GLenum Shader::parseType(const std::string &type)
409 {
410 if (type == "float")
411 {
412 return GL_FLOAT;
413 }
414 else if (type == "float2")
415 {
416 return GL_FLOAT_VEC2;
417 }
418 else if (type == "float3")
419 {
420 return GL_FLOAT_VEC3;
421 }
422 else if (type == "float4")
423 {
424 return GL_FLOAT_VEC4;
425 }
426 else if (type == "float2x2")
427 {
428 return GL_FLOAT_MAT2;
429 }
430 else if (type == "float3x3")
431 {
432 return GL_FLOAT_MAT3;
433 }
434 else if (type == "float4x4")
435 {
436 return GL_FLOAT_MAT4;
437 }
438 else UNREACHABLE();
440 return GL_NONE;
441 }
443 // true if varying x has a higher priority in packing than y
444 bool Shader::compareVarying(const Varying &x, const Varying &y)
445 {
446 if(x.type == y.type)
447 {
448 return x.size > y.size;
449 }
451 switch (x.type)
452 {
453 case GL_FLOAT_MAT4: return true;
454 case GL_FLOAT_MAT2:
455 switch(y.type)
456 {
457 case GL_FLOAT_MAT4: return false;
458 case GL_FLOAT_MAT2: return true;
459 case GL_FLOAT_VEC4: return true;
460 case GL_FLOAT_MAT3: return true;
461 case GL_FLOAT_VEC3: return true;
462 case GL_FLOAT_VEC2: return true;
463 case GL_FLOAT: return true;
464 default: UNREACHABLE();
465 }
466 break;
467 case GL_FLOAT_VEC4:
468 switch(y.type)
469 {
470 case GL_FLOAT_MAT4: return false;
471 case GL_FLOAT_MAT2: return false;
472 case GL_FLOAT_VEC4: return true;
473 case GL_FLOAT_MAT3: return true;
474 case GL_FLOAT_VEC3: return true;
475 case GL_FLOAT_VEC2: return true;
476 case GL_FLOAT: return true;
477 default: UNREACHABLE();
478 }
479 break;
480 case GL_FLOAT_MAT3:
481 switch(y.type)
482 {
483 case GL_FLOAT_MAT4: return false;
484 case GL_FLOAT_MAT2: return false;
485 case GL_FLOAT_VEC4: return false;
486 case GL_FLOAT_MAT3: return true;
487 case GL_FLOAT_VEC3: return true;
488 case GL_FLOAT_VEC2: return true;
489 case GL_FLOAT: return true;
490 default: UNREACHABLE();
491 }
492 break;
493 case GL_FLOAT_VEC3:
494 switch(y.type)
495 {
496 case GL_FLOAT_MAT4: return false;
497 case GL_FLOAT_MAT2: return false;
498 case GL_FLOAT_VEC4: return false;
499 case GL_FLOAT_MAT3: return false;
500 case GL_FLOAT_VEC3: return true;
501 case GL_FLOAT_VEC2: return true;
502 case GL_FLOAT: return true;
503 default: UNREACHABLE();
504 }
505 break;
506 case GL_FLOAT_VEC2:
507 switch(y.type)
508 {
509 case GL_FLOAT_MAT4: return false;
510 case GL_FLOAT_MAT2: return false;
511 case GL_FLOAT_VEC4: return false;
512 case GL_FLOAT_MAT3: return false;
513 case GL_FLOAT_VEC3: return false;
514 case GL_FLOAT_VEC2: return true;
515 case GL_FLOAT: return true;
516 default: UNREACHABLE();
517 }
518 break;
519 case GL_FLOAT: return false;
520 default: UNREACHABLE();
521 }
523 return false;
524 }
526 VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
527 : Shader(manager, renderer, handle)
528 {
529 }
531 VertexShader::~VertexShader()
532 {
533 }
535 GLenum VertexShader::getType()
536 {
537 return GL_VERTEX_SHADER;
538 }
540 void VertexShader::uncompile()
541 {
542 Shader::uncompile();
544 // set by ParseAttributes
545 mAttributes.clear();
546 }
548 void VertexShader::compile()
549 {
550 uncompile();
552 compileToHLSL(mVertexCompiler);
553 parseAttributes();
554 parseVaryings();
555 }
557 int VertexShader::getSemanticIndex(const std::string &attributeName)
558 {
559 if (!attributeName.empty())
560 {
561 int semanticIndex = 0;
562 for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
563 {
564 if (attribute->name == attributeName)
565 {
566 return semanticIndex;
567 }
569 semanticIndex += VariableRowCount(attribute->type);
570 }
571 }
573 return -1;
574 }
576 void VertexShader::parseAttributes()
577 {
578 const char *hlsl = getHLSL();
579 if (hlsl)
580 {
581 const char *input = strstr(hlsl, "// Attributes") + 14;
583 while(true)
584 {
585 char attributeType[256];
586 char attributeName[256];
588 int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
590 if (matches != 2)
591 {
592 break;
593 }
595 mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
597 input = strstr(input, ";") + 2;
598 }
599 }
600 }
602 FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
603 : Shader(manager, renderer, handle)
604 {
605 }
607 FragmentShader::~FragmentShader()
608 {
609 }
611 GLenum FragmentShader::getType()
612 {
613 return GL_FRAGMENT_SHADER;
614 }
616 void FragmentShader::compile()
617 {
618 uncompile();
620 compileToHLSL(mFragmentCompiler);
621 parseVaryings();
622 mVaryings.sort(compareVarying);
623 }
624 }