Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

uber / deck.gl / 13873

19 Sep 2019 - 20:02 coverage increased (+2.8%) to 82.702%
13873

Pull #3639

travis-ci-com

9181eb84f9c35729a3bad740fb7f9d93?size=18&default=identiconweb-flow
Update
Pull Request #3639: Set default pydeck notebook width to 700px

3398 of 4611 branches covered (73.69%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

488 existing lines in 85 files now uncovered.

7192 of 8194 relevant lines covered (87.77%)

4273.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

36.36
/modules/core/src/transitions/gpu-spring-transition.js
1
/* eslint-disable complexity, max-statements, max-params */
2
import GL from '@luma.gl/constants';
3
import {Buffer, Transform, Framebuffer, Texture2D, readPixelsToArray} from '@luma.gl/core';
4
import {
5
  padBuffer,
6
  getAttributeTypeFromSize,
7
  getSourceBufferAttribute,
8
  getAttributeBufferLength,
9
  cycleBuffers
10
} from '../lib/attribute-transition-utils';
11
import Attribute from '../lib/attribute';
12
import Transition from './transition';
13

14
export default class GPUSpringTransition {
15
  constructor({gl, attribute, timeline}) {
16
    this.gl = gl;
1×
17
    this.type = 'spring';
7×
18
    this.transition = new Transition(timeline);
1×
19
    this._isTransitioning = false;
1×
20
    this.attribute = attribute;
1×
21
    // this is the attribute we return during the transition - note: if it is a constant
22
    // attribute, it will be converted and returned as a regular attribute
23
    // `attribute.userData` is the original options passed when constructing the attribute.
24
    // This ensures that we set the proper `doublePrecision` flag and shader attributes.
25
    this.attributeInTransition = new Attribute(gl, attribute.userData);
1×
26
    this.currentBufferLayout = attribute.bufferLayout;
1×
27
    // storing currentLength because this.buffer may be larger than the actual length we want to use
28
    // this is because we only reallocate buffers when they grow, not when they shrink,
29
    // due to performance costs
30
    this.currentLength = 0;
1×
31
    this.transform = null;
1×
32
    this.texture = getTexture(gl);
1×
33
    this.framebuffer = getFramebuffer(gl, this.texture);
1×
34
    const usage = GL.DYNAMIC_COPY;
1×
35
    const byteLength = 0;
1×
36
    this.buffers = [
1×
37
      new Buffer(gl, {byteLength, usage}), // previous
38
      new Buffer(gl, {byteLength, usage}), // current
39
      new Buffer(gl, {byteLength, usage}) // next
40
    ];
41
  }
42

43
  isTransitioning() {
44
    return this._isTransitioning;
1×
45
  }
46

47
  // this will never return a constant attribute, no matter what attribute was passed in
48
  getTransitioningAttribute() {
49
    return this.attributeInTransition;
1×
50
  }
51

52
  // this is called when an attribute's values have changed and
53
  // we need to start animating towards the new values
54
  // this also correctly resizes / pads the transform's buffers
55
  // in case the attribute's buffer has changed in length or in
56
  // bufferLayout
57
  start(transitionSettings, numInstances) {
58
    const padBufferOpts = {
1×
59
      numInstances,
60
      attribute: this.attribute,
61
      fromLength: this.currentLength,
62
      fromBufferLayout: this.currentBufferLayout,
63
      getData: transitionSettings.enter
64
    };
65

66
    for (const buffer of this.buffers) {
1×
67
      padBuffer({buffer, ...padBufferOpts});
1×
68
    }
69

70
    this.currentBufferLayout = this.attribute.bufferLayout;
1×
71
    this.currentLength = getAttributeBufferLength(this.attribute, numInstances);
!
UNCOV
72
    this.attributeInTransition.update({
!
73
      buffer: this.buffers[1],
74
      // Hack: Float64Array is required for double-precision attributes
75
      // to generate correct shader attributes
76
      value: this.attribute.value
77
    });
78

79
    // when an attribute changes values, a new transition is started. These
80
    // are properties that we have to store on this.transition but can change
81
    // when new transitions are started, so we have to keep them up-to-date.
82
    // this.transition.start() takes the latest settings and updates them.
83
    this.transition.start(transitionSettings);
!
84

UNCOV
85
    this.transform = this.transform || getTransform(this.gl, this.attribute, this.framebuffer);
Branches [[0, 0], [0, 1]] missed. !
UNCOV
86
    this.transform.update({
!
87
      elementCount: Math.floor(this.currentLength / this.attribute.size),
88
      sourceBuffers: {
89
        aTo: getSourceBufferAttribute(this.gl, this.attribute)
90
      }
91
    });
UNCOV
92
    this._isTransitioning = true;
!
93
  }
94

95
  update() {
UNCOV
96
    const updated = this.transition.update();
!
UNCOV
97
    if (!updated) {
Branches [[1, 0], [1, 1]] missed. !
UNCOV
98
      return false;
!
99
    }
100

UNCOV
101
    this.transform.update({
!
102
      sourceBuffers: {
103
        aPrev: this.buffers[0],
104
        aCur: this.buffers[1]
105
      },
106
      feedbackBuffers: {
107
        vNext: this.buffers[2]
108
      }
109
    });
UNCOV
110
    this.transform.run({
!
111
      framebuffer: this.framebuffer,
112
      discard: false,
113
      clearRenderTarget: true,
114
      uniforms: {
115
        stiffness: this.transition.settings.stiffness,
116
        damping: this.transition.settings.damping
117
      },
118
      parameters: {
119
        depthTest: false,
120
        blend: true,
121
        viewport: [0, 0, 1, 1],
122
        blendFunc: [GL.ONE, GL.ONE],
123
        blendEquation: [GL.MAX, GL.MAX]
124
      }
125
    });
126

127
    cycleBuffers(this.buffers);
!
128
    this.attributeInTransition.update({buffer: this.buffers[1]});
!
129

UNCOV
130
    this._isTransitioning = readPixelsToArray(this.framebuffer)[0] > 0;
!
131

UNCOV
132
    if (!this.isTransitioning()) {
Branches [[2, 0], [2, 1]] missed. !
UNCOV
133
      this.transition.end();
!
134
    }
135

UNCOV
136
    return true;
!
137
  }
138

139
  cancel() {
UNCOV
140
    this.transition.cancel();
!
UNCOV
141
    this.transform.delete();
!
UNCOV
142
    while (this.buffers.length) {
!
UNCOV
143
      this.buffers.pop().delete();
!
144
    }
UNCOV
145
    this.texture.delete();
!
UNCOV
146
    this.texture = null;
!
UNCOV
147
    this.framebuffer.delete();
!
UNCOV
148
    this.framebuffer = null;
!
149
  }
150
}
151

152
function getTransform(gl, attribute, framebuffer) {
UNCOV
153
  const attributeType = getAttributeTypeFromSize(attribute.size);
!
UNCOV
154
  return new Transform(gl, {
!
155
    framebuffer,
156
    vs: `
157
#define SHADER_NAME spring-transition-vertex-shader
158

159
#define EPSILON 0.00001
160

161
uniform float stiffness;
162
uniform float damping;
163
attribute ATTRIBUTE_TYPE aPrev;
164
attribute ATTRIBUTE_TYPE aCur;
165
attribute ATTRIBUTE_TYPE aTo;
166
varying ATTRIBUTE_TYPE vNext;
167
varying float vIsTransitioningFlag;
168

169
ATTRIBUTE_TYPE getNextValue(ATTRIBUTE_TYPE cur, ATTRIBUTE_TYPE prev, ATTRIBUTE_TYPE dest) {
170
  ATTRIBUTE_TYPE velocity = cur - prev;
171
  ATTRIBUTE_TYPE delta = dest - cur;
172
  ATTRIBUTE_TYPE spring = delta * stiffness;
173
  ATTRIBUTE_TYPE damper = velocity * -1.0 * damping;
174
  return spring + damper + velocity + cur;
175
}
176

177
void main(void) {
178
  bool isTransitioning = length(aCur - aPrev) > EPSILON || length(aTo - aCur) > EPSILON;
179
  vIsTransitioningFlag = isTransitioning ? 1.0 : 0.0;
180

181
  vNext = getNextValue(aCur, aPrev, aTo);
182
  gl_Position = vec4(0, 0, 0, 1);
183
  gl_PointSize = 100.0;
184
}
185
`,
186
    fs: `
187
#define SHADER_NAME spring-transition-is-transitioning-fragment-shader
188

189
varying float vIsTransitioningFlag;
190

191
void main(void) {
192
  if (vIsTransitioningFlag == 0.0) {
193
    discard;
194
  }
195
  gl_FragColor = vec4(1.0);
196
}`,
197
    defines: {
198
      ATTRIBUTE_TYPE: attributeType
199
    },
200
    varyings: ['vNext']
201
  });
202
}
203

204
function getTexture(gl) {
UNCOV
205
  return new Texture2D(gl, {
!
206
    data: new Uint8Array(4),
207
    format: GL.RGBA,
208
    type: GL.UNSIGNED_BYTE,
209
    border: 0,
210
    mipmaps: false,
211
    dataFormat: GL.RGBA,
212
    width: 1,
213
    height: 1
214
  });
215
}
216

217
function getFramebuffer(gl, texture) {
UNCOV
218
  return new Framebuffer(gl, {
!
219
    id: 'spring-transition-is-transitioning-framebuffer',
220
    width: 1,
221
    height: 1,
222
    attachments: {
223
      [GL.COLOR_ATTACHMENT0]: texture
224
    }
225
  });
226
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2019 Coveralls, LLC