-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Conversation
b616b16
to
23cfe73
Compare
Is the actual raster clipping change here dependent on the IndexedPrimitive/Drawables/SegmentInfo changes or can those be an independent PR? |
It's not 100% dependent, but then we'd have to implement something that is essentially like that as well. We have the same code duplication for all of the buckets where we have complex code to make sure that all associated vertices for a number of primitives go into the same segment and. Are you saying we should merge |
src/mbgl/gl/segment.hpp
Outdated
@@ -11,23 +11,39 @@ | |||
namespace mbgl { | |||
namespace gl { | |||
|
|||
template <class Attributes> | |||
class Segment { | |||
class SegmentInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once you rebase on master
to pick up #9433, I'd prefer to reverse the naming here: keep the Segment
class as it is and move Segment::vertexArrays
to a new class that composes it and Segment
(name suggestion: DrawableSegment
). Then give Drawable
a DrawableSegmentVector
rather than a SegmentVector
. That will reduce the size of the diff here (no need to add .info.
everywhere).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I attempted initially as well, but I opted to do it the other way around to keep the diff size small. However, I'm happy to rename Segment
to DrawableSegment
. Another candidate might be SegmentBuffers
for naming alignment with VertexBuffer
and IndexBuffer
.
src/mbgl/gl/attribute.hpp
Outdated
@@ -221,6 +221,32 @@ const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = { | |||
offsetof(VertexType, a5) | |||
}; | |||
|
|||
template <class A1> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems these are only needed for a test; can we move them there? Regular code shouldn't need to compare vertices. (Same with operator==
for SegmentInfo
.)
template <class DrawMode, class LayoutVertex, class AttributeLayout> | ||
class IndexedPrimitives { | ||
public: | ||
void add(std::initializer_list<LayoutVertex> v, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're to convert all the bucket types to IndexedPrimitives
, this will be used in very hot code paths. How much overhead is there in creating initializer_lists
, checking the segment capacity on every add
, checking for valid indexes, etc.?
|
||
private: | ||
friend class Drawable<DrawMode, LayoutVertex, AttributeLayout>; | ||
gl::VertexVector<LayoutVertex> vertices; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the IndexedPrimitives
abstraction won't work for the current implementation of FillBucket
, which shares vertices between triangle and line primitives. It will work if we fix mapbox/mapbox-gl-js#2080 though. Are there any other scenarios where we would want to index the same set of vertices multiple ways? I can't think of any.
What is the advantage of this approach over using the depth buffer or stencil buffers (if we have any bits left there) to do clipping? |
I think we should either implement raster clipping without any major refactoring, or do the refactor to A partial refactor to |
src/mbgl/renderer/tile_mask.hpp
Outdated
namespace mbgl { | ||
|
||
// A TileMask is a set of TileIDs that describe what part of a tile should be rendered. I.e. it | ||
// denotes the part of a tile that is covered by other/better tiles. If the entire tile should be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: these first two sentences seem to contradict each other — first that these parts of a tile "should be rendered" and then that this mask denotes parts that should be not be rendered
The advantage of this approach is that we're shading fewer pixels. Also, raster tiles aren't using stencil clipping since they typically load smaller tiles, which makes our stencil clipping mask overflow. It also allows us to draw the texture directly without first having to draw into the depth or stencil buffer. |
23cfe73
to
0ba701f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the Drawables/Segment changes. Instead of having a TileMaskRepository
, mask vertex buffers are now owned directly by the RasterBucket
objects. When there is no masking happening (=default case when the entire tile is drawn), we're still sharing the global vertex buffer.
0ba701f
to
4df6257
Compare
4df6257
to
1eff949
Compare
// A TileMask is a set of TileIDs that describe what part of a tile should be rendered. It omits | ||
// those parts of the tile that are covered by other/better tiles. If the entire tile should be | ||
// rendered, it contains the { 0, 0, 0 } tile. If it's empty, no part of the tile will be rendered. | ||
// TileMasks are typically generated with algorithm::updateTileMasks(). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The key to understanding how the TileMask is generated and used is to understand the relationship between:
- The tile ID of the tile being rendered
- The tile IDs of the renderable descendants of that tile
- The tile IDs of elements of the resulting TileMask
Can you spell out that relationship here or elsewhere, with either an algebraic definition or example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added an example with a schematic drawing to the algorithm file.
src/mbgl/tile/tile_id.hpp
Outdated
@@ -126,6 +127,15 @@ inline CanonicalTileID CanonicalTileID::scaledTo(uint8_t targetZ) const { | |||
} | |||
} | |||
|
|||
inline CanonicalTileID CanonicalTileID::operator-(const CanonicalTileID& rhs) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this definition of subtraction is specific to tile masks. Should it be a named function in tile_mask.hpp
or update_tile_masks.hpp
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inlined this function
1eff949
to
244fa47
Compare
This changes our raster tile rendering to avoid rendering in the parts of a tile that have children for. It accomplishes this by generating vertex buffers that only have quads for the respective areas, rather than having one quad to fill the entire tile.
The first part of the PR refactors Vertex/Index/Segment vectors into their own
IndexedPrimitive
/Drawable
classes. We can apply the same pattern for other buckets in a separate PR.The algorithm works by recursively descending from the tile in question and generating a list of tiles that would cover the tile, but not any of its children.
Finally, we're computing vertex buffers with our new
IndexedPrimitive
class and store the vertex buffers in a repository object.Remaining tasks:
Fixes #9415, #7760, and #8678