@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 4.8 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import{unpackFloatRGBA as e}from"../../core/floatRGBA.js";import has from"../../core/has.js";import{disposeMaybe as n}from"../../core/maybe.js";import{fromValues as t}from"../../core/libs/gl-matrix-2/factories/vec3f64.js";import{BufferObject as r}from"./BufferObject.js";import{encodeDoubleArray as o}from"./doublePrecisionUtils.js";import{TextureWrapMode as i,TextureSamplingMode as s,Usage as c,DataType as a,PrimitiveType as u,PixelFormat as f,PixelType as l}from"./enums.js";import{FramebufferObject as p}from"./FramebufferObject.js";import{TextureDescriptor as m}from"./TextureDescriptor.js";import{VertexArrayObject as v}from"./VertexArrayObject.js";import{VertexElementDescriptor as h}from"./VertexElementDescriptor.js";import{WebGLDriverTestModule as d}from"./WebGLDriverTestModule.js";class _ extends d{constructor(e){super(),this._rctx=e,this._program=A(this._rctx,!1),this._obfuscated=A(this._rctx,!0)}dispose(){super.dispose(),this._obfuscated=n(this._obfuscated)}_test(e){if(has("force-double-precision-obfuscation"))return!0;if(null==this._obfuscated)return!1;const n=this._rctx,t=n.getBoundFramebufferObject(),{x:r,y:o,width:i,height:s}=n.getViewport(),c=this._runProgram(e),a=this._runProgram(this._obfuscated);return n.setViewport(r,o,i,s),n.bindFramebuffer(t),0!==c&&(0===a||c/a>5)}_runProgram(n){const d=this._rctx;d.resetState();const _=new m(1);_.wrapMode=i.CLAMP_TO_EDGE,_.samplingMode=s.NEAREST;const A=new p(d,_),b=r.createVertex(d,c.STATIC_DRAW,new Uint16Array([0,0,1,0,0,1,1,1])),g=new v(d,new Map([["position",0]]),new Map([["geometry",[new h("position",2,a.UNSIGNED_SHORT,0,4)]]]),new Map([["geometry",b]])),B=t(5633261.287538229,2626832.878767164,1434988.0495278358),w=t(5633271.46742708,2626873.6381334523,1434963.231608387),F=new Float32Array(6);o(B,F,3);const O=new Float32Array(6);o(w,O,3),d.useProgram(n),n.setUniform3f("u_highA",F[0],F[2],F[4]),n.setUniform3f("u_lowA",F[1],F[3],F[5]),n.setUniform3f("u_highB",O[0],O[2],O[4]),n.setUniform3f("u_lowB",O[1],O[3],O[5]),d.bindFramebuffer(A),d.setViewport(0,0,1,1),d.bindVAO(g),d.drawArrays(u.TRIANGLE_STRIP,0,4);const E=new Uint8Array(4);A.readPixels(0,0,1,1,f.RGBA,l.UNSIGNED_BYTE,E),g.dispose(),A.dispose();const x=(B[2]-w[2])/25,I=e(E);return Math.abs(x-I)}}function A(e,n){const t=`\n\n precision highp float;\n\n attribute vec2 position;\n\n uniform vec3 u_highA;\n uniform vec3 u_lowA;\n uniform vec3 u_highB;\n uniform vec3 u_lowB;\n\n varying vec4 v_color;\n\n ${n?"#define DOUBLE_PRECISION_REQUIRES_OBFUSCATION":""}\n\n #ifdef DOUBLE_PRECISION_REQUIRES_OBFUSCATION\n\n vec3 dpPlusFrc(vec3 a, vec3 b) {\n return mix(a, a + b, vec3(notEqual(b, vec3(0))));\n }\n\n vec3 dpMinusFrc(vec3 a, vec3 b) {\n return mix(vec3(0), a - b, vec3(notEqual(a, b)));\n }\n\n vec3 dpAdd(vec3 hiA, vec3 loA, vec3 hiB, vec3 loB) {\n vec3 t1 = dpPlusFrc(hiA, hiB);\n vec3 e = dpMinusFrc(t1, hiA);\n vec3 t2 = dpMinusFrc(hiB, e) + dpMinusFrc(hiA, dpMinusFrc(t1, e)) + loA + loB;\n return t1 + t2;\n }\n\n #else\n\n vec3 dpAdd(vec3 hiA, vec3 loA, vec3 hiB, vec3 loB) {\n vec3 t1 = hiA + hiB;\n vec3 e = t1 - hiA;\n vec3 t2 = ((hiB - e) + (hiA - (t1 - e))) + loA + loB;\n return t1 + t2;\n }\n\n #endif\n\n const float MAX_RGBA_FLOAT =\n 255.0 / 256.0 +\n 255.0 / 256.0 / 256.0 +\n 255.0 / 256.0 / 256.0 / 256.0 +\n 255.0 / 256.0 / 256.0 / 256.0 / 256.0;\n\n const vec4 FIXED_POINT_FACTORS = vec4(1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0);\n\n vec4 float2rgba(const float value) {\n // Make sure value is in the domain we can represent\n float valueInValidDomain = clamp(value, 0.0, MAX_RGBA_FLOAT);\n\n // Decompose value in 32bit fixed point parts represented as\n // uint8 rgba components. Decomposition uses the fractional part after multiplying\n // by a power of 256 (this removes the bits that are represented in the previous\n // component) and then converts the fractional part to 8bits.\n vec4 fixedPointU8 = floor(fract(valueInValidDomain * FIXED_POINT_FACTORS) * 256.0);\n\n // Convert uint8 values (from 0 to 255) to floating point representation for\n // the shader\n const float toU8AsFloat = 1.0 / 255.0;\n\n return fixedPointU8 * toU8AsFloat;\n }\n\n void main() {\n vec3 val = dpAdd(u_highA, u_lowA, -u_highB, -u_lowB);\n\n v_color = float2rgba(val.z / 25.0);\n\n gl_Position = vec4(position * 2.0 - 1.0, 0.0, 1.0);\n }\n `,r="\n precision highp float;\n\n varying vec4 v_color;\n\n void main() {\n gl_FragColor = v_color;\n }\n ";return e.programCache.acquire(t,r,new Map([["position",0]]))}export{_ as DoublePrecisionRequiresObfuscation};