Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Use individual textures for line dash patterns #15862

Merged
merged 1 commit into from
Oct 29, 2019

Conversation

kkaefer
Copy link
Contributor

@kkaefer kkaefer commented Oct 25, 2019

This moves the LineAtlas from a shared texture that contained SDF dash patterns to use individual textures.

Previously, the texture space was limited to a texture of 512 pixels height. Dash patterns were never removed (and are still never removed as of this patch), which means that this texture could fill up for styles that use a lot of different dash patterns. In particular, dash patterns for lines with a round line cap take up 15 pixels of texture height, limiting the amount of unique dash patterns to 34. While this was probably enough for rendering a single style, we quickly exhausted this number when reusing the Map object to render different styles.

Instead of a global shared texture, we're now creating individual textures for every dash pattern. These textures are still cached so that we don't need to re-upload the texture on every frame.

There are a few changes that we could implement as well:

  • We're currently putting 1 or 2 (for transitions) dash patterns into a texture and use texture coordinates to select the correct one. Instead, we could split this up into actual textures, pass two textures into the line_sdf shader, and bind both textures. This is would be useful because we currently hash on the dash patterns, and transitions between two dash patterns require the creation of a new unique texture.
  • We don't have a strategy to eventually evict old/unused dash pattern textures, so they'll accumulate over time. This applies to a few other entities as well (e.g. glyphs).
  • There are no tests that specifically test the removal of this limitation

This moves the LineAtlas from a shared texture that contained SDF dash patterns to use individual textures.

Previously, the texture space was limited to a texture of 512 pixels height. Dash patterns were never removed (and are still never removed as of this patch), which means that this texture could fill up for styles that use a lot of different dash patterns. In particular, dash patterns for lines with a round line cap take up 15 pixels of texture height, limiting the amount of unique dash patterns to 34. While this was probably enough for rendering a single style, we quickly exhausted this number when reusing the Map object to render different styles.

Instead of a global shared texture, we're now creating individual textures for every dash pattern. These textures are still cached so that we don't need to re-upload the texture on every frame.
@kkaefer kkaefer added bug Core The cross-platform C++ core, aka mbgl rendering labels Oct 25, 2019
@kkaefer kkaefer self-assigned this Oct 25, 2019
Copy link
Contributor

@pozdnyakov pozdnyakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pozdnyakov
Copy link
Contributor

@kkaefer could this PR be merged?

@kkaefer kkaefer merged commit 84f2ff1 into master Oct 29, 2019
@kkaefer kkaefer deleted the individual-line-dash-pattern-textures branch October 29, 2019 10:27
kkaefer added a commit that referenced this pull request Nov 19, 2019
In #15862, we introduced individual textures for line dash patterns to eliminate atlas overflows. Unfortunately, this broke dashed lines that had round caps (dashed lines with straight caps still rendered correctly). Line pattern textures for round caps were now using 256×15 pixel textures.

The OpenGL ES 2.0 spec, section 3.8.2 states:

    Calling a sampler from a fragment shader will return `(R,G,B,A) = (0,0,0,1)` if any of the following conditions are true:
    […]
    - A two-dimensional sampler is called, the corresponding texture image is a non-power-of-two image […], and either the texture wrap mode is not `CLAMP_TO_EDGE`, or the minification filter is neither `NEAREST` nor `LINEAR`.
    […]

This means that texture lookups won't work for NPOT textures unless they use `GL_CLAMP_TO_EDGE`. We're using `GL_CLAMP_TO_EDGE` for the vertical direction, but GL_REPEAT for the horizontal direction, which means that we need a power-of-two texture for our line dash patterns to work on OpenGL ES 2.0 conforming implementations. Fortunately, this just means changing the height from 15 to 16, and from 30 to 32, so we don't waste many pixels.
kkaefer added a commit that referenced this pull request Nov 22, 2019
In #15862, we introduced individual textures for line dash patterns to eliminate atlas overflows. Unfortunately, this broke dashed lines that had round caps (dashed lines with straight caps still rendered correctly). Line pattern textures for round caps were now using 256×15 pixel textures.

The OpenGL ES 2.0 spec, section 3.8.2 states:

    Calling a sampler from a fragment shader will return `(R,G,B,A) = (0,0,0,1)` if any of the following conditions are true:
    […]
    - A two-dimensional sampler is called, the corresponding texture image is a non-power-of-two image […], and either the texture wrap mode is not `CLAMP_TO_EDGE`, or the minification filter is neither `NEAREST` nor `LINEAR`.
    […]

This means that texture lookups won't work for NPOT textures unless they use `GL_CLAMP_TO_EDGE`. We're using `GL_CLAMP_TO_EDGE` for the vertical direction, but GL_REPEAT for the horizontal direction, which means that we need a power-of-two texture for our line dash patterns to work on OpenGL ES 2.0 conforming implementations. Fortunately, this just means changing the height from 15 to 16, and from 30 to 32, so we don't waste many pixels.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Core The cross-platform C++ core, aka mbgl rendering
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants