Skip to content

Commit

Permalink
Adjust patterns added with addImage by the asset pixel ratio (#9372)
Browse files Browse the repository at this point in the history
* Adjust *-pattern images based on their asset pixel ratio
Instead of using the device pixel ratio, use the image asset pixel ratio

Fix for issue #8020

* EOF

* Add render tests

* Rebase from master
Update baseline for line-pattern to take into account #9266
  • Loading branch information
karimnaaji authored Mar 11, 2020
1 parent eeefc07 commit d8cf290
Show file tree
Hide file tree
Showing 19 changed files with 344 additions and 70 deletions.
22 changes: 13 additions & 9 deletions src/data/array_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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:
Expand Down Expand Up @@ -1054,7 +1058,7 @@ export {
StructArrayLayout4i8,
StructArrayLayout2i4i12,
StructArrayLayout2i4ub8,
StructArrayLayout8ui16,
StructArrayLayout8ui2ub18,
StructArrayLayout4i4ui4i24,
StructArrayLayout3f12,
StructArrayLayout1ul4,
Expand All @@ -1078,7 +1082,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,
Expand Down
4 changes: 3 additions & 1 deletion src/data/bucket/pattern_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'},
]);
40 changes: 27 additions & 13 deletions src/data/program_configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ interface AttributeBinder {
interface UniformBinder {
uniformNames: Array<string>;
setUniform(uniform: Uniform<*>, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue<*>, uniformName: string): void;
getBinding(context: Context, location: WebGLUniformLocation): $Shape<Uniform<*>>;
getBinding(context: Context, location: WebGLUniformLocation, name: string): $Shape<Uniform<*>>;
}

class ConstantBinder implements UniformBinder {
Expand All @@ -104,7 +104,7 @@ class ConstantBinder implements UniformBinder {
uniform.set(currentValue.constantOr(this.value));
}

getBinding(context: Context, location: WebGLUniformLocation): $Shape<Uniform<any>> {
getBinding(context: Context, location: WebGLUniformLocation, _: string): $Shape<Uniform<any>> {
return (this.type === 'color') ?
new UniformColor(context, location) :
new Uniform1f(context, location);
Expand All @@ -115,27 +115,37 @@ class CrossFadedConstantBinder implements UniformBinder {
uniformNames: Array<string>;
patternFrom: ?Array<number>;
patternTo: ?Array<number>;
pixelRatioFrom: number;
pixelRatioTo: number;

constructor(value: mixed, names: Array<string>) {
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<mixed>, 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<Uniform<any>> {
return new Uniform4f(context, location);
getBinding(context: Context, location: WebGLUniformLocation, name: string): $Shape<Uniform<any>> {
return name.startsWith('u_pattern') ?
new Uniform4f(context, location) :
new Uniform1f(context, location);
}
}

Expand Down Expand Up @@ -283,7 +293,7 @@ class CompositeExpressionBinder implements AttributeBinder, UniformBinder {
uniform.set(factor);
}

getBinding(context: Context, location: WebGLUniformLocation): Uniform1f {
getBinding(context: Context, location: WebGLUniformLocation, _: string): Uniform1f {
return new Uniform1f(context, location);
}
}
Expand Down Expand Up @@ -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,
);
}
}
Expand Down Expand Up @@ -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});
}
}
Expand Down Expand Up @@ -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, '_')];
Expand Down
5 changes: 2 additions & 3 deletions src/render/program/fill_extrusion_program.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
Uniform1f,
Uniform2f,
Uniform3f,
Uniform4f,
UniformMatrix4f
} from '../uniform_binding';

Expand Down Expand Up @@ -41,7 +40,7 @@ export type FillExtrusionPatternUniformsType = {|
'u_image': Uniform1i,
'u_pixel_coord_upper': Uniform2f,
'u_pixel_coord_lower': Uniform2f,
'u_scale': Uniform4f,
'u_scale': Uniform3f,
'u_fade': Uniform1f,
'u_opacity': Uniform1f
|};
Expand All @@ -67,7 +66,7 @@ const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocati
'u_texsize': new Uniform2f(context, locations.u_texsize),
'u_pixel_coord_upper': new Uniform2f(context, locations.u_pixel_coord_upper),
'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower),
'u_scale': new Uniform4f(context, locations.u_scale),
'u_scale': new Uniform3f(context, locations.u_scale),
'u_fade': new Uniform1f(context, locations.u_fade),
'u_opacity': new Uniform1f(context, locations.u_opacity)
});
Expand Down
10 changes: 5 additions & 5 deletions src/render/program/fill_program.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
Uniform1i,
Uniform1f,
Uniform2f,
Uniform4f,
Uniform3f,
UniformMatrix4f
} from '../uniform_binding';
import {extend} from '../../util/util';
Expand All @@ -32,7 +32,7 @@ export type FillPatternUniformsType = {|
'u_image': Uniform1i,
'u_pixel_coord_upper': Uniform2f,
'u_pixel_coord_lower': Uniform2f,
'u_scale': Uniform4f,
'u_scale': Uniform3f,
'u_fade': Uniform1f
|};

Expand All @@ -44,7 +44,7 @@ export type FillOutlinePatternUniformsType = {|
'u_image': Uniform1i,
'u_pixel_coord_upper': Uniform2f,
'u_pixel_coord_lower': Uniform2f,
'u_scale': Uniform4f,
'u_scale': Uniform3f,
'u_fade': Uniform1f
|};

