From f12cc6cdea1df7b716a9eb11fa9ce2e60c5424ed Mon Sep 17 00:00:00 2001 From: Karim Naaji Date: Thu, 27 Feb 2020 18:07:48 -0500 Subject: [PATCH] Adjust *-pattern images based on their asset pixel ratio In most cases the pixel ratio from and pixel ratio to should be the same, for completeness and to cover cases where some assets are transitionning between different @xx, we reference them separately. Fix for issue https://github.com/mapbox/mapbox-gl-js/issues/8020 --- src/data/array_types.js | 22 +++++----- src/data/bucket/pattern_attributes.js | 4 +- src/data/program_configuration.js | 40 +++++++++++++------ .../fill_extrusion_pattern.fragment.glsl | 4 ++ .../fill_extrusion_pattern.vertex.glsl | 8 +++- .../fill_outline_pattern.fragment.glsl | 2 +- src/shaders/fill_outline_pattern.vertex.glsl | 8 +++- src/shaders/fill_pattern.vertex.glsl | 8 +++- src/shaders/line_pattern.fragment.glsl | 8 +++- src/shaders/line_pattern.vertex.glsl | 4 ++ 10 files changed, 76 insertions(+), 32 deletions(-) diff --git a/src/data/array_types.js b/src/data/array_types.js index 5f703cce3a1..963af829a6d 100644 --- a/src/data/array_types.js +++ b/src/data/array_types.js @@ -150,10 +150,11 @@ register('StructArrayLayout2i4ub8', StructArrayLayout2i4ub8); /** * Implementation of the StructArray layout: * [0]: Uint16[8] + * [16]: Uint8[2] * * @private */ -class StructArrayLayout8ui16 extends StructArray { +class StructArrayLayout8ui2ub18 extends StructArray { uint8: Uint8Array; uint16: Uint16Array; @@ -162,14 +163,15 @@ class StructArrayLayout8ui16 extends StructArray { this.uint16 = new Uint16Array(this.arrayBuffer); } - emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number) { + emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number) { const i = this.length; this.resize(i + 1); - return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7); + return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); } - emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number) { - const o2 = i * 8; + emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number, v8: number, v9: number) { + const o2 = i * 9; + const o1 = i * 18; this.uint16[o2 + 0] = v0; this.uint16[o2 + 1] = v1; this.uint16[o2 + 2] = v2; @@ -178,12 +180,14 @@ class StructArrayLayout8ui16 extends StructArray { this.uint16[o2 + 5] = v5; this.uint16[o2 + 6] = v6; this.uint16[o2 + 7] = v7; + this.uint8[o1 + 16] = v8; + this.uint8[o1 + 17] = v9; return i; } } -StructArrayLayout8ui16.prototype.bytesPerElement = 16; -register('StructArrayLayout8ui16', StructArrayLayout8ui16); +StructArrayLayout8ui2ub18.prototype.bytesPerElement = 18; +register('StructArrayLayout8ui2ub18', StructArrayLayout8ui2ub18); /** * Implementation of the StructArray layout: @@ -1153,7 +1157,7 @@ export { StructArrayLayout4i8, StructArrayLayout2i4i12, StructArrayLayout2i4ub8, - StructArrayLayout8ui16, + StructArrayLayout8ui2ub18, StructArrayLayout4i4ui4i24, StructArrayLayout3f12, StructArrayLayout1ul4, @@ -1177,7 +1181,7 @@ export { StructArrayLayout2i4i12 as FillExtrusionLayoutArray, StructArrayLayout2i4 as HeatmapLayoutArray, StructArrayLayout2i4ub8 as LineLayoutArray, - StructArrayLayout8ui16 as PatternLayoutArray, + StructArrayLayout8ui2ub18 as PatternLayoutArray, StructArrayLayout4i4ui4i24 as SymbolLayoutArray, StructArrayLayout3f12 as SymbolDynamicLayoutArray, StructArrayLayout1ul4 as SymbolOpacityArray, diff --git a/src/data/bucket/pattern_attributes.js b/src/data/bucket/pattern_attributes.js index a46d42cc057..f47b64ca115 100644 --- a/src/data/bucket/pattern_attributes.js +++ b/src/data/bucket/pattern_attributes.js @@ -4,5 +4,7 @@ import {createLayout} from '../../util/struct_array'; export default createLayout([ // [tl.x, tl.y, br.x, br.y] {name: 'a_pattern_from', components: 4, type: 'Uint16'}, - {name: 'a_pattern_to', components: 4, type: 'Uint16'} + {name: 'a_pattern_to', components: 4, type: 'Uint16'}, + {name: 'a_pixel_ratio_from', components: 1, type: 'Uint8'}, + {name: 'a_pixel_ratio_to', components: 1, type: 'Uint8'}, ]); diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index 22e9cba0d3f..2a5320486d3 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -86,7 +86,7 @@ interface AttributeBinder { interface UniformBinder { uniformNames: Array; setUniform(uniform: Uniform<*>, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue<*>, uniformName: string): void; - getBinding(context: Context, location: WebGLUniformLocation): $Shape>; + getBinding(context: Context, location: WebGLUniformLocation, name: string): $Shape>; } class ConstantBinder implements UniformBinder { @@ -104,7 +104,7 @@ class ConstantBinder implements UniformBinder { uniform.set(currentValue.constantOr(this.value)); } - getBinding(context: Context, location: WebGLUniformLocation): $Shape> { + getBinding(context: Context, location: WebGLUniformLocation, name: string): $Shape> { return (this.type === 'color') ? new UniformColor(context, location) : new Uniform1f(context, location); @@ -115,27 +115,37 @@ class CrossFadedConstantBinder implements UniformBinder { uniformNames: Array; patternFrom: ?Array; patternTo: ?Array; + pixelRatioFrom: number; + pixelRatioTo: number; constructor(value: mixed, names: Array) { this.uniformNames = names.map(name => `u_${name}`); this.patternFrom = null; this.patternTo = null; + this.pixelRatioFrom = 1.0; + this.pixelRatioTo = 1.0; } setConstantPatternPositions(posTo: ImagePosition, posFrom: ImagePosition) { - this.patternTo = posTo.tlbr; + this.pixelRatioFrom = [posFrom.pixelRatio]; + this.pixelRatioTo = [posTo.pixelRatio]; this.patternFrom = posFrom.tlbr; + this.patternTo = posTo.tlbr; } setUniform(uniform: Uniform<*>, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue, uniformName: string) { const pos = uniformName === 'u_pattern_to' ? this.patternTo : - uniformName === 'u_pattern_from' ? this.patternFrom : null; + uniformName === 'u_pattern_from' ? this.patternFrom : + uniformName === 'u_pixel_ratio_to' ? this.pixelRatioTo : + uniformName === 'u_pixel_ratio_from' ? this.pixelRatioFrom : null; if (pos) uniform.set(pos); } - getBinding(context: Context, location: WebGLUniformLocation): $Shape> { - return new Uniform4f(context, location); + getBinding(context: Context, location: WebGLUniformLocation, name: string): $Shape> { + return name.startsWith('u_pattern') ? + new Uniform4f(context, location) : + new Uniform1f(context, location); } } @@ -283,7 +293,7 @@ class CompositeExpressionBinder implements AttributeBinder, UniformBinder { uniform.set(factor); } - getBinding(context: Context, location: WebGLUniformLocation): Uniform1f { + getBinding(context: Context, location: WebGLUniformLocation, name: string): Uniform1f { return new Uniform1f(context, location); } } @@ -345,11 +355,15 @@ class CrossFadedCompositeBinder implements AttributeBinder { for (let i = start; i < end; i++) { this.zoomInPaintVertexArray.emplace(i, imageMid.tl[0], imageMid.tl[1], imageMid.br[0], imageMid.br[1], - imageMin.tl[0], imageMin.tl[1], imageMin.br[0], imageMin.br[1] + imageMin.tl[0], imageMin.tl[1], imageMin.br[0], imageMin.br[1], + imageMid.pixelRatio, + imageMin.pixelRatio, ); this.zoomOutPaintVertexArray.emplace(i, imageMid.tl[0], imageMid.tl[1], imageMid.br[0], imageMid.br[1], - imageMax.tl[0], imageMax.tl[1], imageMax.br[0], imageMax.br[1] + imageMax.tl[0], imageMax.tl[1], imageMax.br[0], imageMax.br[1], + imageMid.pixelRatio, + imageMax.pixelRatio, ); } } @@ -503,7 +517,7 @@ export default class ProgramConfiguration { if (binder instanceof ConstantBinder || binder instanceof CrossFadedConstantBinder || binder instanceof CompositeExpressionBinder) { for (const name of binder.uniformNames) { if (locations[name]) { - const binding = binder.getBinding(context, locations[name]); + const binding = binder.getBinding(context, locations[name], name); uniforms.push({name, property, binding}); } } @@ -620,9 +634,9 @@ function paintAttributeNames(property, type) { 'text-halo-width': ['halo_width'], 'icon-halo-width': ['halo_width'], 'line-gap-width': ['gapwidth'], - 'line-pattern': ['pattern_to', 'pattern_from'], - 'fill-pattern': ['pattern_to', 'pattern_from'], - 'fill-extrusion-pattern': ['pattern_to', 'pattern_from'], + 'line-pattern': ['pattern_to', 'pattern_from', 'pixel_ratio_to', 'pixel_ratio_from'], + 'fill-pattern': ['pattern_to', 'pattern_from', 'pixel_ratio_to', 'pixel_ratio_from'], + 'fill-extrusion-pattern': ['pattern_to', 'pattern_from', 'pixel_ratio_to', 'pixel_ratio_from'], }; return attributeNameExceptions[property] || [property.replace(`${type}-`, '').replace(/-/g, '_')]; diff --git a/src/shaders/fill_extrusion_pattern.fragment.glsl b/src/shaders/fill_extrusion_pattern.fragment.glsl index f3243d74b71..1edd25eac45 100644 --- a/src/shaders/fill_extrusion_pattern.fragment.glsl +++ b/src/shaders/fill_extrusion_pattern.fragment.glsl @@ -11,12 +11,16 @@ varying vec4 v_lighting; #pragma mapbox: define lowp float height #pragma mapbox: define lowp vec4 pattern_from #pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to void main() { #pragma mapbox: initialize lowp float base #pragma mapbox: initialize lowp float height #pragma mapbox: initialize mediump vec4 pattern_from #pragma mapbox: initialize mediump vec4 pattern_to + #pragma mapbox: initialize lowp float pixel_ratio_from + #pragma mapbox: initialize lowp float pixel_ratio_to vec2 pattern_tl_a = pattern_from.xy; vec2 pattern_br_a = pattern_from.zw; diff --git a/src/shaders/fill_extrusion_pattern.vertex.glsl b/src/shaders/fill_extrusion_pattern.vertex.glsl index 2761d56b6a9..a14b9ebdf44 100644 --- a/src/shaders/fill_extrusion_pattern.vertex.glsl +++ b/src/shaders/fill_extrusion_pattern.vertex.glsl @@ -21,12 +21,16 @@ varying vec4 v_lighting; #pragma mapbox: define lowp float height #pragma mapbox: define lowp vec4 pattern_from #pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to void main() { #pragma mapbox: initialize lowp float base #pragma mapbox: initialize lowp float height #pragma mapbox: initialize mediump vec4 pattern_from #pragma mapbox: initialize mediump vec4 pattern_to + #pragma mapbox: initialize lowp float pixel_ratio_from + #pragma mapbox: initialize lowp float pixel_ratio_to vec2 pattern_tl_a = pattern_from.xy; vec2 pattern_br_a = pattern_from.zw; @@ -41,8 +45,8 @@ void main() { vec3 normal = a_normal_ed.xyz; float edgedistance = a_normal_ed.w; - vec2 display_size_a = vec2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio); - vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio); + vec2 display_size_a = (pattern_br_a - (pattern_tl_a) / (pixelRatio * pixel_ratio_from); + vec2 display_size_b = (pattern_br_b - (pattern_tl_b) / (pixelRatio * pixel_ratio_to); base = max(0.0, base); height = max(0.0, height); diff --git a/src/shaders/fill_outline_pattern.fragment.glsl b/src/shaders/fill_outline_pattern.fragment.glsl index 8d75cbbfe4d..64813c2757c 100644 --- a/src/shaders/fill_outline_pattern.fragment.glsl +++ b/src/shaders/fill_outline_pattern.fragment.glsl @@ -40,4 +40,4 @@ void main() { #ifdef OVERDRAW_INSPECTOR gl_FragColor = vec4(1.0); #endif -} +} \ No newline at end of file diff --git a/src/shaders/fill_outline_pattern.vertex.glsl b/src/shaders/fill_outline_pattern.vertex.glsl index ac5ed0c423f..b215fa8d087 100644 --- a/src/shaders/fill_outline_pattern.vertex.glsl +++ b/src/shaders/fill_outline_pattern.vertex.glsl @@ -13,11 +13,15 @@ varying vec2 v_pos; #pragma mapbox: define lowp float opacity #pragma mapbox: define lowp vec4 pattern_from #pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to void main() { #pragma mapbox: initialize lowp float opacity #pragma mapbox: initialize mediump vec4 pattern_from #pragma mapbox: initialize mediump vec4 pattern_to + #pragma mapbox: initialize lowp float pixel_ratio_from + #pragma mapbox: initialize lowp float pixel_ratio_to vec2 pattern_tl_a = pattern_from.xy; vec2 pattern_br_a = pattern_from.zw; @@ -31,8 +35,8 @@ void main() { gl_Position = u_matrix * vec4(a_pos, 0, 1); - vec2 display_size_a = vec2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio); - vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio); + vec2 display_size_a = (pattern_br_a - (pattern_tl_a) / (pixelRatio * pixel_ratio_from); + vec2 display_size_b = (pattern_br_b - (pattern_tl_b) / (pixelRatio * pixel_ratio_to); v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, fromScale * display_size_a, tileRatio, a_pos); v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, toScale * display_size_b, tileRatio, a_pos); diff --git a/src/shaders/fill_pattern.vertex.glsl b/src/shaders/fill_pattern.vertex.glsl index a3be3320186..8a25314d1bb 100644 --- a/src/shaders/fill_pattern.vertex.glsl +++ b/src/shaders/fill_pattern.vertex.glsl @@ -11,11 +11,15 @@ varying vec2 v_pos_b; #pragma mapbox: define lowp float opacity #pragma mapbox: define lowp vec4 pattern_from #pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to void main() { #pragma mapbox: initialize lowp float opacity #pragma mapbox: initialize mediump vec4 pattern_from #pragma mapbox: initialize mediump vec4 pattern_to + #pragma mapbox: initialize lowp float pixel_ratio_from + #pragma mapbox: initialize lowp float pixel_ratio_to vec2 pattern_tl_a = pattern_from.xy; vec2 pattern_br_a = pattern_from.zw; @@ -27,8 +31,8 @@ void main() { float fromScale = u_scale.z; float toScale = u_scale.w; - vec2 display_size_a = vec2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio); - vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio); + vec2 display_size_a = (pattern_br_a - pattern_tl_a) / (pixelRatio * pixel_ratio_from); + vec2 display_size_b = (pattern_br_b - pattern_tl_b) / (pixelRatio * pixel_ratio_to); gl_Position = u_matrix * vec4(a_pos, 0, 1); v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, fromScale * display_size_a, tileZoomRatio, a_pos); diff --git a/src/shaders/line_pattern.fragment.glsl b/src/shaders/line_pattern.fragment.glsl index e18de38320e..262c9e1963b 100644 --- a/src/shaders/line_pattern.fragment.glsl +++ b/src/shaders/line_pattern.fragment.glsl @@ -12,12 +12,16 @@ varying float v_gamma_scale; #pragma mapbox: define lowp vec4 pattern_from #pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to #pragma mapbox: define lowp float blur #pragma mapbox: define lowp float opacity void main() { #pragma mapbox: initialize mediump vec4 pattern_from #pragma mapbox: initialize mediump vec4 pattern_to + #pragma mapbox: initialize lowp float pixel_ratio_from + #pragma mapbox: initialize lowp float pixel_ratio_to #pragma mapbox: initialize lowp float blur #pragma mapbox: initialize lowp float opacity @@ -32,8 +36,8 @@ void main() { float fromScale = u_scale.z; float toScale = u_scale.w; - vec2 display_size_a = vec2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio); - vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio); + vec2 display_size_a = (pattern_br_a - pattern_tl_a) / (pixelRatio * pixel_ratio_from); + vec2 display_size_b = (pattern_br_b - pattern_tl_b) / (pixelRatio * pixel_ratio_to); vec2 pattern_size_a = vec2(display_size_a.x * fromScale / tileZoomRatio, display_size_a.y); vec2 pattern_size_b = vec2(display_size_b.x * toScale / tileZoomRatio, display_size_b.y); diff --git a/src/shaders/line_pattern.vertex.glsl b/src/shaders/line_pattern.vertex.glsl index 6b4eb54c87a..73f01dd8ac4 100644 --- a/src/shaders/line_pattern.vertex.glsl +++ b/src/shaders/line_pattern.vertex.glsl @@ -30,6 +30,8 @@ varying float v_gamma_scale; #pragma mapbox: define mediump float width #pragma mapbox: define lowp vec4 pattern_from #pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to void main() { #pragma mapbox: initialize lowp float blur @@ -39,6 +41,8 @@ void main() { #pragma mapbox: initialize mediump float width #pragma mapbox: initialize mediump vec4 pattern_from #pragma mapbox: initialize mediump vec4 pattern_to + #pragma mapbox: initialize lowp float pixel_ratio_from + #pragma mapbox: initialize lowp float pixel_ratio_to // the distance over which the line edge fades out. // Retina devices need a smaller distance to avoid aliasing.