Expand All @@ -58,7 +58,7 @@ const fillPatternUniforms = (context: Context, locations: UniformLocations): Fil
'u_texsize': new Uniform2f(context, locations.u_texsize),
'u_pixel_coord_upper': new Uniform2f(context, locations.u_pixel_coord_upper),
'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower),
'u_scale': new Uniform4f(context, locations.u_scale),
'u_scale': new Uniform3f(context, locations.u_scale),
'u_fade': new Uniform1f(context, locations.u_fade)

});
Expand All @@ -75,7 +75,7 @@ const fillOutlinePatternUniforms = (context: Context, locations: UniformLocation
'u_texsize': new Uniform2f(context, locations.u_texsize),
'u_pixel_coord_upper': new Uniform2f(context, locations.u_pixel_coord_upper),
'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower),
'u_scale': new Uniform4f(context, locations.u_scale),
'u_scale': new Uniform3f(context, locations.u_scale),
'u_fade': new Uniform1f(context, locations.u_fade)
});

Expand Down
9 changes: 4 additions & 5 deletions src/render/program/line_program.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
Uniform1i,
Uniform1f,
Uniform2f,
Uniform4f,
Uniform3f,
UniformMatrix4f
} from '../uniform_binding';
import pixelsToTileUnits from '../../source/pixels_to_tile_units';
Expand Down Expand Up @@ -42,7 +42,7 @@ export type LinePatternUniformsType = {|
'u_device_pixel_ratio': Uniform1f,
'u_units_to_pixels': Uniform2f,
'u_image': Uniform1i,
'u_scale': Uniform4f,
'u_scale': Uniform3f,
'u_fade': Uniform1f
|};

Expand Down Expand Up @@ -82,7 +82,7 @@ const linePatternUniforms = (context: Context, locations: UniformLocations): Lin
'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio),
'u_image': new Uniform1i(context, locations.u_image),
'u_units_to_pixels': new Uniform2f(context, locations.u_units_to_pixels),
'u_scale': new Uniform4f(context, locations.u_scale),
'u_scale': new Uniform3f(context, locations.u_scale),
'u_fade': new Uniform1f(context, locations.u_fade)
});

Expand Down Expand Up @@ -143,8 +143,7 @@ const linePatternUniformValues = (
'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom),
'u_device_pixel_ratio': browser.devicePixelRatio,
'u_image': 0,
// this assumes all images in the icon atlas texture have the same pixel ratio
'u_scale': [browser.devicePixelRatio, tileZoomRatio, crossfade.fromScale, crossfade.toScale],
'u_scale': [tileZoomRatio, crossfade.fromScale, crossfade.toScale],
'u_fade': crossfade.t,
'u_units_to_pixels': [
1 / transform.pixelsToGLUnits[0],
Expand Down
8 changes: 3 additions & 5 deletions src/render/program/pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import {
Uniform1i,
Uniform1f,
Uniform2f,
Uniform4f
Uniform3f
} from '../uniform_binding';
import pixelsToTileUnits from '../../source/pixels_to_tile_units';
import browser from '../../util/browser';

import type Painter from '../painter';
import type {OverscaledTileID} from '../../source/tile_id';
Expand Down Expand Up @@ -39,7 +38,7 @@ export type PatternUniformsType = {|
// pattern uniforms:
'u_image': Uniform1i,
'u_texsize': Uniform2f,
'u_scale': Uniform4f,
'u_scale': Uniform3f,
'u_fade': Uniform1f,
'u_pixel_coord_upper': Uniform2f,
'u_pixel_coord_lower': Uniform2f
Expand All @@ -60,8 +59,7 @@ function patternUniformValues(crossfade: CrossfadeParameters, painter: Painter,
return {
'u_image': 0,
'u_texsize': tile.imageAtlasTexture.size,
// this assumes all images in the icon atlas texture have the same pixel ratio
'u_scale': [browser.devicePixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale],
'u_scale': [tileRatio, crossfade.fromScale, crossfade.toScale],
'u_fade': crossfade.t,
// split the pixel coord into two pairs of 16 bit numbers. The glsl spec only guarantees 16 bits of precision.
'u_pixel_coord_upper': [pixelX >> 16, pixelY >> 16],
Expand Down
4 changes: 4 additions & 0 deletions src/shaders/fill_extrusion_pattern.fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 10 additions & 7 deletions src/shaders/fill_extrusion_pattern.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ uniform mat4 u_matrix;
uniform vec2 u_pixel_coord_upper;
uniform vec2 u_pixel_coord_lower;
uniform float u_height_factor;
uniform vec4 u_scale;
uniform vec3 u_scale;
uniform float u_vertical_gradient;
uniform lowp float u_opacity;

Expand All @@ -21,28 +21,31 @@ 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;
vec2 pattern_tl_b = pattern_to.xy;
vec2 pattern_br_b = pattern_to.zw;

float pixelRatio = u_scale.x;
float tileRatio = u_scale.y;
float fromScale = u_scale.z;
float toScale = u_scale.w;
float tileRatio = u_scale.x;
float fromScale = u_scale.y;
float toScale = u_scale.z;

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) / pixel_ratio_from;
vec2 display_size_b = (pattern_br_b - pattern_tl_b) / pixel_ratio_to;

base = max(0.0, base);
height = max(0.0, height);
Expand Down
Loading

0 comments on commit d8cf290

Please sign in to comment.